人脸识别与人脸验证的区别
内容来自吴恩达深度学习课程,大学自学时对课程所讲内容没有体会,导致心中一直有所疑问,把课程内容整理。(用过百度AI人脸识别的接口,发现其解决方案仅需要进行“人脸注册”,而不是每次新添加人脸都需要重新训练)
什么是人脸识别?
人脸识别作为CNN的重要应用,一般包含人脸识别和活体检测两个部分,后一项技术用来确认你是一个活人(常常用监督学习来实现)。
这里讲的是,如何构造这个系统中的人脸识别。
首先,我们要区分一下人脸验证和人脸识别
- 人脸验证(face verification)
- 人脸识别(face recognition)
对于人脸验证问题,如果你有一张输入图片,以及某人的 ID 或者是名字,这个系统要做的是,验证输入图片是否是这个人。因此验证问题也被称作 1 对 1 问题,系统只需要弄明白这个人是否和他声称的身份相符。
而人脸识别问题比人脸验证问题难很多(1 对多问题(1:𝐾)),为什么呢?
假设你有一个验证系统,准确率是 99%,还可以。
但是现在,假设在识别系统中,𝐾 = 100,
如果你把这个验证系统应用在 100 个人的人脸识别上,你犯错的机会就是 100 倍了。
(事实上,如果我们有一个 100 人的数据库,正确率可能需要远大于 99%,才能得到很好的效果)
Face Verification Vs. Face recognition:
Verification:
- Input image, name/ID
- Output whether the input image is that of the claimed persons
Recognition:
- Has a database of K persons
- Get an input image
- Output ID if the image is any of the K persons (Or 'not recognized')
在接下来的介绍中,我们主要讲构造一个人脸验证基本模块,如果准确率够高,就可以把它用在识别系统上。
人脸验证之所以难,原因主要就在于要解决“one-shot learning”问题。
One-shot learning
一次学习(One-shot learning)问题是说在人脸识别应用中,你需要仅通过一张图片或单一个人脸样例就能去识别这个人。但我们知道,当深度学习只有一个训练样例时,它的表现并不好。
让我们看一个直观的例子,并讨论如何去解决这个问题。
假设你有4个员工需要识别,有一种办法是,将人的照片放进卷积神经网络中,
使用 softmax 单元来输出 4 5 种标签,分别对应这 4 个人,以及是陌生人的概率。
但实际上这样效果必定不好,因为如此小的训练集不足以去训练一个稳健的神经网络。
而且,假如有新人加入你的团队,你现在将会有 5 个组员需要识别,所以输出就变成了
6 种,这时你要重新训练你的神经网络吗?这听起来实在不像一个好办法。
所以人脸识别任务中,为了能有更好的效果,应该是学习一个Similarity 函数。
详细地说,你想要神经网络学习这样一个用𝑑表示的函数,
𝑑(𝑖𝑚𝑔1,𝑖𝑚𝑔2) = 𝑑𝑒𝑔𝑟𝑒𝑒 𝑜𝑓 𝑑𝑖𝑓𝑓𝑒𝑟𝑒𝑛𝑐𝑒 𝑏𝑒𝑡𝑤𝑒𝑒𝑛 𝑖𝑚𝑎𝑔𝑒𝑠,
它以两张图片作为输入,然后输出这两张图片的差异值。
如果这两张图片的差异值小于某个阈值𝜏,这时就能预测这两张图片是同一个人,
否则就是不同的两个人。
那么下面学习的重点就是训练神经网络学会这个函数𝑑。
Siamese network
你经常看到这样的卷积网络,输入图片\(𝑥^1\),
然后通过卷积,池化和全连接,最终得到一个特征向量(编号 1)。
(有时我们还会把它送进 softmax 来做分类,但在这里不需要这么做)
我们关注的重点是这个向量(编号 1),先假设它有 128 个数,
它是由网络的全连接层计算出来的,我们给这 128 个数命个名字,
把它叫做\(𝑓(𝑥^1)\)。我们把\(𝑓(𝑥^1)\)看作是输入图像\(𝑥^1\)的编码。

建立一个人脸识别系统的方法就是,
如果你要比较两个图片的话,
那么就去把第二张图片喂给有同样参数的的神经网络,
然后得到一个不同的 128 维的向量(编号 3),
这个向量代表或者编码第二个图片,
把第二张图片的编码叫做\(𝑓(𝑥^2)\)。

只要这些编码能够很好代表了这两个图片,
我们可以去定义𝑑了,将\(𝑥^1\)和\(𝑥^2\)的距离定义为这两幅图片的编码之差的范数。
接下来的问题就转变为怎么训练这个 Siamese 神经网络?不要忘了这两个网络有相同的参数,所以我们实际要
做的就是训练一个网络,它计算得到的编码可以用于函数𝑑。
下面我们会利用三元组损失(Triplet 损失)函数达到这个目的。
Triplet 损失
要想通过学习神经网络的参数来得到优质的人脸图片编码,
方法之一就是定义三元组损失函数然后应用梯度下降。

