为了理解为什么我们有一次性学习的原因,我们需要讨论下深度学习和数据。通常,在深度学习中,我们需要大量的数据,而我们拥有的数据越多,结果就越好。可是,假如可以用仅仅很少的数据学习就更方便了,因为我们并不是所有人都有丰富的数据。
另一方面,为了识别物体,大脑并不需要见过成千上万相同物体的图片。这里我们不讨论与大脑的类比,因为它太复杂,太强大,很多事情都涉及到我们学习和记忆的过程,比如感觉、先验知识和互动等等。
本文的思路是,我们只从很少的几个数据中学习对象类,这就是一次性学习算法的原理。
在这个人脸识别系统中,我们只想通过向系统提供一张人脸的照片便可识别一个人的身份。而且,如果它不能识别图片,那就意味着这个人的图像没有存储在系统的数据库中。
为了解决这个问题,我们不能只使用卷积神经网络,有两个原因:1)CNN 并不在一个小的训练集上工作 ;2) 我们每次向系统添加一个新人的图片时,不方便对模型进行再训练。然而,我们可以使用 Siamese 神经网络来进行人脸识别。
Siamese 神经网络有一个目标,就是找出两个相似的东西有多相似 (例如,签名验证、人脸识别等)。这个网络有两个相同的子网络,它们都具有相同的参数和权重。
图片来自 C4W4L03 Siamese Network.Andrew Ng 创建
上面的图片是来自 deeplearning.ai 的一个例子,它很好地使用 Siamese 神经网络体系结构进行了人脸识别。正如您所看到的,第一个子网络的输入是一个图像,然后是一系列的卷积、池化、全连接层,最后是一个特性向量 (我们不打算使用 softmax 函数进行分类)。最后一个向量 f(x1) 是输入 x1 的编码。然后,我们对图像 x2 做同样的事情,把它输入到与第一个子网络完全相同的第二个子网络中,得到了输入 x2 的编码 f(x2)。
为了比较这两个图像 x1 和 x2,我们计算编码 f(x1) 和 f(x2) 之间的距离 d。如果它小于一个阈值 (一个超参数),这就意味着这两个图像是同一个人,否则便是两个不同的人。
x1 和 x2 的两种编码之间的距离函数
此方法适用于任意两张图片 xi 和 xj。
那么,我们如何学习这些参数以便为输入图像获得良好的编码呢?
我们可以通过三联体损失函数使用梯度下降法,这是一个使用三张图片的损失函数:一张锚点图像 A,一张正确的图像 P(和锚点图像中人物一样),以及一个不正确的图像 N(人物与锚点图像不同)。我们想让图像 A 与图像 P 的距离 d(A,P) 小于等于图像 A 与图像 N 的距离 d(A,N)。换句话说,我们想让有同一个人的照片间的距离接近,而有不同人的照片距离则远离对方。
“三联”的损失使锚与正之间的距离最小化,两者都具有相同的身份,并使锚与一个不同的身份之间的距离最大化。《FaceNet: 人脸识别和聚类的统一嵌入》
这里有个问题,模型可以学习对不同的图像进行相同的编码,这就会使其间距离为 0,同时它仍满足三元组损失函数。由于这个原因,我们添加了一个边际 alpha(一个超参数) 值,以防止这种情况发生,这样在 A 和 P 及 A 和 N 之间便可一直存在差值。
max 是指,只要 d(A,P)-d(A,N)+alpha 小于或等于零,损失 L(A,P,N) 便是零,但是如果大于零,损失将是正的,此函数将设法使其最小化为零或小于零。
代价函数是所有训练集的不同三元组的个体损失的总和。
训练集:
训练集应该包含同一个人的多张图片,让他们拥有一对 A 和 P,这样模型一旦训练完成,我们就能认出只有一张照片的人。
我们如何选择三元组来训练这个模型呢?
如果我们随机选择它们,就很容易满足损失函数的约束,因为距离多数情况下都是比较大的。梯度下降的方法并不会从训练集中学到太多。因为这个原因,我们需要找到 A,P,N,其中 A 和 P 需要跟 N 尽可能接近。我们的目标是,让梯下降方法越来越难从模型训练中得到优化。
英文原文链接:
https://towardsdatascience.com/one-shot-learning-face-recognition-using-siamese-neural-network-a13dcf739e