Faster RCNN的特征提取模块使用的是VGG16(去掉了pool5及fc层):
Faster RCNN支持任意尺寸的输入,上图中input size=(P,Q)。
首先进行规范化尺寸,在检测时会将最小边缩放到600,最大边不超过1000。假定M*N=1000*600,经过基准网络VGG16的卷积模块,feature map的size为 60*40(1000/16~60, 600/16~40)。则feature map的维度为60*40*512(512为channel)。
经典的检测方法生成候选框都很耗时:OpenCV asaboost使用的滑动窗口+图像金字塔生成检测框、RCNN中使用Selective Search生成检测框。
Faster RCNN直接使用RPN(CNN)生成检测框,极大提升了检测框的生成速度。
接下来是网络这样设计的详细介绍
对于图像里目标检测边界框
【方法1】训练一个回归任务,输出4个值代表边界框的(xmin, ymin, xmax, ymax)。 这种方法存在问题:(1) 图像中的目标尺寸存在多尺度。常见的均方差作为loss难以训练。(2)实际预测时,无法保证xmin【方法2】预先设定好候选框,然后学习真实的bbox与候选框的偏移量。例:获取box:xcenter、ycenter、width、height,网络标签为Δxcenter、Δycenter、Δwidth、Δheight。偏移量一般数值较小且处于同一量级,网络可以很好的学习
!!!所以就要进行候选框的预设定的操作,也就是下面的anchor boxes的生成。
经过基准网络后,得到feature map的大小为 w*h,作为RPN的输入。
【anchor】feature map上的任意一个元素。用滑动窗口(conv)扫过feature map,滑动窗口的中心就是anchor,此中心会遍历feature map的每一个元素,所以anchor是遍历feature map上的每个元素。由于特征图和原始图像之间存在比例关系,在特征图上面密集的点对应到原始图像上面是有16个像素的间隔,如下图所示:
【anchor boxes】以base_anchor在input map上的映射点为中心构建的框
需要注意的是,anchor是基于feature map定义的,但anchor boxes是相对于原始图片的。
【RPN制作标签流程如下】:
以上的流程,是对于某一个anchor的操作。
【anchor boxes的数量】对于RPN输入feature map的大小为 w*h,对应的有w*h 个anchor、w*h*k个anchor boxes。
【平移不变性】当输入图片中的目标发生平移,但不会影响锚点和提议框的生成。作为比较,MultiBox方法[27]使用的k-means生成800个锚点,如果目标平移,MultiBox生成的提议框可能也会改变。
平移不变性也减小的模型的大小。该层的参数比MultiBox少了两个量级,期望可以在PASCAL VOC上有更小的过拟合
【多尺度锚点作为回归的参考】多尺度预测的方法
Faster RCNN使用了多尺度的锚点、单尺度的卷积层。下面会通过实验对比锚点的多尺度的效果。
对feature map上的每个像素分别生成9个anchor boxes,对这些anchor boxes进行过滤和标记。
二分类的label:
检测框偏移量的label:
上图中的黑框是anchor box,红框是predict box。实际的框计算示意图同理
所以RPN的loss function如下图
方程中的两项,通过各自的batchsize进行了归一化。我们通过实验发现:(1) 结果对宽范围的值不敏感[Table9];(2) 归一化不是必须的,可以简化。
概述一下RPN的计算流程:
经过基准网络VGG16后,feature map的大小为原图的1/16【feature map(60*40)的 1*1,对应原图(1000*600)的16*16】(默认k=9)
- feature map A,size=(1, 60, 40, 512)
- A 经过conv(3*3*512)*512,输出B的 output_size= (1, 60, 40, 512)
- 分类:B 经过conv(1*1*512)*18,output_size=(1, 60, 40, 18);在经过reshape,得到Ycls。
- 回归:B 经过conv(1*1*512)*36,output_size=(1, 60, 40, 36),得到Yreg。
- 训练时,也是在这里设置标签,进行RPN的训练
- 利用Ycls和Yreg,得到很多候选框。经过Proposal层,结合使用NMS筛选出约300个候选框,输入到下一层。
训练时的RPN结构图
红框:不关心基准网络的结构,所以将基准网络用ConvLayers代替,用红框圈出,后续图都如此
紫框:网络结构中部分,其余部分是label训练处理的流程。
rpn-data:(python AnchorTargetLayer)层会按照和test阶段Proposal层完全相同的方法用于训练
rpn_loss_cls:rpn_cls_score_reshape --->> p,rpn_labels -->>p*,Ncls参数被隐含了
rpn_loss_bbox:rpn_bbox_pred -->> t,rpn_bbox_targets -->> t*,rpn_bbox_inside_weight对应为p*。
综合anchor box、相应的得分、偏移量的信息,使用非极大值抑制 (NMS),筛选出较为精准的Proposal boxes(对应M*N维度),送入到RoI pooling。
caffe源码中的处理方式:
RPN的网络结构整体的流程就是
【生成设定的候选框anchor boxes】 --->> 【候选框内的数据的分类+偏移量回归】 --->> 【使用NMS筛选出指定数量的候选框】
基准模型提取的feature map、RPN提取的Proposal,输入到任务模块中。
为了接受不同尺度的数据,所以需要RoI pooling层,将不同维度的feature map转化成相同维度。所以RoI pooling相当于任务模块的接口。
在自己总结的Fast R-CNN中,有介绍RoI pooling的相关内容
这里RoI pooling的输入:【原始的feature maps】+【RPN输出的proposal boxes (尺寸不固定)】
这里RoI pooling的输出:固定维度的特征。
在代码实现中,
RoI pooling 的输入为:VGG16最后一层输出的feature map大小 (60,40,512)、RPN层产生的300个proposal boxes。
- 遍历每个proposal boxes将其坐标值缩小16倍,也就是获取了proposal boxes在特征图上的尺度。
- 对每个boxes内的特征图,划分成7*7个小区域,每个区域内使用maxpooling
RoI pooling的输出为:300*(7*7*512) 维度的特征(batchsize=300)
看到这里有疑问:(1) 如果boxes中的feature map的尺寸小于7应该怎样处理?(2) 并且输入图中的boxes对应到特征图上的boxes,不是整除的关系;使用7*7得到小区域,也不是一定是整除的关系。两次的向下取整的操作,造成了一定的精度损失,这又该怎样解决呢?
答:(1) 代码中应有处理方式,后续补充。(2) Faster RCNN并未解决该问题,而是在后续的Mask RCNN中得到了优化。
RoI pooling层的输出大小为 (300, 7,7,512),输入到全连接层。分为两个任务
训练时的结构图:
蓝框:从前面保存的pickle文件中读取出scores和rois,rois传入网络
绿框:计算bbox_inside_weights+bbox_outside_weights传入soomth_L1_loss(??????)
基准网络选择VGG,使用预训练好的参数。实际训练过程的步骤:
这里只是用了类似的2次循环训练。作者表述,循环更多次后效果并没有提升。
基准网络:预训练好的VGG
优化器:SGD
batch:每一个mini-batch包含从一张图片中随机提取的256个anchor(注意不是所有的anchor都用于训练),正样本和负样本比例为1:1。如果图个图片中正样本数小于128,则多用一些负样本以满足256个Proposal训练。
初始化:新增的2层参数用均值为0,标准差为0.01的高斯分布来进行初始化,其余层(都是共享的卷积层,与VGG共有的层)参数用ImageNet分类预训练模型来初始化
参数化设置:个
在PASCAL数据集上:
前60k个mini-batch进行迭代,学习率设置为0.001;
后20k个mini-batch进行迭代,学习率设置为0.0001;
设置动量momentum=0.9,权重衰减为0.0005
画图工具:http://ethereon.github.io/netscope/#/editor
https://blog.csdn.net/w113691/article/details/78644982