人脸识别是一个很有趣的卷积神经网络的应用。
来看看人脸验证和人脸识别的区别。人脸验证系统输入的是一张图片和某个人的名字或ID,输出的是图片是否是这个人。在人脸识别中,系统有K个人的数据库,输入一张图片,如果图片是这K个人中的一个,就输出这个人的ID。
人脸识别面临的一个问题是One-Shot学习(一次学习问题)。只有一张图片,用这张图片进行学习,这就是One-Shot学习问题。比如,人脸识别数据库中,每个人的图片只有一张,一张图片是很难学习到一个很好的神经网络来识别数据库里的人。
解决的方法是,系统不去学习每个人的特有特征,而是学习两张图片有哪些不同。给出一张图片img1和人脸识别数据库中的一个人的照片img2,为了判断这两张图片是否是同一个人,我们需要有一个函数d(img1,img2)d(img1,img2),这个函数可以输出两张图片的不同程度。我们再设置一个阈值ττ,如果d(img1,img2)≤τd(img1,img2)≤τ,那么这两张图片是同一个人,如果d(img1,img2)>τd(img1,img2)>τ,那么这两张图片不是同一个人。
学习d(img1,img2)d(img1,img2)函数可以使用Siamese network。
Siamese network结构如下:
最后输出的结果是一个长度为128的向量,这个向量可以认为是图片的特征编码。第一幅图的特征编码用f(x(1))f(x(1))表示,第二幅图片的特征编码用f(x(2))f(x(2))表示。
函数d(img1,img2)d(img1,img2)定义为:
d(img1,img2)=∥f(x(1))−f(x(2))∥22d(img1,img2)=‖f(x(1))−f(x(2))‖22
Siamese network具体的参数没有在课程中给出来,详情请看论文 Taigman et. al.,2014. DeepFace closing the gap to human level performance
要学习函数d(img1,img2)d(img1,img2),需要设置好训练数据。我们选择3张图片,分别是
我们的目标图片是Anchor,再选择一张与Anchor是同一人的图片Positive,然后选择一张与Anchor不是同一人的图片Negative,组成一个三元组。我们希望
∥f(A)−f(P)∥2≤∥f(A)−f(N)∥2‖f(A)−f(P)‖2≤‖f(A)−f(N)‖2
如果训练出来的模型计算出来的特征编码f(image)=0f(image)=0,那么∥f(A)−f(P)∥2=0‖f(A)−f(P)‖2=0和∥f(A)−f(N)∥2=0‖f(A)−f(N)‖2=0,从而上一个不等式一定成立。算法学习到了一个错误的模型。为了避免这种情况,我们添加一个超参数αα,α>0α>0,
∥f(A)−f(P)∥2−∥f(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+α<0‖f(A)−f(P)‖2−‖f(A)−f(N)‖2+α<0
超参数αα是一个比较少的数值,比如0.2,用于确保算法不会学习出错。
设置好训练的对象,我们再定义一下损失函数。三元组的损失函数是
l(A,P,N)=max(∥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+α,0)
当满足不等式时,损失函数值为0;当不满足不等式时,损失函数值为两个特征编码向量的差值(大于0)。
当我们有m个三元组,成本函数J为
J=∑i=1ml(A(i),P(i),N(i))J=∑i=1ml(A(i),P(i),N(i))
如果Negative是随机选择的一张不同的图片,那么∥f(A)−f(N)∥2‖f(A)−f(N)‖2的值是一个很大的数,很容易实现
∥f(A)−f(P)∥2+α≤∥f(A)−f(N)∥2‖f(A)−f(P)‖2+α≤‖f(A)−f(N)‖2
神经网络的学习效果也就不好,因此,要选择难以学习的三元组个神经网络学习。难以学习的三元组是指
∥f(A)−f(P)∥2≈∥f(A)−f(N)∥2‖f(A)−f(P)‖2≈‖f(A)−f(N)‖2
在Siamese网络后半段
计算出图片的特征编码后,下一层需要输出这两张图片是否是同一个人。这就可以转换成一个二分类问题,可以使用sigmoid函数来预测两张图片是同一个人的概率。最后一层网络的计算可以是
y^=sigmoid(∑k=1128wk|f(x(i)k)−f(x(j)k)|+b)y^=sigmoid(∑k=1128wk|f(xk(i))−f(xk(j))|+b)
或者是
y^=sigmoid(∑k=1128wk(f(x(i)k)−f(x(j)k))2+b)y^=sigmoid(∑k=1128wk(f(xk(i))−f(xk(j)))2+b)
人脸验证监督学习问题可以使用Siamese网络,使用的训练集是
人脸验证可以简单的说是1比1问题(1张图片和1张图片做对比),人脸识别就是1比N问题,实现人脸识别的最简单方法就是目标图片与数据库N个人的图片进行N次人脸验证,通过置信度来判断目标图片最像数据库中的哪个人。
神经风格转换是把一张图片转换成另外一张图片的风格。比如
左边的是风景图,右边是一幅艺术画,是梵高画的星空图,把风景图和星空图结合起来,形成新的带有星空图艺术风格的风景图。
实现神经风格转换要深入理解卷积神经网络在学习什么。有一篇论文使用可视化来展示了卷积神经网络在学习什么。下面来直观地了解一下。
下图一个AlexNet的简化版网络
在第一层网络中选择一个神经元,寻找能够最大化这个神经单元激活函数的9张图片。下图是9组不同的能够最大化神经单元激活函数的9张图片。
可以看到,第一层网络主要学习图像的边缘和纯颜色块。
接着看第二层网络中能够最大化神经单元激活函数的9张图片,同样是9组图片
第二层网络主要学习简单的形状,比如说线条、圆等。
接着看第四层网络
第四层网络可以学习更加复杂的物体,比如可以识别狗。
为了判断生成的图片是否是内容和风格的结合体,我们定义神经风格转换的代价函数
J(G)=αJContent(C,G)+βJStyle(S,G)J(G)=αJContent(C,G)+βJStyle(S,G)
其中内容代价函数JContent(C,G)JContent(C,G)表示生成的图片和内容原图的相识度,风格代价函数JStyle(S,G)JStyle(S,G)表示生成的图片和风格图的相识度。αα和ββ用于衡量生成的图片的内容和风格。
神经风格转换的过程如下,首先随机初始化Generated image,接着使用梯度下降最小化J(G)J(G)
G=G−∂∂GJ(G)G=G−∂∂GJ(G)
使用预训练的卷积网络(比如VGG),使用某隐藏层l来计算内容代价函数。使用a[l](C)a[l](C)和a[l](G)a[l](G)分别表示内容原图和生成图片在第l层的激活函数值。如果a[l](C)a[l](C)和a[l](G)a[l](G)相似,说明两张图片有相似的内容。所以
JContent(C,G)=14×nH×nW×nC∥a[l](C)−a[l](G)∥2JContent(C,G)=14×nH×nW×nC‖a[l](C)−a[l](G)‖2
我们使用第l层网络层的激活值来衡量风格。定义风格是信道之间的激活值的相关性。
下图是某个卷积层的激活项。
上图的激活项有5个信道,使用不同颜色标记出来。每个信道相当于普通神经网络的神经元。使得红色信道的激活值最大化的9张图片在图中的红色框中。使得黄色信道的激活值最大化的9张图片在图中的黄色框中。红色信道和黄色信道的激活值的相关性强,是指当红色框的竖条特征出现时,黄色框中的橙色特征有很大的概率会出现。红色信道和黄色信道的激活值的相关性不强,当红色框的竖条特征出现时,黄色框中的橙色特征有很大的概率不会出现。红色信道和黄色信道的激活值的相关性也就是竖条特征和橙色特征的相关性。图片的风格就是各种特征之间的相关性。
计算激活项信道的相关性,相当于计算图片的风格。两两信道的相关性可以组成相关性矩阵,定义这个矩阵为风格矩阵。设a[l]i,j,kai,j,k[l]为第l层在(i,j,k)(i,j,k)的激活值,其中i是指激活项的高度n[l]HnH[l],j指激活项的宽度n[l]WnW[l],k指激活项的信道数n[l]cnc[l]。设G[l]G[l]为第l层的风格矩阵,大小是n[l]c×n[l]cnc[l]×nc[l]。风格图在l层的风格矩阵的计算公式是
G[l](S)kk′=∑i=1n[l]H∑j=1n[l]Wa[l](S)i,j,ka[l](S)i,j,k′Gkk′[l](S)=∑i=1nH[l]∑j=1nW[l]ai,j,k[l](S)ai,j,k′[l](S)
生成图在l层的风格矩阵的计算公式是
G[l](G)kk′=∑i=1n[l]H∑j=1n[l]Wa[l](G)i,j,ka[l](G)i,j,k′Gkk′[l](G)=∑i=1nH[l]∑j=1nW[l]ai,j,k[l](G)ai,j,k′[l](G)
最后判断G[l](S)kk′Gkk′[l](S)和G[l](G)kk′Gkk′[l](G)的相似度。
J[l]Style(S,G)=1(2n[l]Hn[l]Wn[l]c)2∥G[l](S)kk′−G[l](G)kk′∥2F=1(2n[l]Hn[l]Wn[l]c)2∑k∑k′(G[l](S)kk′−G[l](G)kk′)2JStyle[l](S,G)=1(2nH[l]nW[l]nc[l])2‖Gkk′[l](S)−Gkk′[l](G)‖F2=1(2nH[l]nW[l]nc[l])2∑k∑k′(Gkk′[l](S)−Gkk′[l](G))2
最后计算所有网络层的风格代价函数
JStyle(S,G)=∑lλ[l]J[l]Style(S,G)JStyle(S,G)=∑lλ[l]JStyle[l](S,G)
其中λ[l]λ[l]是l层风格矩阵相似度的权重,不同网络层学习的特征不同,不同特征的重要性不同,所以可以加上权重。
卷积网络处理的数据不仅可以是二维的数据,还可以是一维的和三维的。