ROI Pooling vs ROI Align
ROI (Region of Interest) 是计算机视觉中,从被处理的图像以方框、圆、椭圆、不规则多边形等方式勾勒出需要处理的区域。通俗的讲就是原图中的一个区域检测块,ROI提取出来之后会被用来后续的目标检测。现如今已经有很多成熟的方法可以用来提取ROI,比如传统的是用一些离线的计算机视觉的方法(如selective search)来获取。在faster R-CNN后更主流的是用Region Proposal Network,用训练神经网络的方式从特征图(feature map)中提取ROI。
用上述方法提取到的ROI是大小不一的区域块,在输入到全连接层之前,还需要经过一个叫ROI pooling layer(下图蓝色框部分)的层来把这些大小不一的区域块调整到一致的大小。
RoI pooling layer
RoI pooling layer中就用到了本文要讲的2个算法,分别是ROI pooling和ROI align。ROI align其实是RoI pooling的进化版,它是mask RCNN中引入的,消除掉了ROI pooling的2次量化过程所造成的误差,从而在mask RCNN中实现了像素级的目标检测。
ROI Pooling
我们来看看ROI Pooling是怎么工作的。假设现在模型的backbone是VGG16,我们用selective search在原图中找了一堆目标候选图,那我们会如何在feature map中找到对应的ROI呢?
extract RoI
拿其中一个候选图距离,它的实际尺寸是200*145,左上坐标(x,y) = (296,192)
VGG16最后的卷积层feature map相对原图是缩小了32倍,按原尺寸缩小32倍不难发现坐标很多都不会是整数。
- width: 200/32 = 6.25
- height: 145/32 = ~4.53
- x: 296/32 = 9.25
- y: 192/32 = 6
如下图所示,由于RoI尺寸不是整数,无法和feature map的cell对齐
mismatch with feature map
那要怎么处理这些非整数呢,这里就要引入一个概念叫Quantization——量化,说白了就是向下取整。这种情况我们会把坐标数值都向下取整,即量化。结果如下图所示
Quantizaton
很明显这个操作有个缺点就是我们丢失了一部分图像数据(蓝色的部分),还多计算了一部分画面(绿色的部分)
这就是ROI pooling量化导致的第一次误差。
现在我们已经在feature map中找到了一堆ROI,接下来就要对ROI做pooling——即之前提到的要把它们调整到一致的大小。举例最后我们要输入到全连接层的ROI大小是3*3,那么我们就需要想办法把现在4*6的ROI压缩成3*3
ROI pooling用的还是向下取整的笨办法,如下图直接长宽按比例缩放。
这个方法的缺点显而易见,就是第四行的数据彻底丢失了。这也是ROI pooling量化导致的第二次误差。
这里我们采用max pooling的方式做下采样,avg pooling也同理
VGG16的feature map是512维的,所以经过pooling之后,所有ROI都会被转成3*3*512的统一大小输入到后续的全连接层。
RoI Align
ROI align是在mask R-CNN中引入的,他们发现在ROI pooling中引入的微小误差,在做像素级的语义分割时,误差会放大。所以ROI Align的目标就是为了消除ROI pooling中的两次量化操作导致的误差。
让我们回到量化前的图,我们现在试着把带小数的尺寸按3*3等分,即会均匀分成2.08*1.51的9个小块。
其实我们的目标就是要从每个小块的中心点提取出准确的值信息,这样就不会有信息丢失了。这里我们会用到双线性插值算法(bilinear interpolation)
首先在每个小块中采样4个点,我们取得是长宽的3等分点。坐标如下图所示
4个采样点
之后就是要分别计算每个采样点的值了,根据临近的元素值通过双线性插值的方式计算。
bilinear interpolation
拿第一个点举例,它坐标是(9.94, 6.50),和它最近的4个元素坐标是(9.50,6.50),(10.50,6.50),(9.50,7.50)和(10.50,7.50)。直接套用上面的公式,就可以巨酸出来(9.94,6.50)的双线性插值是0.14
我们计算出4个点的值,分别是0.14,0.21,0.51 和0.43。现在我们就可以对这个小块就pooling了,这里用max pooling的方式取出值0.51
接着我们就对所有块都计算一遍之前的操作,得到最终pooling后的matrix
后续的过程就和ROI pooling是一样的。
最后我们来比较以下2个算法的区别。下图右边是ROI pooling,可以看到它在pooling时丢失了很大一部分数据(蓝色的部分),而ROI align在pooling时使用的是整块区域,没有丢失数据,在mask R-CNN中也证明了使用ROI align,正确率比pooling方法高了不少。当然不管是ROI pooling还是ROI align,我们要知道他们的任务都是把ROI调整成合适的大小,所以它们并不是只适用于特定的神经网络,你当然也可以把ROI align应用到faster R-CNN中,如果你想进一步提升性能的话。
refs:
Understanding Region of Interest — (RoI Pooling)
Understanding Region of Interest — (RoI Align and RoI Warp)
R. Girshick. Fast R-CNN. In ICCV, 2014 https://arxiv.org/pdf/1504.08083.pdf
K. He, G. Gkioxari, P. Dollar and R. Girshick. Mask R-CNN In ICCV, 2018 https://arxiv.org/pdf/1703.0687