首次把记载的东西,拿出来和大家分享、讨论。有理解错误的地方请指出。下面把刚接触时,对Pnet(第一层网络),在前向传播时,如何产生的人脸Proposals,进行代码解读。代码参考的是tensorflow版,原作者为了大家理解代码写的好多重复,在前任的基础上,我进行了删减与增加。增加了一些脚本文件,供大家参考。并且尝试了修改原论文作者的框架深度,训练显示在卷积层不能做padding。我把修改过的MTCNN-tensorflow版代码放到了github上,感兴趣的可以下载点击打开链接。readme文件没做太多修改,后续有时间完善。(这里要感谢原作者)。下面对Pnet的前向如何提取proposal进行纾解。
此段代码是来自Detection文件下的MTCNNDetector.py
boundingbox = np.vstack([np.round((stride*t_index[1]+1)/scale),
np.round((stride*t_index[0]+1)/scale),np.round((stride*t_index[1]+1+cellsize)/scale),
np.round((stride*t_index[0]+1+cellsize)/scale),
score,
reg])
###################
Pnet有两个输出,一个是softmax输出即得分(:0背景,1人脸),一个是目标框的回归(4维:x,y,w,h)
Pnet 两个输出的维度是: softmax (1,2,x,y); 线性回归:(1,4,x,y) // 这里的x, y代表的是图像经过隐藏层之后,长和宽还剩下的维度。
softmax的输出意义:[0,1,:,:]表示人脸目标的概率, 其有x*y个
线性回归的输出意义:[0,0,:,:]表示左上角x方向的微调
[0,1,:,:]表示左上角y方向的微调
[0,2,:,:]表示右下角x方向的微调
[0,3,:,:]表示右下角y方向的微调
-------因为线性回归的目标函数是预测与目标框的差值
最终boundingbox的两个坐标点确定是根据softmax
-------------- 选出softmax里得分最高的几个,然后根据其 x与y 的值映射回原图像,来找到人脸框。
--------------- 原因,经过卷积等处理后得到的 维度(x,y),每一个点代表一个人脸框的结果。所以每一个点都可以映射回原图找到人脸。因此一共有 x*y个框。
#################################################
Pnet训练数据处理
一幅原图片是有bbox标签的[x1,y1,x2,y2],图像的宽与高为 c, r;
负样本的生产:
1)在原图中任意位置生产bbox ---{扣取50个}
在[12,min(c,r)/2] 中任意取一个数做为 负样本bbox的size。左上顶点坐标[x1,y1],在[0,c]与[0,r]中任意取。用这个bbox来与这个图片中所有的gd_bbox
做面积的重叠比值,小于0.3的做为负样本,从原图扣取图片,没有bbox标签。
2)在原图的每一个bbox中心点附近生产bbox ---{扣取5个}
生产的size与(1)相同;左上角定点从[x1-size, x2]中产生新的nx1,同理产生ny1;用新的bbox来与这个图片中产生这个样本的gd_bbox
做面积的重叠比值,小于0.3的做为负样本,从原图扣取图片,没有bbox标签
正样本的生产
在原图中每一个bbox附近生产 ---{扣取20个} 每一个bbox的宽与高为 w,h
生产的候选bbox的大小为 [min(w,h)*0.8, 1.25*max(w.h)]中任意选取。 新的bbox的中心点的产生是与产生这一个样本的bbox的中心点的偏移决定。
偏移量在[-w*0.2, w*0.2] 和[-h*0.2, h*0.2]中任意取高与宽。
新的bbox与产生这一个的标签bbox面积做比值, IOU >=0.65标记为1 剩下的 IOU >0.4的标记为-1 ;
制作样本的bbox的标签 offset_x1 = (x1-nx1)/float(size) 同理其他, 所以标签为 真实值的偏移量与样本的size的比值
##########################################3
下面贴几个训练后的结果图