facenet人脸识别从理解到手把手训练

人脸识别算法,结合facenet网络结构和center loss作为损失,基于tensorflow框架,含训练和测试代码,支持从头训练和摄像头测试

具体代码实现即讲解请参考我的github,https://github.com/LeslieZhoa/tensorflow-facenet


模型介绍


本代码在训练开始前通过MTCNN网络对数据集的图片进行筛选,筛选出能识别的人脸图像,并通过人脸框将图片裁剪resize成一定尺度用于模型的输入,对于人脸检测MTCNN算法的讲解,我的另一篇项目中做了详尽的介绍和代码注释,本代码的实现也是在此基础上简单修改。


本代码参考FaceNet: A Unified Embedding for Face Recognition and Clustering的主体结构,即使用inception_resnet_v1作为模型主体架构,输出一定维度的图片embeddings。facenet的损失函数采用triplet_loss,即对于某张训练图片img,再选取一张同一类别一张图作为pos,选取不同类别的一张图作为neg。img的embeddings与pos的embeddings的平方和作为pos_dist,im的embeddings和neg的embeddings的平方和作为neg_dist,使pos_dist与neg_dist的差总保持一定阈值。实际训练中在每一batch中对于某一张图,选取同一类别图像作为pos,选取embeddings平方和大于pos的不同类别图像作为neg,依次构成三元组来训练模型。triplet_loss的公式如下所示:


但是这样训练三元组并不能确保每次训练的数据的pos和neg图片都是最难识别的,而且模型收敛极慢。A Discriminative Feature Learning Approach for Deep Face Recognition提出center_loss,可以对模型很快收敛。本代码的损失函数就参考center_loss论文中损失函数。损失公式如下所示:


代码中的损失函数采用softmax交叉熵和center_loss相结合。softmax交叉熵为了使类间距离变大,center_loss是计算某一图片与该类别图片embeddings的均值的损失,为了使类间距离变小。论文中采取minst实验来说明损失函数的功能,如下图所示:

facenet人脸识别从理解到手把手训练_第1张图片

facenet人脸识别从理解到手把手训练_第2张图片

在实际训练中并不是遍历整个数据集来求取某类别center的embeddings,而是只针对每一个batch中出现的类别的center通过batch内相同类别的图像embeddings来进行一定学习率的更新,未出现该批次的类别的center不进行更新。


训练过程中是有类别标记的,那在实际视频测试的时候的验证身份是没有在训练集中出现的类别该怎么办?对于实际测试的时候,有身份图片,和待验证图片,主要就是计算两者embeddings之间的平方和均值与阈值进行比较,当待验证图片与身份图片的embeddings的平方和均值小于一定阈值就判定待验证图片的身份。


我的代码只训练了15个epoch,如果你有兴趣可以在我的基础上重载继续训练或者重新训练,我在筛选图像的时候花费了好长时间,所以要做好心理准备。


代码介绍



环境说明


ubuntu16.04
python3.6.5
tensorflow1.8.0
opencv3.4.3
pip install tqdm为了显示进度条
pip install h5py测试时候存储身份图片的embeddings


结果展示


结果是我通过摄像头的身份验证,其中身份图像来源于百度图片,手机上的图片来源于新浪微博。
 


 

你可能感兴趣的:(CV)