利用tensorflow实现人脸验证(face verification)的过程

一.前言

这一学期一直在学tensorflow框架,和深度学习的知识,重点是学卷积神经网络。因为只学理论的知识太枯燥无味,于是我就找了一个应用点,人脸识别。前几天随便逛谷歌学术的时候无意看到一篇关于人脸识别的文章,Deep Learning Face Representation from Predicting 10,000 Classes》,于是乎自己就想参考这篇文章利用之前学过的卷积神经网络CNN基础和自己爱好的Python语言尝试做一个人脸识别系统。经查很多资料后,发现图像处理需要运用到部分Opencv的知识,所以就先补了下Opencv的知识。最终自己在pc端做了一个系统,在数据集测试准确率可达96%,但是在实际环境下利用电脑镜头准确率比较低。

二.实现过程

2.1.模型的选取

选取的模型为《Deep Learning Face Representation from Predicting 10,000 Classes》这篇论文所提到的卷积神经网络,模型图如下:

 

5层网络,越往上的神经元的个数就越少,到最后就剩下160个神经元的输出,上面的Face patches 是进过对齐过后的的人脸块,也就是说已左(右)眼为中心的人脸区域块,嘴角为中心的人脸区域块等等,这样就有多个不同的输入块输入到CNN中,文章采用了把倒数第二层的输出+倒数第一层的输出作为特征(这应该是采用12年的Le Cun 那篇文章的track)。最后再把不同的块所输出的特征连接起来,就形成了一个最终一张人脸的特征。然后再用各种分类器对其特征进行分类。采用Max-Pooling,softmax;

输入图像:39*31*k 个人矩形脸图像块+31*31*k(这里k在彩色图像时为3,灰度时k为1)个人脸正方形块(因为后面要考虑到是全局图像还是局部图像,且需要考虑到尺度问题),使用ReLU非线性处理;

以上是这个模型的说明,当然我只是参考了这个模型,在实际运用过程中稍做了修改。

2.2数据集的处理

我利用的数据集是celebFaces,其包含10,177个名人身份的202,599张人脸图片,每张图片都做好了特征标记,包含人脸bbox标注框、5个人脸特征点坐标以及40个属性标记,CelebA由香港中文大学开放提供,广泛用于人脸相关的计算机视觉训练任务,可用于人脸属性标识训练、人脸检测训练以及landmark标记等,官方网址:Large-scale CelebFaces Attributes (CelebA) Dataset

利用python将数据集划分为训练集,验证集,测试集。其中训练集包括1109个人的99810张图片,验证集包括1109个人的11090张图片,测试集包含2760对人脸照片,有的一对是同一个人(用1表示),有的不是同一个人(用0表示)。

2.3训练模型

将训练集数据以一批20张图片输入模型中,每张图片的大小为55*47*3。设置迭代次数为50000次,学习率为0.0001。经过四层卷积层,一层全连接层(特征层),一层softmax分类输出层输出后的值与标签值做比较,利用代价函数交叉熵,梯度下降法,来更新权值w,b。经过50000次迭代,在验证集上的准确率达到99%,保存模型参数。其中前三层卷积层有最大池化层,第四层卷积层经过激活函数relu(线性修正单元函数)和第三层最大池化层作为特征层的输入。部分代码见附录

2.4模型测试

测试模型时,输入的是2760对人脸图片,将特征层的结果作为输出层,对测试集数据,利用训练好的网络提取特征,因此每一张人脸用160维特征向量表示,计算每一对人脸的距离,此距离我们用余弦距离表示。得出判别是否同一个人的结果。余弦距离定义为:

余弦相似性通过测量两个向量的夹角的余弦值来度量它们之间的相似性。0度角的余弦值是1,而其他任何角度的余弦值都不大于1;并且其最小值是-1。从而两个向量之间的角度的余弦值确定两个向量是否大致指向相同的方向。两个向量有相同的指向时,余弦相似度的值为1;两个向量夹角为90°时,余弦相似度的值为0;两个向量指向完全相反的方向时,余弦相似度的值为-1。这结果是与向量的长度无关的,仅仅与向量的指向方向相关。余弦相似度通常用于正空间,因此给出的值为0到1之间。公式如下


经过测试准确率达到96%

2.5实现人脸识别系统

首先利用opencv和电脑摄像头采集试验室同学作为人脸数据库。在测试时,利用电脑摄像头拍下的图片与库中的人脸图片经过训练好的模型提取特征后做余弦距离计算,若距离小余0.48则为同一个人并在框标记出名字。经过实测准确率较低,还有待提高。最后效果见附录

三.总结

对实测环境下准确率不高我认为有以下几点原因:

问题一:数据采集偏差。基于网络采集的人脸数据集存在偏差。这些偏差表现在:1,个体之间照片数量差异很大;2,大部分采集的照片都是:微笑,化妆,年轻,漂亮的图片。这些和真实场景中差异较大,因此在现实场景中准确率很低。
问题二:模型测试加阳性率非常低,但是现实应用中,人们更关注真阳性率。
问题三:人脸图片的角度,光线,闭合(开口、闭口)和年龄等差异相互的作用,导致人脸识别系统现实应用准确率很低。

过程中遇到的问题和收获:

过拟合的现象。训练的epoch太高,模型测试反而准确率不高,说明模型出现了过拟合的问题。因此训练的数据样本需要足够多, 增加样本类别和样本数,需要花费很多精力和时间;也可以调整模型,在神经网络每一层的输入数据进行Batch Normalization(数据归一化),有利于数据的高效性,防止神经元的激励函数钝化实效 ,但是在样本数量比较小的时候同样不是很显著。

自己在对数据集制作的操作中摸索了很久,查了很多资料,对Python的文件操作os模块有了进一步的了解,以及对Opencv图像处理有初步的理解和运用。


 效果图:

 

猜你喜欢

转载自blog.csdn.net/qq_29023939/article/details/80614850