算法步骤(包括数据准备过程)—全过程
- 根据MTCNN架构,从CelebA、wider_face数据集里(类似数据皆可,需自行下载)采样出positive、part、negative样本并同时得到样本的label信息(采样图片包含三种size:12,24,48),因此这里需要写一个采样程序
- 无论你是选择TensorFlow或者Pytorch,都需要继承一个dataset类来读取采样数据,因为该数据是外部数据,需要读取进来。笔者用的Pytorch,这里写了一个dataset,然后通过dataloader加载dataset里数据,需要注意dataloader是按照你设置的批次大小加载的
- 创建神经网络,这个比较简单,按照架构创建即可。一共三个网络,PNet(全卷积网络),RNet(CNN+MLP),ONet(CNN+MLP),每个网络都会输出一个置信度,和四个偏移值。注意,PNet因为是全卷积网络,所以对输入图片数据的size不敏感,也即是可以输入任意size图片,但是PNet、ONet却只能输入固定size图片数据,即架构size,因为网络后面加了全连接,全连接对size则是非常敏感的
- 网络训练部分,其实也简单,无非就是forward传导和backward传导。网络做的主要是一个分类和偏移值的输出,因此关键就是确定采用什么样的损失函数。那么分类就可以采用交叉熵,偏移值即可采用平方差,然后就是确定反向梯度计算的优化器。代码方面,一定要注意输入数据的维度、形式,图片本身的格式一般都是:HWC,这里我们需要处理多张图片,因此需要加个批次即为:NHWC。Note:TensorFlow要求的数据格式为:NHWC,但是pytorch则是NCHW,一定要注意了,不同的框架输入格式可能不同,因此需要针对性的对数据进行处理。pnet,输出的是一个四维的数据,rnet,onet默认输出的是二维的,因此及应用的时候做不同处理
最后就是检测部分,pnet,rnet,onet三个网络分别做检测。pnet检测后输出一些人脸框输入rnet,rnet检测后得到一些框输入最有一个网络onet检测,最后回归到原图上的人脸框,这里涉及到一些关键技术,NMS,IOU,坐标值的回归计算
笔者做这个过程中遇到很多坑,当然因人而异 。笔者愚钝,开始在理论上付出很多代价,即使是现在里面的很多内容也没有理解到其精髓,还需后面进一步加强,其次就是代码部分,遇到很多关于形状变换的问题,经常在这上面出错,也是醉了,所以各位一定要注意这个。