4.1 什么是人脸识别
吴恩达老师用他早年在百度的一个人脸识别项目解释了人脸识别的内容和原理,其中我们发现如果想要识别系统的错误率不太高,首先需要一个准确度相当高的验证系统,一般准确率在99.9%左右。
下一节我们将学习一次学习
4.2 One-shot 学习
人脸识别首先需要解决的一个问题就是一次学习问题。也就是说,模型只能通过仅仅一张照片来学习,然后就要对比输入给出输出了。
首先想到的思路是一个简易的学习模型,通过一个样本的学习,最后输出。但显然这个方法并不具有推广性,因为每加入一个新成员,输出的数量就改变了,那么你就要重新训练你的网络么,这显然是太麻烦了。不仅如此,这样的网络效果也不会太好,因为深度学习是需要大量的学习数据的。
在此之上我们想到了一种解决办法,就是通过让模型网络学会一个叫做d的函数,这个函数是负责对比输入图片和某一张图片的不同度的。如果两张图片非常相似(是同一个人),那么输出的数值会非常地小,如果两个人有较大的不同,那么输出值就很大了。通过设定一个标准值来判断是否是同一人,这样就完成了任务。接下来的问题就是如何让网络学会这个函数d了。
4.3 Siamese 网络
上一节我们分析得到的结论是,d函数的作用是告诉你输入的两个图片的不同度或者相似度。实现这个功能的一个方法就是使用Siamese网络。
如图,比如 x ( 1 ) x^{(1)} x(1)是传入的第一张图片。按照常规卷积神经网络的做法,我们可以对他做卷积然后池化等等,最后是全连接层,这时候的图片就变成了一个向量,比如这张图片就是一个128维的向量。但我们不需要把向量传入signmax函数做分类,而是先这样放着(
然后对第二张图片做相同的操作,经过相同的卷积神经网络,同样输出了一个维数与第一张图片相同的图片。
接下来,我们要对两个向量计算,将 x ( 1 ) 、 x ( 2 ) x^{(1)}、x^{(2)} x(1)、x(2)两个编码之差的范数记作两个向量的距离。公式为
d ( x ( 1 ) , x ( 2 ) ) = ∣ ∣ f ( x ( 1 ) ) − f ( x ( 2 ) ) ∣ ∣ 2 d(x^{(1)} ,x^{(2)}) = ||f(x^{(1)} )-f(x^{(2)})||^2 d(x(1),x(2))=∣∣f(x(1))−f(x(2))∣∣2
而后我们的目标就很明显了,如果这两张图片表示的是同一个人,那么最后两个向量的距离计算的结果就一定要小;如果两个图片表示的不是同一个人,那么最后的结果当然要大得多。
接下来我们要研究的就是,如果利用函数来实现这个网络了。
4.4 Triplet 损失
要想通过学习神经网络的参数来得到优质的人脸识别代码,方法之一就是定义三元组损失函数然后应用梯度下降。
为了应用三元组损失函数,你需要比较成对的图片,比如上图这个例子,positive表示是同一个人,negative表示不是同一个人。显然我们的目标是,想要左边的两个向量相似,而想让右边两个的两个向量差别大一些。
用三元组损失的术语来说,你要做的通常是看一个 Anchor 图片,你想让Anchor图片和Positive图片的距离很接近。然而,当Anchor图片与Negative图片对比时,你会想让他们的距离离得更远一点。
这就是为什么要叫做三元组损失,因为它代表你要一起看三张图片,我们分别把三张图片简写成A、P、N。我们想要前一组的结果小于后一组,如图下方的式子。做相应的变换,得到最下方的式子,及:
∣ ∣ f ( A