参考自:https://www.cnblogs.com/wangyong/p/8523814.html
仅作记录学习~
个人理解/总结
含有FC层的网络,要求输入图像尺寸必须一致。因为FC层的参数量是固定的,都是C类*前一层特征数量,要是输入图尺寸不一,FC便无法计算。
而卷积却没有这个问题,是因为卷积的参数运算 只与自身卷积核大小有关,与输入图或前层的输出大小无关。
在two-stage检测算法里,
- 最原始的R-CNN,先通过各种方法或取候选框,再通过候选框在原图上扣除目标区域,送到后面CNN提特征分类。送入CNN前,子区域大小不一,这也是为什么会warp成一个大小在送入的原因。
- faster rcnn中的 roi pooling, mask rcnn中的 roi align就是对此步骤的优化,提速。
不必对每个目标区域提特征。只要提全图特征,根据检测框坐标,映射到调整图上,直接取对应子区域特征(图)就好了。 - 其中,映射过程就涉及到了比例缩放,难免会有除不尽或除出小数的情况,这种对量化精度的取舍就是两种roi操作的区别。
ROI Pooling
这个可以在Faster RCNN中使用以便使生成的候选框region proposal映射产生固定大小的feature map
先贴出一张图,接着通过这图解释RoiPooling的工作原理
针对上图
Conv layers使用的是VGG16,feat_stride=32(即表示,经过网络层后图片缩小为原图的1/32),原图800800,最后一层特征图feature
map大小:2525假定原图中有一region proposal,大小为665665,这样,映射到特征图中的大小:665/32=20.78,即**20.7820.78**,如果你看过Caffe的Roi
Pooling的C++源码,在计算的时候会进行取整操作,于是,进行所谓的第一次量化,即映射的特征图大小为20*20假定pooled_w=7,pooled_h=7,即pooling后固定成77大小的特征图,所以,将上面在 feature map上映射的2020的 region
proposal划分成49个同等大小的小区域,每个小区域的大小20/7=2.86,即2.86*2.86,此时,进行第二次量化,故小区域大小变成2*2每个22的小区域里,取出其中最大的像素值,作为这一个区域的‘代表’,这样,49个小区域就输出49个像素值,组成77大小的feature
map
总结:
通过上面可以看出,经过两次量化,即将浮点数取整,原本在特征图上映射的2020大小的region
proposal,偏差成大小为77的,这样的像素偏差势必会对后层的回归定位产生影响所以,产生了替代方案,ROI Align
ROI Align
这个是在Mask RCNN中使用以便使生成的候选框region proposal映射产生固定大小的feature map时提出的
先贴出一张图,接着通过这图解释RoiAlign的工作原理
同样,针对上图,有着类似的映射
Conv layers使用的是VGG16,feat_stride=32(即表示,经过网络层后图片缩小为原图的1/32),原图800800,最后一层特征图feature
map大小:2525假定原图中有一region proposal,大小为665665,这样,映射到特征图中的大小:665/32=20.78,即**20.7820.78**,此时,没有像RoiPooling那样就行取整操作,保留浮点数
假定pooled_w=7,pooled_h=7,即pooling后固定成77大小的特征图,所以,将在 feature map上映射的20.7820.78的region proposal
划分成49个同等大小的小区域,每个小区域的大小20.78/7=2.97,即2.97*2.97假定采样点数为4,即表示,对于每个2.97*2.97的小区域,平分四份,每一份取其中心点位置,而中心点位置的像素,采用双线性插值法进行计算,这样,就会得到四个点的像素值,如下图
上图中,四个红色叉叉‘×’的像素值是通过双线性插值算法计算得到的
最后,取四个像素值中最大值作为这个小区域(即:2.972.97大小的区域)的像素值,如此类推,同样是49个小区域得到49个像素值,组成77大小的feature map
总结:
知道了RoiPooling和RoiAlign实现原理,在以后的项目中可以根据实际情况进行方案的选择;对于检测图片中大目标物体时,两种方案的差别不大,而如果是图片中有较多小目标物体需要检测,则优先选择RoiAlign,更精准些。
更多详细解释可参考: 链接