三元组损失函数,就是你需要比较成对的图像。
比如图片1 和图片 2,
我们希望它们的编码相似,因为这是同一个人。
假如是图片3 和图片 4,
我们希望它们的编码差异大一些,因为这是不同的人。
用三元组损失的术语来说,你要做的通常是看一个 Anchor 图片,
让 Anchor 图片和 Positive 图片(Positive 意味着是同一个人)的距离很接近。
相反,我们希望 Anchor 图片与 Negative图片的距离离得更远一点。
这就是为什么叫做三元组损失,它代表我们通常会同时看三张图片:
Anchor 图片、Postive 图片,还有 Negative 图片。
我们简写成𝐴、𝑃、𝑁。
把这些写成公式的话,你想要的是网络的参数或者编码能够满足以下特性:
\(||𝑓(𝐴) − 𝑓(𝑃)||^2\),我们希望它越小越好。
准确地说,你想让它小于等𝑓(𝐴)和𝑓(𝑁)之间的距离,
或者说是它们的范数的平方,即:
不过我们仍需要对这个不等式做一点改进,以避免以下问题:
- 把所有的东西都学成 0,如果𝑓总是输出 0,即 0-0≤0,那么总能满足这个方程
- 每个图片的编码和其他图片一样,还是得到 0-0
为了阻止网络出现这种情况,我们需要修改这个目标,两个特征的差值不能是刚好小于等于 0,应该是比 0 还要小,应该小于一个−𝑎值。
这里的α可以叫做间隔(margin),是一个超参数。
举个例子,假如间隔设置成 0.2,如果在这个例子中,𝑑(𝐴, 𝑃) = 0.5,如果 Anchor 和
Negative 图片的𝑑,即𝑑(𝐴, 𝑁)只大一点,比如说 0.51,条件就不能满足。
虽然 0.51 也是大于0.5 的,但还是不够好,我们想要𝑑(𝐴, 𝑁)比𝑑(𝐴, 𝑃)大很多。
接下来我们定义损失函数,取
这个𝑚𝑎𝑥函数的作用就是,只要这个\(||𝑓(𝐴) − 𝑓(𝑃)||2 − ||𝑓(𝐴) − 𝑓(𝑁)||2 + 𝑎 ≤ 0\),那么损失函数就是 0,这样为了让网络不会关心它负值有多大。我们会得到一个正的损失值。
这是一个三元组定义的损失,整个网络的代价函数应该是训练集中这些单个三元组损失
的总和。
假如我们有一个 10000 个图片的训练集,里面是 1000 个不同的人的照片,
现在要做的就是取这 10000 个图片,然后生成这样的三元组,然后训练学习算法,
对这种代价函数用梯度下降。
注意,为了定义三元组的数据集需要成对的𝐴和𝑃,即同一个人的成对的图片,为了
训练你的系统你确实需要一个数据集,里面有同一个人的多个照片。
现在我们来看,你如何选择这些三元组来形成训练集。
一个问题是如果你从训练集中,
随机地选择𝐴、𝑃和𝑁,遵守𝐴和𝑃是同一个人,而𝐴和𝑁是不同的人这一原则。
但是要注意如果随机的选择它们,那么这个约束条件(𝑑(𝐴, 𝑃) + 𝑎 ≤ 𝑑(𝐴, 𝑁))很容易达到,因为随机
选择的图片,𝐴和𝑁比𝐴和𝑃差别很大的概率很大。这样网络并不能从中学到什么。
Face verification and binary classification
Triplet loss 是一个学习人脸识别卷积网络参数的好方法,还有其他学习参数的方法,比方说把人脸识别当成一个二分类问题。
另一个训练神经网络的方法是选取一对Siamese网络,使其同时计算这
些嵌入,比如说 128 维的嵌入(编号 1),或者更高维,然后将其输入到逻辑回归单元,
然后进行预测,如果是相同的人,那么输出是 1,若是不同的人,输出是 0。
这就把人脸识别问题转换为一个二分类问题,训练这种系统时可以替换 Triplet loss 的方法。

最后的逻辑回归单元是怎么处理的?相比起直接放入这些编码\(𝑓(𝑥^{(𝑖)}), 𝑓(𝑥^{(𝑗)})\),你可以利用编码之间的不同。

其中,
- \(𝑓(𝑥^{(𝑖)})_𝑘\)代表图片\(𝑥^{(𝑖)}\)的编码,
- 下标𝑘代表选择这个向量中的第𝑘个元素,
- \(|𝑓(𝑥^{(𝑖)})_𝑘 − 𝑓(𝑥^{(𝑗)})_𝑘|\)是对这两个编码取元素差的绝对值。
你可以想,把这128个元素当作特征,
然后把他们放入逻辑回归中,最后的逻辑回归可以增加参数𝑤和𝑏,
就像普通的逻辑回归一样。
在这 128 个单元上训练合适的权重,用来预测两张图片是否是一个人,这是一个很
合理的方法。
此外,还有其他不同的形式来计算绿色标记的这部分公式比方说𝜒平方相似度。
但是在这个学习公式中,输入是一对图片,还有训练输入𝑥(编号 1、2),
输出𝑦是 0 或者 1,取决于你的输入是相似图片还是非相似图片。
与之前类似,我们正在训练一个Siamese 网络,意味着上面这个神经网络拥有的参数和下面神经网络的相同(编号 3 和 4 所示的网络),这样的系统效果很好。

还有一个计算技巧可以显著提高部署效果,假设一张新图片(编号 1),
当员工走进门时,希望门可以自动为他们打开,这个(编号 2)是在数据库中的图片,不需
要每次都计算这些特征(编号 6),可以提前计算好存下来,那么
当一个新员工走近时,你可以使用上方的卷积网络来计算这些编码(编号 5),然后使用它,
和预先计算好的编码进行比较,然后输出预测值𝑦^。
总结一下,把人脸验证当作一个监督学习,创建一个只有成对图片的训练集,不是三个
一组,而是成对的图片,目标标签是 1 表示一对图片是一个人,目标标签是 0 表示图片中是
不同的人。利用不同的成对图片,使用反向传播算法去训练神经网络,训练 Siamese 神经网
络。

浙公网安备 33010602011771号