简化版mtcnn--复现过程详解

这篇博客记录了我复现mtcnn的理论流程,相关处理(nms及iou等)操作可见本专栏,时间有限只用了边框回归,人脸关键点没有考虑,过些天再加上一波,代码待整理之后放上。
人脸检测旨在解决两个问题,1是识别图中有没有人脸,2是有的话,人脸在什么位置并画出人脸框
在解决上述两个问题时,mtcnn采用了下面两个方法:

  • 找出所有可能是人脸的候选
  • 从候选区中筛选出最可能是人脸的候选区。
    可以看出,这种操作带来高准确性的同时,也会使得其速度变慢,特别是在第一步中。

1.mtcnn训练部分

1.1,怎么产生正、负、部分样本?

没有对比就没有差异,没有差异就没法学习。
问题1和问题2要结合起来看

  • 顾名思义,正样本就是包含人脸的样本框,负样本为不包含人脸的样本框,部分样本为包含部分人脸的样本框。
    在mtcnn作者通过iou来区分这三种样本的:
    正:iou>0.65;部分样本:iou>0.4;负样本:iou<0.3。这些值需要根据不同的数据集进行调整。
      产生过程是一种随机截取,具体为,在我们拿到数据集后,里面会有与该人脸对应的人脸框,即人脸的位置坐标(x1,y1,w,h),这里的随机截取是有技巧的,不能在整个图片上毫无目的的来截取,因为我们想获得足够多的positive,negative,part,而假如只有一个人脸的话,直接随机截取很容易获得很多没有用的图片。所以这里采用中心点偏移来随机截取,即先找到数据集给定的人脸框中心点的位置,然后根据让中心点进行随机微调多次,再分次进行截取,通过计算其与数据集给定人脸框的iou值,最后resize为12,24,48,这样就可以获得足够多的正,负,部分样本了,然后在保存的时候,给正样本标为1,负样本标为0,部分样本标为-1,就可以获得神经网络输入对应的x和y_lable了。(对三个网络,产生3个数据集,截取框的大小分别为12,24,48)
1.2,采用偏移量进行边框回归?

   但是,论文中和问题1中描述的有不同的是,在边框回归的过程中,利用的是offset偏移量,计算方法为:假设标定的人脸框左上角横坐标为x1,框的宽高为w和h,随机产生的框的横坐标为x1_,那么,offset = (x1_-x1)/min(w,h),这里存在归一化可以把它理解为,该点基于框的宽高的偏移程度,是往左偏移了0.1倍,还是往右偏移了0.2倍??等等。结合问题2,在随机截取图片后,先计算出offset,然后再通过计算iou将其分为正负部分样本,resize后,最后再给它们标上标签,具体标法例子为:正样本:{1,offset_x1,offset_y1,offset_x2offset_y2},这样就得到了我们真正的神经网络输入x和y_lable了。

  • 为什么采用偏移量进行边框回归?
    假设一个图里面最小有12x12的人脸以及最大有500x500的人脸,如果直接预测坐标和宽高,那么预测值的波动范围会比较大,模型的预测空间会非常大,会导致模式训练不容易收敛。而采用偏移量的方式,会是预测空间比较小,会让模型训练容易收敛。
  • 损失函数的选择及还原原图坐标
    这样把x和y_label输入神经网络后,输出的ylabel也为置信度和偏移量offset,偏移量的损失函数为mse平方差损失函数,训练目的就是使得输出的偏移量更接近给定的人脸框的偏移量,从而反算回去,得到原图上预测到的人脸框坐标,公式为:

x 1 ∗ = x 1 + o f f s e t ∗ m i n ( w , h ) {x1_*} = x1+offset*min(w,h) x1=x1+offsetmin(w,h)
关于人脸分类采用的交叉熵损失函数,这里就不细说了。

  • 这里为什么要进行归一化?
    原因在于我们这里使用了resize,对于图片数据x和p网络,我们需要将其resize为12x12,而对于标签,归一化之后,resize对标签中的offset值不会产生干扰。
  • 样本如何去使用?
    1)在人脸分类过程中,即是非人脸问题,这里采用只正样本和负样本,原因应该是两者相差较大,在训练中能使模型快速收敛。
    2)在边框回归的问题中,使用了正样本和部分样本,原因在于,负样本里面几乎没有人脸,而正样本和部分样本里面是存在人脸或部分人脸的,这样子做offset来回归是可行的。

