吴恩达《Convolutional Neural Networks》神经网络应用:人脸识别笔记

须知:本文作者建议各位读者结合Coursera上Andrew NG(吴恩达)教授的DeeLearning.ai课程一同学习,理解效果更佳。本文为《Convolutional Neural Networks》第四周 特殊应用:人脸识别和神经风格迁移的学习笔记。



What is face recognition?

在人脸识别的相关文献中,人们经常提到人脸验证(face verification)和人脸识别(face recognition)

  • 对于人脸验证问题,如果你有一张输入图片,以及某人的ID或者是名字,这个系统要做的是,验证输入图片是否是这个人。有时候也被称作1对1问题,只需要弄明白这个人是否和他声称的身份相符。
  • 对于人脸识别问题,要复杂很多(一对多问题(1:k))。假设你有一个验证系统,准确率是99%,还可以。假设在识别系统中,K=100,如果你把这个验证系统应用在100个人的人脸识别上,你犯错的机会就是100倍了。如果每个人犯错的概率是1%,如果你有一个上百人的数据库,如果你想得到一个可接受的识别误差,你要构造一个验证系统,其准确率为99.9%或者更高,然后才可以在 100 人的数据库上运行,而保证有很大几率不出错。事实上,如果我们有一个 100 人的数据库,正确率可能需要远大于 99%,才能得到很好的效果。

人脸验证之所以难,原因之一在于要解决“一次学”(one-shot learning problem)问题。

One-shot learning

人脸识别所面临的一个挑战就是你需要解决一次学习问题,这意味着在大多数人脸识别应用中,你需要通过单单一张图片或者单单一个人脸样例就能去识别这个人。当深度学习只有一个训练样例时,它的表现并不好。

举个栗子:

比如现在你的数据库中有4个人,现在假设有个人(编号1所示)来到办公室,并且她想通过带有人脸识别系统的栅门,现在系统需要做的就是,仅仅通过一张已有的照片,来识别前面这个人确实是她。相反,如果机器看到一个不在数据库里的人(编号 2 所示),机器应该能分辨出她不是数据库中四个人之一。

  • 方法一

27.png-183.5kB

