RoI Align 来源于 17 年提出的经典目标检测与实例分割模型: Mask R-CNN.
在这篇论文中,作者明确指出:RoI Pooling 的量化误差会显著影响像素级任务。
因此,他们提出了一种针对性的改进:
不改变整体框架,只修正对齐方式。
RoI Align 核心思想也并不复杂,总结来说就是:
取消 RoI 边界映射和 bin 分割中的取整,保留所有浮点数表示的边界,用双线性插值来获取采样点的特征值。
下面来详细展开:
2. RoI Align 的具体改进#
2.1 候选框映射#
在这一步的改进较为简单,就是直接省去取整步骤:
2.2 划分子区域#
这一步和原本的 RoI Pooling 没有区别,只是候选框并没有取整。
我们直接用图中的例子来演示完整逻辑,设 ,已知 RoI 为:
首先计算 RoI 在特征图上的宽和高:
,
因为要划分为 ,计算得到每个 bin 的尺寸为:
,
最终,四个子区域划分如下:
| 位置 | x 范围 | y 范围 |
|---|---|---|
| 左上 (0,0) | ||
| 右上 (0,1) | ||
| 左下 (1,0) | ||
| 右下 (1,1) |
现在,整个 RoI 被均匀、连续地切分,没有任何量化误差。
但新的问题是:
连续划分的 bin 并不和特征图网格完全贴合,要如何取样进行下一步池化?
这便是 RoI Align 的核心内容,关键点只有一句话:
既然采样点不再落在整数网格上,那就必须“估算”这个位置的特征值。
2.3 线性插值和双线性插值#
插值是使用离散点估计连续值的常见方法,我们先简单介绍一下。
假设在一条数轴上,我们已知两个点的值:
现在我们想求一个中间位置 的值,该怎么办?
直觉上,这个点更接近 1,因此它的值应该更偏向 。
所以,这里线性插值的公式就是:
其中:
最终得到估计值:
这便是一维线性插值的逻辑,由此我们推广到二维的双线性插值:
特征图是一个二维离散网格,而我们的采样点 通常是浮点数,比如:
就像我们现在遇到的,这个点不会正好落在某个像素中心,而是落在一个“格子内部”。
其周围最近的四个整数点是(以视觉任务中惯例的左上角为原点):
- 左上:
- 右上:
- 左下:
- 右下:
双线性插值本质是:先横向插值,再纵向插值(或者反过来也一样)。
于是,我们定义:
在本例中不难得到:
最终结果是四个点的加权和:
总结双线性插值的逻辑如下:
一个采样点的值,是由它周围四个网格点“按距离加权平均”得到的。越近权重越大,越远权重越小,四个权重加起来刚好为 1 。
到这里,就可以明白 RoI Align 的采样思路了。
2.4 采样每个子区域#
现在,我们已经有了划分好的连续子区域,这些 bin 不像取整划分一样直接固定好了采样点。因此问题变成了:
一个 bin 内,到怎么取点?取多少个点?
这就引出了新的超参数:采样率(sampling ratio),或者采样密度。
具体展开,对于每个 bin,在两个方向分别定义采样率:
我们可以手动指定两个方向的采样率,在原论文的设计中,每个 bin 内固定为 4 个规则采样点。但现代更常见的是自适应采样:
得到采样率后,我们就可以以此划分该方向的步长:
最终,我们以等分加中心偏移的形式得到采样点的位置:
这种设计是为了让点“取中心”,不然不同 bin 的采样点就会在边界处发生重合,在偶数采样率时还会发生不对称取点的情况。在下面的例子里就可以直观感受到这点。
先总结采样逻辑如下:
直接对 bin 的尺寸向上取整,作为该方向的采样率。以此在 x 和 y 方向分别均匀划分,形成规则的 个采样点。