2,mtcnn测试流程

前言,为什么要图像金字塔?

  一句话,为了解决目标的多尺度问题。因为实际原因,我们需要处理的图片中人脸的尺寸大小不一,为了避免算法被人脸尺寸影响,我们需要创建一组具备不同分辨率的相同图像集,并且在这个图像集中搜索对象去搜索目标。

  上图是mctnn的第一个网络:P网络,可以看出,P网络能接受的输入大小固定为为12x12,我们想要在测试中使得效果最佳,需要将待识别的人脸r按照缩放比例去resize到12x12得到类似金字塔的结构,再将这些图片都传入p网络中处理。

整个流程可以从论文中这个图看出来。(文中数据需要根据实际情况修改)
在这里插入图片描述
  第一行对应图像金字塔处理。缩放规模为0.7-0.8。拒绝调包!且看MTCNN人脸检测推断过程详解!参考知乎博文:图像金字塔在进行缩放操作时,默认把宽和高变为1/2,那么面积就变为了1/4,如果认为图片缩放幅度过大,只想将面积变为1/2,那么只需将宽高变为sqrt(1/2),即为0.709。对图片进行resize直到最小边尺寸等于12为止,这样就得到了原图,原图x0.7,原图x0.7^2…系列图片,即为图像金字塔,然后把这些图片都输入P网络。
在这里插入图片描述
  第二行对应把这些大小不一的图片都输入P网络,p网络会预测出一堆预测框偏移量,把这些预测框还原到原图上后,将其进行nms非极大值抑制,筛选掉一大部分候选预测框,这里nms的阈值设置为,也就是iou的阈值0.5,也会得到一大部分候选预测框,此步为粗略筛选。经过P网络后,候选框变少,但任大量存在。

  第三行对应为P网络输出的结果输入R网络。过程同上,这里的R网络设计的更为精细。
在这里插入图片描述
输入R网络的数据为:原始图片,经过p网络后得到的候选回归框。注意,这里有个细节是:先根据p网络提供的候选回归框从原图上抠出图片(是根据候选回归框边长最大值去截取,这样是因为PNet中推理出来的bounding box坐标可能超出元素图片的大小,这时候需要做下图片处理,把坐标值限定在元素图片内,而空出来的数据值为0)。再把它resize为24x2输入网络,这样,R网络会根据该数据输出预测的y_label,即为置信度和4个偏移量,同样,先筛选出置信度>0.6的框,再还原到原图上后,再对这些框进行nms,阈值设为0.5,得到更精确的候选框。从图中可以看出,经过R网络后,候选框显著变少我觉得这个图应该在多几个框才比较直观。
  第四行对应为R网络输出的结果输入O网络,流程同R网络类似:
在这里插入图片描述
输入O网络的数据为:原始图片,经过R网络输出的候选回归框。同样先通过R网络提供的回归框最大边长抠图,再resize成risize为48x48输入O网络,后面过程一样,只是阈值设的比较高,我设的是置信度阈值设为0.97,nms的阈值设为0.7。最后得到返回的人脸框坐标。

3.注

1)mtcnn训练和测试是不同的,测试的时候是按照流程一步一步走的,训练的时候,每个网络都有自己的数据集,可以并行训练。我刚学这个时候总是会把这两者弄混,在看训练代码的时候总是想着图像金字塔在哪,找不到就觉得自己真是个瓜皮,哈哈。
2)复现还有很多要完善的地方,例如学习率得随着训练过程变化,用矩阵运算代替for循环等等。
3)以上为自己复现mtcnn的一点心得,参考了很多大神的博客理解及代码,在此鞠躬!
在这里插入图片描述

参考博文:

http://www.sfinst.com/?p=1683
https://zhuanlan.zhihu.com/p/58825924
https://space.bilibili.com/471915350/
https://zhuanlan.zhihu.com/p/32121614

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

通信仿真爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值