《Deep Convolutional Network Cascade for Facial Point Detection》复现

 1.引言

       锵锵锵,好久不见,我又肥来了,前一段时间上网找资料的时候偶然发现一篇关于人脸关键点检测的文章,应该说这篇论文是关键点检测的看山鼻祖,论文主页:http://mmlab.ie.cuhk.edu.hk/archive/CNN_FacePoint.htm,一篇中文翻译的博客:基于DCNN的人脸特征点定位。我大概看了一遍发现这个论文的思路对我有很大的帮助,同时整体神经网络结构的搭建也不算太复杂,因此决定将论文复现一下看看效果,同时我对论文提出的网络也进行了一点细微的修改,但是中间有点事所以这个计划在进行了一半后就搁浅了,直到这几天才将后续的部分完成,让我们一起看一看实现的过程。

       我的训练环境是使用Python3.6,Tensorflow—gpu,CUDA9.1,CUDNN7版本,每个网络进行1000epoch训练,最终训练效果如下图所示,红色点是网络预测的坐标点,蓝色点为数据集中给出的坐标点,该网络的预测效果相对来说还是可以的,但是在嘴角部分的预测还有一定差距。

《Deep Convolutional Network Cascade for Facial Point Detection》复现《Deep Convolutional Network Cascade for Facial Point Detection》复现《Deep Convolutional Network Cascade for Facial Point Detection》复现

《Deep Convolutional Network Cascade for Facial Point Detection》复现《Deep Convolutional Network Cascade for Facial Point Detection》复现《Deep Convolutional Network Cascade for Facial Point Detection》复现

2.网络结构

       论文提出的网络整体思想是将网络分为两个模块,第一模块是通过适应openCV、faster rcnn或者训练的其他网络将原始图片裁剪出人脸部分用作第二模块关键点检测的数据,由于我使用的是Kaggle上提供的人脸关键点定位数据集,因此我没有使用第一模块,如果需要使用第一模块我个人推荐使用openCV进行人脸的裁剪,因为我们在第一步仅需要将人脸大致范围进行提取,结果中只要包含人脸关键区域即可,没有必要专门搭建一个其他网络进行定位;第二模块又分为3个‘层级’,第一层对图片关键点进行粗定位,第二层在第一层的基础上对图片进行细定位,第三层在第二层的基础上进行精细定位。接下来对三个层级进行讲解。(默认英文五官对应单词首字母代表对应点的网络)

《Deep Convolutional Network Cascade for Facial Point Detection》复现

2.1第一层级

        第一层级有三个网络构成,一个全脸卷积,一个眼睛鼻子卷积,一个鼻子嘴角卷积,第一层最后检测的左眼、右眼、鼻子、左嘴角以及右嘴角的坐标有上述三个网络结果取平均后得出,比如鼻子在三个网络中都包含结果就将三个网络预测的鼻子坐标相加除以三,类似的眼睛和嘴巴分别为两个网络结果相加取平均,下图是第一个F网络,整张人脸检测的结构图,可以发现原论文使用的是四个卷积层+两个全连接层,在我实现的过程中改为了三个卷积层+一个Dropout层+一个全连接层;后两个EN网络和NM网络结构和次类似,只是最后的全连接层维度不同。

《Deep Convolutional Network Cascade for Facial Point Detection》复现

2.2第二层级

       第二层级共有十个网络,分别为LE、RE、N、LM和RM五个网络,每个网络实现两次,用以最后的取平均减小误差,在这一层网络的结构由第一层的四个卷积变为两个卷积层,论文给出的结构式两个卷积层+两个全连接层,相应的我的结构改为两个卷积层+一个Dropout层+一个全连接层,值得注意的是这一层在输入数据时需要依据第一层粗定位的坐标点对原始图像进行裁剪,LE网络输入为图片的左眼,RE网络输入的是图片的右眼依此类推。

2.3第三层级

       第三层网络和第二层的网络结构保持一致,经过前两层的训练提取出的坐标点已经有一定精度了,在第三层中我们依据第二层检测的坐标点进行裁剪输入到第三层十个进行最后的精细预测,或许你会有疑问这样看起来第二层和第三层没有什么区别,是否可以取消第三层?首先经过前两轮提取在第三层裁剪的区域肯定与第二层的区域是不同的,相对来说第三层裁剪时我们期望的坐标点在裁剪区域中心的概率很大,其次在第三层中裁剪的时候要比第二层裁剪的区域更加小,比如说嘴角的裁剪,在第二层有可能输入的左嘴角区域包含嘴巴的一半,但是在第三层输入的区域将仅仅包含左嘴角的一小块区域。

3.网络训练

       此部分可以参考我开头发的两个链接第一个为原始论文主页,第二个为博主对论文的解析,里面对此部分都进行了详细的描述,原文提出的损失函数是下图形式的对欧式距离除以图片长度的方式,在我现实时没有对其取根号,其想法来自adma的思想,在训练初期网络损失值过大通过取平方加大损失,进而加快网络的拟合速度,但是经过一定程度的迭代后当损失值减小时通过取平方减小损失,进而在反向传播时小步更新权重。

《Deep Convolutional Network Cascade for Facial Point Detection》复现

4.总结

       这篇到这里就结束了,这次的复现单纯就是想玩玩吧,总的来说这篇论文实现起来没有什么特别难的地方,复现过程只在第二层第三层训练时需要坐标值的更新踩了一点坑,最后的结果看起来也是挺好的,对于网络的搭建我还有一些其他的想法就不一一细说了,之后再进行改进验证一下自己的想法。源码在我改进之后会放到github上。