显然,我与Matt或Leo不太相似,但是它们有一些共同点!
我们可以更加深入,在嵌入向量中运行PCA并将图像投影到二维平面中
frommatplotlib.offsetboximportOffsetImage, AnnotationBboxdefpca(x: torch.Tensor, k: int=2) ->torch.Tensor: """From http://agnesmustar.com/2017/11/01/principal-component-analysis-pca-implemented-pytorch/"""#preprocessthedataX_mean=torch.mean(x, 0) x=x-X_mean.expand_as(x) #svdU, S, V=torch.svd(torch.t(x)) returntorch.mm(x, U[:, :k]) points=pca(embs, k=2) plt.rcParams["figure.figsize"] = (12,12) fig, ax=plt.figure(), plt.subplot(111) plt.scatter(points[:,0], points[:,1]) fori, pinenumerate(points): x, y=p[0], p[1] img=un_normalize(ds[i][0]) img_np=img.permute(1, 2, 0).numpy().squeeze() ab=AnnotationBbox(OffsetImage(img_np, zoom=0.6), (x, y), frameon=False) ax.add_artist(ab) plt.plot()
我们将512维压缩为2,所以我们丢失了很多数据。
好的,我们有一种方法来找到脸,看看它们是否彼此相似,现在我们可以创建我们的脸解锁算法。
我的想法是取n张允许的人的图像,在嵌入空间中找到中心,选择一个阈值,看d看中心和新图像之间的余弦相似度是小于还是大于它。
fromdataclassesimportdataclass, fieldfromtypingimportList, CallablefromPILimportImageclassFaceUnlock: images: List[Image.Image] =field(default_factory=list) th: float=0.8transform: Callable=MTCNN(image_size=160, margin=18) embedder: torch.nn.Module=InceptionResnetV1(pretrained='vggface2').eval() center: torch.Tensor=Nonedef__post_init__(self): faces=torch.stack(list(map(self.transform, self.images))) embds=self.embedder(faces) self.center=embds.sum(0) /embds.shape[0] def__call__(self, x: Image.Image) ->bool: face=self.transform(x) emb=self.embedder(face.unsqueeze(0)) similarity=torch.cosine_similarity(emb.view(1, -1), self.center.view(1, -1)) is_me=similarity>self.threturnis_me, similarity#loadpicturesofmyselfme=data_root/'faces'/'me'images=list(map(Image.open, me.glob('*'))) #initializefaceunlockwithmyimagesface_unlock=FaceUnlock(images) fromipywidgetsimportinteract, interactive, fixed, interact_manualdefunlock_with_filepath(path): img=Image.open(path) is_me, similarity=face_unlock(img) print(f"{'🔓' if is_me else '🔒'} similarity={similarity.item():.3f}") fig=plt.figure() plt.imshow(img) plt.plot() test_root=data_root/'faces_test'interact(unlock_with_filepath, path=list(test_root.glob('*')))
相似度得分比以前的图像高,所以我猜是真的!
让我们尝试自己的新自拍
总结
我们已经看到了一种仅使用2D数据(图像)创建人脸解锁算法的有吸引力的方法。它依靠神经网络对相似面孔彼此靠近的高维向量空间中的裁剪面孔进行编码。但是,我不知道该模型是如何训练的,并且可能很容易弄糊涂(即使在我的实验中该算法效果很好)。
如果在没有数据扩充的情况下训练模型怎么办?然后,可能只是翻转同一个人可能会破坏潜在的表示。
更加健壮的训练例程将是无监督的(类似于BYOL),它严重依赖于数据增强。
最后,你可以在这里找到所有的代码
https://github.com/FrancescoSaverioZuppichini/Face-Unlock
感谢您的阅读。