将人的照片放进卷积神经网络中,使用softmax单元来输出5种标签(分别对应数据库的4个人& 4个都不是。但实际上这样效果并不好,因为如此小的训练集不足以去训练一个稳健的神经网络。还存在另一个问题,假如有新人加入你的团队,你现在将会有 5 个组员需要识别,所以输出就变成了6种,这时你要重新训练你的神经网络吗?这听起来实在不像一个好办法。

  • 方法二
    要让人脸识别能够做到一次学习,为了能有更好的效果,你现在要做的应该是学习Similarity 函数。你想要神经网络学习这样一个函数d
    d ( i m g 1 , i m g 2 ) = d e g r e e   o f   d i f f e r e n c e   b e t w e e n   i a m g e s d(img1,img2)= degree\ of\ difference\ between\ iamges d(img1,img2)=degree of difference between iamges

i f   d ( i m g 1 , i m g 2 ) { &lt; τ , &quot; s a m e &quot; ( v e r i f i c a t i o n ) &gt; τ , &quot; d i f f e r e n t &quot; ( v e r i f i c a t i o n ) if\ d(img1,img2)\begin{cases} &lt; \tau &amp; ,&quot;same&quot;(verification)\\&gt; \tau &amp; ,&quot;different&quot;(verification) \end{cases} if d(img1,img2){<τ>τ"same"(verification)"different"(verification)

如何检测?

它以两张图片作为输入,然后输出这两张图片的差异值。如果你放进同一个人的两张照片,你希望它能输出一个很小的值,如果放进两个长相差别很大的人的照片,它就输出一个很大的值。所以在识别过程中,如果这两张图片的差异值小于某个阈值 τ \tau τ(它是一个超参数),那么这时就能预测这两张图片是同一个人,如果差异值大于 τ \tau τ,预测这是不同的两个人。

对应的,如果某个人不在你的数据库中,你通过函数 d ( i m g 1 , i m g 2 ) d(img1,img2) d(img1,img2)将他们的照片两两进行比较,最后我们发现 d ( i m g 1 , i m g 2 ) d(img1,img2) d(img1,img2)会对所有的比较都输出一个很大的值,这就证明这个人并不是数据库中4个人的其中一个。

如何解决一次性学习?

是如何解决一次学习问题的,只要你能学习这个函数 d ( i m g 1 , i m g 2 ) d(img1,img2) d(img1,img2),通过输入一对图片,它将会告诉你这两张图片是否是同一个人。如果之后有新人加入了你的团队,你只需将他的照片加入你的数据库,系统依然能照常工作。

Siamese network

通过Siamese network,我们就可以实现输入两张人脸,通过Similarity 函数 d ( i m g 1 , i m g 2 ) d(img1,img2) d(img1,img2)求出它们的相似度。

  • 输入第一张图片(编号1)为 x ( 1 ) x^{(1)} x(1),通过神经网络(卷积层、池化层、全连接层)得到一个输出向量(比如128维),记作 f ( x ( 1 ) ) f(x^{(1)}) f(x(1)) 之前我们会把它再送到softmax单元来做分类,但在这里,我们不去做softmax。现在我们把 f ( x ( 1 ) ) f(x^{(1)}) f(x(1))看做是输入图像 x ( 1 ) x^{(1)} x(1)的编码。
  • 接着,我们输入第二张图片(编号2)为为 x ( 2 ) x^{(2)} x(2),连接到有同样参数的同样的神经网络,然后得到一个不同的128维的向量,记作 f ( x ( 2 ) ) f(x^{(2)}) f(x(2)),同样用这个向量来作为图像 x ( 2 ) x^{(2)} x(2) 的编码。
  • 定义函数 d d d,将 x ( 1 ) x^{(1)} x(1) x ( 2 ) x^{(2)} x(2) 的距离定义为这两幅图片的编码之差的范数
    d ( x ( 1 ) , x ( 2 ) ) = ∣ ∣ f ( x ( 1 ) ) − f ( x ( 2 ) ) ∣ ∣ 2 2 d(x^{(1)},x^{(2)})=||f(x^{(1)})-f(x^{(2)})||^2_2 d(x(1),x(2))=f(x(1))f(x(2))22
  • 对于两个不同的输入,运行相同的卷积神经网络,然后比较它们,这一般叫做 Siamese 网络架构。

How to Train ?

对于两幅图片,我们都是通过同一个网络进行输出,我们我们要做的是训练一个网络,输出的编码作用于函数 d d d 来判断两张图片是否是同一个人。。更准确地说,神经网络的参数定义了一个编码函数 f ( x ( i ) ) f(x^{(i)}) f(x(i)),如果给定输入图像 x ( i ) x^{(i)} x(i),这个网络会输出 x ( i ) x^{(i)} x(i) 的128维的向量编码。要做的就是通过反向传播来学习参数,使得如果两个图片 x ( 1 ) x^{(1)} x(1) x ( 2 ) x^{(2)} x(2) 是同一个人,那么得出函数 d d d得出的距离就越小。

Triplet Loss

通过学习神经网络的参数来得到良好的人脸图片编码,方法之一就是定义三元组损失函数(Triplet Loss)然后应用梯度下降(gradient descent)。

definenation

为了应用三元组损失函数,你需要比较成对的图像。对于一个 Anchor 图片,我们希望让 Anchor 图片和 Positive 图片(Positive 意味着是同一个人)的距离很接近。而当Anchor图片与Negative图片(Negative意味着是非同一个人)对比时,我们希望让他们的距离离得更远一点。这就是为什么叫做三元组损失,它代表你通常会同时看三张图片,你需要看 Anchor 图片、Postive 图片,还有 Negative 图片,我要把 Anchor 图片、Positive 图片和 Negative 图片简写成 A 、 P 、 N A、P、N APN

接下来我们定义损失函数:

  • L ( A , P , N ) = m a x ( ∣ ∣ f ( A ) − f ( P ) ∣ ∣ 2 − ∣ ∣ f ( A ) − f ( N ) ∣ ∣ 2 + α , 0 ) L(A,P,N)=max(||f(A)-f(P)||^2-||f(A)-f(N)||^2+\alpha,0) L(A,P,N)=max(f(A)f(P)2f(A)f(N)2+α0)
  • 我们希望 ∣ ∣ f ( A ) − f ( P ) ∣ ∣ 2 − ∣ ∣ f ( A ) − f ( N ) ∣ ∣ 2 ≤ 0 ||f(A)-f(P)||^2-||f(A)-f(N)||^2 \leq 0 f(A)f(P)2f(A)f(N)20
  • 但如果都 f f f 都为0向量,输出一直都等于0,方程式一直满足
  • 设置一个超参数 α \alpha α 来作为一个margin/gap,来阻止网络输出无用的结果。
  • ∣ ∣ f ( A ) − f ( P ) ∣ ∣ 2 − ∣ ∣ f ( A ) − f ( N ) ∣ ∣ 2 + α &lt; 0 ||f(A)-f(P)||^2-||f(A)-f(N)||^2+\alpha &lt;0 f(A)f(P)2f(A)f(N)2+α<0时, L ( A , P , N ) L(A,P,N) L(A,P,N)输出为0
  • ∣ ∣ f ( A ) − f ( P ) ∣ ∣ 2 − ∣ ∣ f ( A ) − f ( N ) ∣ ∣ 2 + α &gt; 0 ||f(A)-f(P)||^2-||f(A)-f(N)||^2+\alpha &gt;0 f(A)f(P)2f(A)f(N)2+α>0时, L ( A , P , N ) L(A,P,N) L(A,P,N)输出为一个正数,通过最小化这个损失函数达到的效果就是使这部分变为0或者小于等于0。只要这个损失函数小于等于 0,网络不会关心它负值有多大。

整个网络的代价函数:

  • J = ∑ i = 1 m L ( A ( i ) , P ( i ) , N ( i ) ) J=\sum_{i=1}^mL(A^{(i)},P^{(i)},N^{(i)}) J=i=1mL(A(i),P(i),N(i))

整个网络的代价函数应该是训练集中这些单个三元组损失的总和。
假如你有一个 10000 个图片的训练集,里面是 1000 个不同的人的照片,你要做的就是取这 10000 个图片,然后生成这样的三元组,然后训练你的学习算法,对这种代价函数用梯度下降,这个代价函数就是定义在你数据集里的这样的三元组图片上。

【注意】为了定义三元组的数据集你需要成对的A和P,即同一个人的成对的图片。比如提到的1000个不同的人的10000张照片,也许是这1000个人平均每个人10张照片,组成了你整个数据集。如果你只有每个人一张照片,那么根本没法训练这个系统。当然,训练完这个系统之后,你可以应用到你的一次学习问题上,对于你的人脸识别系统,可能你只有想要识别的某个人的一张照片。但对于训练集,你需要确保有同一个人的多个图片,至少是你训练集里的一部分人,这样就有成对的 Anchor 和 Positive 图片了。

Choose the triplets A,P,N

现在我们来讨论选择这些三元组来形成训练集。一个问题是如果你从训练集中,
随机地选择A、P和N,遵守【A和P是同一个人,A和N是不同的人】这一原则,A和P的差异越大,我们希望的 ∣ ∣ f ( A ) − f ( P ) ∣ ∣ 2 − ∣ ∣ f ( A ) − f ( N ) ∣ ∣ 2 + α ≤ 0 ||f(A)-f(P)||^2-||f(A)-f(N)||^2+\alpha \leq 0 f(A)f(P)2f(A)f(N)2+α0越容易满足。

这里,也可以将 ∣ ∣ f ( A ) − f ( P ) ∣ ∣ 2 = d ( A , P ) ||f(A)-f(P)||^2=d(A,P) f(A)f(P)2=d(A,P)
因此 ∣ ∣ f ( A ) − f ( P ) ∣ ∣ 2 − ∣ ∣ f ( A ) − f ( N ) ∣ ∣ 2 + α ≤ 0 ||f(A)-f(P)||^2-||f(A)-f(N)||^2+\alpha \leq0 f(A)f(P)2f(A)f(N)2+α0 等价于 d ( A , P ) − d ( A , N ) + α ≤ 0 d(A,P)-d(A,N)+\alpha \leq0 d(A,P)d(A,N)+α0 等价于 d ( A , P ) + α ≤ d ( A , N ) d(A,P)+\alpha \leq d(A,N) d(A,P)+αd(A,N)

A,N的差距越大,神经网络学到的东西越少。因此我们需要尽可能选择难训练的三元组A、P和N,换言之你的选择应使得 d ( A , P ) d(A,P) d(A,P)很接近 d ( A , N ) d(A,N) d(A,N),即 d ( A , P ) ≈ d ( A , N ) d(A,P)\approx d(A,N) d(A,P)d(A,N),才能让神经网络学到更多的东西。此时为了满足 d ( A , P ) + α ≤ d ( A , N ) d(A,P)+\alpha \leq d(A,N) d(A,P)+αd(A,N),我们会使 d ( A , P ) d(A,P) d(A,P)尽可能小,而 d ( A , N ) d(A,N) d(A,N)尽可能大,来保证有一个足够的 α \alpha α
关于这个更多细节可参见这篇论文:
FaceNet: A Unified Embedding for Face Recognition and Clustering

Summary

训练这个三元组损失你需要取你的训练集,然后把它做成很多三元组,如下图的编号1、2、3,分别是一个三元组。有一个Anchor图片、一个Positive图片、一个Negative图片。其中A、P为同一人,A、N为不同人。

定义了这些包括 定义了这些包括定义了这些包括 A 、 P 、 N A、P、N APN的图片的数据集之后,你还需要做的就是用梯度下降最小化我们之前定义的代价函数 J J J,这样做的效果就是反向传播到网络中的所有参数来学习到一种编码,使得如果两个图片是同一个人,那么它们的 d d d 就会很小,如果两个图片不是同一个人,它们的 d d d 就会很大。

Tricks】大规模的商业人脸识别系统都是在超过百万图、千万甚至上亿图片的数据集上训练,按照现在的标准,这些数据集并不容易获得。所以相比于从头训练这些网络,可以下载很多公司已经训练好并且上传了模型参数的网络预训练模型。

Face verification and binary classification

Triplet loss 是一个学习人脸识别卷积网络参数的好方法,还有其他学习参数的方法,比如将人脸识别当成一个二分类问题。

选取一对Siamese神经网络,使其同时计算输出向量(比如128维,或者更高维),然后将其输入到逻辑回归单元,然后进行预测,如果是相同的人,那么输出是1,若是不同的人,输出是0。这就把人脸识别问题转换为一个二分类问题,训练这种系统是可以替换 Triplet loss 的方法。

逻辑回归单元是怎么处理的?

  • y ^ = σ ( ∑ k = 1 128 w i ∣ f ( x ( i ) ) k − f ( x ( j ) ) k ∣ + b ) \hat{y}=\sigma(\sum_{k=1}^{128}w_i|f(x^{(i)})_k-f(x^{(j)})_k|+b) y^=σ(k=1128wif(x(i))kf(x(j))k+b)
  • f ( x ( i ) ) k f(x^{(i)})_k f(x(i))k 代表图片 x ( i ) x^{(i)} x(i) 的编码,下标 k k k 代表选择这个向量中的第 k k k 个元素
  • ∣ f ( x ( i ) ) k − f ( x ( j ) ) k ∣ |f(x^{(i)})_k-f(x^{(j)})_k| f(x(i))kf(x(j))k代表对这两个编码取元素差的绝对值
  • 这128个元素当作特征,把他们放入逻辑回归中(增加参数 w i 、 b w_i、b wib)
  • 在这128个单元上训练合适的权重,用来预测两张图片是否是一个人(0或者1)

除此以外,公式中 ∣ f ( x ( i ) ) k − f ( x ( j ) ) k ∣ |f(x^{(i)})_k-f(x^{(j)})_k| f(x(i))kf(x(j))k 还可替换为 ( f ( x ( i ) ) k − f ( x ( j ) ) k ) 2 f ( x ( i ) ) k + f ( x ( j ) ) k \frac{(f(x^{(i)})_k-f(x^{(j)})_k)^2}{f(x^{(i)})_k+f(x^{(j)})_k} f(x(i))k+f(x(j))k(f(x(i))kf(x(j))k)2
这个公式也称为 χ 2 \chi^2 χ2公式 或 χ \chi χ平方相似度。

这些公式及其变形的更多细节参见论文:
DeepFace: Closing the gap to human-level performance in face verification

Tricks
如果有一个很大的员工图片数据库,不需要每次都计算数据库中图片这些特征(128维输出向量),可以利用预先计算(precompute)思想,提前计算好可以节省大量的计算成本,然后直接与员工走进时卷积神经网络输出的向量进行比较,输出预测值 y ^ \hat{y} y^

Summary

我们把人脸验证当作一个监督学习,创建一个只有成对图片的训练集,不是三个一组,目标标签是1表示一对图片是同一个人,目标标签是0表示图片中是不同的人。利用不同的成对图片,使用反向传播算法去训练神经网络,训练 Siamese 神经网络。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值