21个项目玩转深度学习:基于TensorFlow的实践详解
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

6.2 使用深度卷积网络提取特征

经过人脸检测和人脸识别两个步骤,就获得了包含人脸的区域图像,接下来就要进行人脸识别了。这一步一般是使用深度卷积网络,将输入的人脸图像转换成一个向量的表示,也就是所谓的“特征”。

如何针对人脸来提取特征?可以先来回忆VGG16的网络结构(见图2-22),输入神经网络的是图像,经过一系列卷积计算后,全连接分类得到类别概率。

在通常的图像应用中,可以去掉全连接层,使用卷积层的最后一层当作图像的“特征”,如图3-1中的conv5_3。但如果对人脸识别问题同样采用这种方法,即使用卷积层最后一层做为人脸的“向量表示”,效果其实是不好的。这其中的原因和改进方法是什么?在后面会谈到,这里先谈谈希望这种人脸的“向量表示”应该具有哪些性质。

在理想的状况下,希望“向量表示”之间的距离可以直接反映人脸的相似度:

· 对于同一个人的两张人脸图像,对应的向量之间的欧几里得距离应该比较小。

· 对于不同人的两张人脸图像,对应的向量之间的欧几里得距离应该比较大。

例如,设人脸图像为x1, 2x,对应的特征为f(x1), f(x2),当x1, 2x对应是同一个人的人脸时,f(x1), f(x2)的距离|| f(x1)-f(x2)||2应该很小,而当x1, x2是不同人的人脸时,f(x1), f(x2)的距离|| f(x1)-f(x2)||2应该很大。

在原始的CNN模型中,使用的是Softmax损失。Softmax是类别间的损失,对于人脸来说,每一类就是一个人。尽管使用Softmax损失可以区别出每个人,但其本质上没有对每一类的向量表示之间的距离做出要求。

举个例子,使用CNN对MNIST进行分类,设计一个特殊的卷积网络,让最后一层的向量变为2维,此时可以画出每一类对应的2维向量,如图6-10所示。

图6-10 当最后一层为2维时各个类别对应的2维向量的分布情况

图6-10是直接使用Softmax训练得到的结果,它不符合希望特征具有的特点:

· 希望同一类对应的向量表示尽可能接近。但这里同一类的点可能具有很大的类间距离。

· 希望不同类对应的向量应该尽可能远。但在图中靠中心的位置,各个类别的距离都很近。

对于人脸图像同样会出现类似的情况。对此,有很多改进方法。这里介绍其中两种,一种是使用三元组损失(Triplet Loss),一种是使用中心损失。

6.2.1 三元组损失的定义

三元组损失(Triplet Loss)的原理是:既然目标是特征之间的距离应当具备某些性质,那么就围绕这个距离来设计损失。具体地,每次都在训练数据中取出三张人脸图像,第一张图像记为,第二张图像记为,第三张图像记为。在这样一个“三元组”中,对应的是同一个人的图像,而是另外一个不同的人的人脸图像。因此,距离应该较小,而距离应该较大。严格来说,三元组损失要求下面的式子成立

即相同人脸间的距离平方至少要比不同人脸间的距离平方小α(取平方主要是方便求导)。据此,设计损失函数为

这样的话,当三元组的距离满足时,不产生任何损失,此时Li=0。当距离不满足上述等式时,就会有值为的损失。此外,在训练时会固定‖f(x)‖2=1,以保证特征不会无限地“远离”。

三元组损失直接对距离进行优化,因此可以解决人脸的特征表示问题。但是在训练过程中,三元组的选择非常地有技巧性。如果每次都是随机选择三元组,虽然模型可以正确地收敛,但是并不能达到最好的性能。如果加入“难例挖掘”,即每次都选择最难分辨的三元组进行训练,模型又往往不能正确地收敛。对此,又提出每次都选取那些“半难”(Semi-hard)的数据进行训练,让模型在可以收敛的同时也保持良好的性能。此外,使用三元组损失训练人脸模型通常还需要非常大的人脸数据集,才能取得较好的效果。

6.2.2 中心损失的定义

与三元组损失不同,中心损失(Center Loss)不直接对距离进行优化,它保留了原有的分类模型,但又为每个类(在人脸模型中,一个类就对应一个人)指定了一个类别中心。同一类的图像对应的特征都应该尽量靠近自己的类别中心,不同类的类别中心尽量远离。与三元组损失相比,使用中心损失训练人脸模型不需要使用特别的采样方法,而且利用较少的图像就可以达到与三元组损失相似的效果。下面就一起来学习中心损失的定义。

还是设输入的人脸图像为xi,该人脸对应的类别为yi,对每个类别都规定一个类别中心,记作。希望每个人脸图像对应的特征f(xi)都尽可能接近其中心。因此定义中心损失为

多张图像的中心损失就是将它们的值加在一起

这是一个非常简单的定义。不过还有一个问题没有解决,那就是如何确定每个类别的中心呢?从理论上来说,类别yi的最佳中心应该是它对应的所有图片的特征的平均值。但如果采取这样的定义,那么在每一次梯度下降时,都要对所有图片计算一次,计算复杂度就太高了。针对这种情况,不妨近似一处理下,在初始阶段,先随机确定,接着在每个batch内,使用对当前batch内的也计算梯度,并使用该梯度更新。此外,不能只使用中心损失来训练分类模型,还需要加入Softmax损失,也就是说,最终的损失由两部分构成,即L=Lsoftmax+λLcenter,其中λ是一个超参数。

最后来总结使用中心损失来训练人脸模型的过程。首先随机初始化各个中心,接着不断地取出batch进行训练,在每个batch中,使用总的损失L,除了使用神经网络模型的参数对模型进行更新外,也对进行计算梯度,并更新中心的位置。

中心损失可以让训练处的特征具有“内聚性”。还是以MNIST的例子来说,在未加入中心损失时,训练的结果不具有内聚性。在加入中心损失后,得到的特征如图6-11所示。

图6-11 同时使用中心损失和Softmax得到的各个类别的2维向量的分布

从图中可以看出,当中心损失的权重λ越大时,生成的特征就会具有越明显的“内聚性”。