ROI Pooling 和 ROI Align

不想你离开。 提交于 2020-01-29 02:12:34

1. 为什么会提出ROI Pooling?

在Rcnn系列检测器中,rcnn在selective search后得到一系列的预选框,再将这些预选框 resize到同样大小的尺寸,通过卷积网络,再进行检测,这是因为固定的卷积网络需要同样大小的输入,这样多次通过网络,不仅费时,box之间存在大量的重复区域,也浪费了计算资源。

selective search
resize
CNN
Image
box
box_samesize
vector

在之后改进的Faster rcnn中,图像通过卷积网络后得到feature map,此时根据预选框的位置坐标在对应到特征图中。但是每个预选框大小不同,对应在特征图的大小也不同。所以通过RO Pooling将特征图区域池化为固定尺寸,以便进行后续的分类和包围框回归操作

selective search
map
CNN
ROIPooling
Image
box
feature_map
vector

2. 为什么会提出ROI Align

由于预选框的位置通常是由模型回归得到的,一般来讲是浮点数,而池化后的特征图要求尺寸固定。故ROI Pooling这一操作存在两次量化的过程。

  • 将候选框边界量化为整数点坐标值。
  • 将量化后的边界区域平均分割成 k x k 个单元(bin),对每一个单元的边界进行量化。
    在这里插入图片描述

从图中可以看到两次量化舍弃了小数位,第二次量化舍弃了小数点后的0.8,feature map尺寸是原图的1/32,所以一个像素的误差放大到原图就是接近32个像素。
所以需要一种可以尽量避免这种误差的替代方法

3. 方法本质

ROI Pooling的本质是最近邻插值法,即选取离点最近的像素点的值作为该点的值。

ROI Align的本质是双线性插值,即两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。其原理是待插点像素值取原图像中与其相邻的4个点像素值的水平、垂直两个方向上的线性内插,即根据待采样点与周围4个邻点的++距离++确定相应的权重,从而计算出待采样点的像素值。
在这里插入图片描述

f(x,y)(1dx)(1dy)f(0,0)+(dx)(1dy)f(1,0)+(1dx)(dy)f(0,1)+(dx)(dy)f(1,1) f(x,y) \approx (1-dx)(1-dy)f(0,0)+ (dx)(1-dy)f(1,0)+ (1-dx)(dy)f(0,1)+ (dx)(dy)f(1,1)

4.代码

mxnet里有定义好的函数,可以直接调用

from mxnet.ndarray import ROIPooling
from mxnet.contrib.ndarray import ROIAlign

x = mx.nd.array(
    [[[[  0.,   1.,   2.,   3.,   4.,   5.],
       [  6.,   7.,   8.,   9.,  10.,  11.],
       [ 12.,  13.,  14.,  15.,  16.,  17.],
       [ 18.,  19.,  20.,  21.,  22.,  23.],
       [ 24.,  25.,  26.,  27.,  28.,  29.],
       [ 30.,  31.,  32.,  33.,  34.,  35.],
       [ 36.,  37.,  38.,  39.,  40.,  41.],
       [ 42.,  43.,  44.,  45.,  46.,  47.]]]])

#// region of interest i.e. bounding box coordinates.
y  = mx.nd.array([[0,0,0,3,3]])

#// returns array of shape (2,2) according to the given roi with max pooling.

print(ROIPooling(x, y, (2,2), 1.0))
[[[[ 7.  9.]
   [19. 21.]]]]
<NDArray 1x1x2x2 @cpu(0)>

print(ROIAlign(x, y, (2,2), 1))

[[[[ 5.25  6.75]
   [14.25 15.75]]]]


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!