type
status
date
slug
summary
tags
category
icon
password
😀
博主在学习深度学习时,遇到有关 RoI Align 的知识,为了方便理解记忆故记录下这篇博客。
 

📝 主旨内容

1. RoI Align 相关背景知识

首先,RoI的英文全称是: Region of Interest (感兴趣区域),RoI是针对原始图片的提议区域(proposed region)。
 
在实现基于pytorch的目标检测算法时,一种方法是基于 Faster R-CNN 目标检测框架。而 Faster R-CNN 目标检测框架也是对 R-CNN 系列算法的进一步改进。其将候选框生成与目标分类合并到一个网络中(这样就避免了 R-CNN 与 Fast R-CNN 模型的主要缺陷:它们使用两个独立的网络,一个用于识别可能包含对象的区域,一个用于对预测的识别对象边界框进行校正),实现了端到端的训练。可以同时优化候选框生成和目标分类任务,提高了检测的准确性和效率。
 
在 Faster R-CNN 与 Fast R-CNN 模型检测的步骤中,对区域提议均采用 RoI pooling 操作,这样能避免通过预训练模型传递所有(调整大小后的)区域提议,极大的减少了重复计算,提高了检测速度。然而,事实上在执行 RoI pooling 操作时可能会丢失某些信息。
(关于 RoI pooling 的详细操作与缺陷,见补充部分)
 
然而,在进行基于深度学习的图像分割算法时,由于与传统目标检测算法相比,基于 Faster R-CNN 的 Mask R-CNN 算法要求不仅可以准确地检测图像中的对象,还可以为每个对象生成精确的像素级别的分割掩码。这意味着 Mask R-CNN 要更细粒度地理解图像的结构与语义信息。所以,RoI pooling 操作的计算精度已经不能满足实际要求。
 
为此,在后来的 Mask R-CNN 算法架构中,将 Faster R-CNN 的 RoI pooling 层修改为更加精准的 RoI Align 层。
 
RoI Align 首先在 Mask R-CNN 中引入。其解决了 RoI pooling 中的数据丢失问题,使得数据能够保全。它们之间的区别在于量化,RoI Align在data pooling中没有使用量化。

2. RoI Align 计算方法

1.首先将 feature map 上的RoI切分成9个相等尺寸的 boxes,如图1所示:
notion image
图1
box的宽:4.53 / 3 = 1.51
box的高:6.25 / 3 = 2.08
 
你可能会疑惑,为什么要除以 3?
其实,这个 3 主要根据你的 pooling 层的 size 有关。例如,你的 pooling layer size 为 3x3,那么,这里就是 4.53/3 和 6.25/3 。
也就是说:每个 box 的 size 都取决于 feature map 上的 RoI 的大小 和 pooling 层的大小
 
如图2所示,我们将 RoI 切分为9个 boxes :
notion image
图2
 
观察一下图3中最左上角的 box,它包含6个 cell :
notion image
图3
 
2.我们需要从 box 中提取值,输入到 pooling 层。在这之前,需要进行数据采样。首先,需要在 box 中创建4个采样点,如图4所示:
notion image
图4
观察一下这张图,左上角中 box 里的4个采样点,分别是:(9.94, 6.50), (10.64, 6.50), (9.94, 7.01), (10.64, 7.01)
 
那么,上面4个点的值怎么计算出来的呢?
(1)我们先看一下图-18,左上角起点的坐标是:(9.25, 6),即:x=9.25, y=6,每一个网格的 width=2.08,height=1.51
notion image
图5
(2)接下来,我们分别计算网格中的四个坐标点的值,顺序是先第一列的2个点,然后再计算第二列的2个点。
第一个点的坐标计算:
X1 : 9.25 + (2.08 / 3) ~= 9.94
Y1 : 6 + ( 1.51 / 3) ~= 6.50
第二个点的坐标计算:
X2 : 9.25 + (2.08 / 3) ~= 9.94
Y2 : 6 + ( 1.51 / 3) * 2 ~= 7.01
第三个点的坐标计算:
X3 : 9.25 + (2.08 /3) * 2 ~= 10.64
Y3 : 6 + ( 1.51 / 3) ~= 6.50
第四个点的坐标计算:
X4 : 9.25 + (2.08 /3) * 2 ~= 10.64
Y4 : 6 + ( 1.51 / 3) * 2 ~= 7.01
 
3.计算完4个点坐标之后,我们将利用双线性差值公式计算差值。公式如下所示:
notion image
 
(1)根据这个公式,我们先计算第一个点的双线性差值,如图6所示:
notion image
图6
第一个点的双线性差值为:0.14
 
(2)按照同样的方式计算出第二个点的差值,如图7所示:
notion image
图7
第二个点的双线性差值为:0.21
 
(3)按照同样的方式计算出第三个点的差值,如图8所示:
notion image
图8
第三个点的双线性差值为:0.51
 
(4)按照同样的方式计算出第四个点的差值,如图9所示:
notion image
图9
第四个点的双线性差值为:0.43
 
4.计算完一个网格中四个双线性插值后,可以利用 max pooling 获取四个值中的最大值当做最终值。如图10所示:
notion image
图10
 
使用上述计算方法应用到所有层(512层),如图11所示:
notion image
 
图11
 

3.RoI Align 与 RoI Pooling 的比较

3.1 RoI Align 与 RoI Pooling 的区别在于前者在计算过程中会用到所有数据,而后者则会丢失数据。如图12所示:
notion image
图12
3.2 我们对比一下这两者的性能的区别:如图13所示:
notion image
图13
 
总结来看,RoI Align 在 precision 上带来了更大的性能提升。
 

4.补充部分:RoI pooling 的详细操作与缺陷

4.1 RoIPool 概念

RoIPool 是一种区域池化操作,可以提取出固定大小的特征图,RoIPool 内部会将 RoI 区域均匀地划分为 k*k 个部分,并针对每个小部分执行最大池化操作,最终将所有结果拼接在一起得到固定大小的输出特征图,RoIPool 的输出大小是固定的,因此可以输入到后续网络中执行操作。

4.2 ROI pooling具体操作如下:

  1. 根据输入 image,将 ROI 映射到 feature map 对应位置;
  1. 将映射后的区域划分为相同大小的 sections(sections 数量与输出的维度相同);
  1. 对每个 sections 进行 max pooling 操作;
这样我们就可以从不同大小的方框得到固定大小的相应的 feature maps。值得一提的是,输出的 feature maps 的大小不取决于 ROI 和卷积 feature maps 大小。ROI pooling 最大的好处就在于极大地提高了处理速度。

4.3 具体实例

例如:我们有一个 16x16 的 feature map,一个获取得到的 RoI,以及规定输出为 3x3 。
(1)feature map 如图14所示,该图左边是原始图像,其 size 是: 512 x 512 x 3 (width x height x RGB),经过 VGG16 进行特征提取后,得到右边的 size 为 16x16x512 的 feature map :
notion image
图14
这个 feature map 的宽和高分别是 16 和 16,正好是输入图像 512x512 缩小了 32 倍。512 / 32 = 16,所以这里的缩小因子 factor=32。记住这个值,后续所有的 RoI 在缩小时,都需要除以 32,得到缩小后的尺寸。
【注意:不同的案例,feature map 和 factor 的大小都不同,这里只是举例说明。】
 
(2)接下来,说明如何从 feature map 上获取 RoI :
图15表示:将原始图像上的 RoI 映射到 VGG16 输出的 feature map 上后的效果。
notion image
图15
每一个 feature map 上的 RoI 都有相对于原始 RoI 的坐标和尺寸(即在图片中的相对位置不变),如图16所示:
notion image
图16
图16中的红框尺寸是: 145 x 200,即:高=145,宽=200,左上角的坐标值=(192, 296)。
之前我们提到过缩放因子 factor=32,那么,这些原图上的 RoI 映射到 feature map 上,其尺寸需要缩小 32 倍,左上角坐标值需要缩小 32 倍。即:
宽和高:
width : 200 / 32 = 6.25
height : 145 / 32 ~= 4.53
左上角坐标:
x : 296 / 32 = 9.25
y : 192 / 32 = 6
 
将上述计算结果应用到 feature map 上,就可以得到图17:
notion image
图17
 
(3)然后,我们在 feature map 上进行坐标值量化(quantization of coordinates)
首先,量化的概念:量化是一个将输入从一个大的值集(如实数)限制为离散的值集(如整数)的过程。
那么,我们为什么要量化,如图18所示:
notion image
图18
我们可以明显发现一个问题,我们不能够直接在这个 RoI 上应用 RoI pooling 操作。观察一下这个图,有些 cell 并没有与网格线对齐,要么多了一点,要么少了一点。解决措施就是用量化操作,说白了,就是向下取整,例如:9.25 改为 9,4.53 改为 4.
如图19所示,量化后的 RoI :
notion image
图19
观察一下上图,深蓝色区域为丢弃的区域,左边的红色区域为新增的区域。我们再看一下量化后的 RoI 完整的示意图(绿色部分即为新的 RoI 区域),如图20所示:
notion image
图20
 
(4)RoI pooling
当我们将原图上的 RoI 映射到 feature map 上之后,我们可以应用 pooling。其实,这里也有一个问题:为什么要用 RoI pooling?
因为在 RoI pooling 层之后,有固定尺寸的全连接层(Fully Connected Layer)。由于成百上千的 RoI 有不同的尺寸,因而需要将它们 pooling 到相同的尺寸,例如:我们前面已经规定输出尺寸为:3x3x512。
我们刚刚计算了量化后的 RoI,尺寸=4x6x512,其中,512是通道数量。那么,为了进行 pooling 操作,我们需要将 4 与 6 均除以 3。然而,这里的 4 无法被 3 整除,因此,需要再次量化(说白了,就是去掉小数点)。
我们分别计算一下:4 / 3 ~= 1.33 , 6 / 3 = 2 , 向下取整后,得到 1 x 2 的向量表示。如图21所示:
notion image
图21
 
这时候,观察上图我们发现,量化之后,左图的最后一行数据就被丢弃了。(即:最后一行蓝色部分数据全部丢失了)如图22所示:
notion image
图22
 
【注意:同样的操作会作用到原始图片上的每个RoI,因此,最后会输出成百上千个 3x3x512 的矩阵】
整个 RoI pooling 层的输出如图23所示:
notion image
图23
每一个 RoI matrix 都会被输入进 FC 层,然后,模型会分别生成 bbox 和 calss。
但是,在这其中,每个输出均会丢弃上述所说位置的数据,进而影响整个模型分类和定位的准确性,解决方式就是引入了 RoI Align。

🤗 总结归纳

本文先介绍了 RoI Align 相关背景知识,然后引出 RoI Align 的计算方法,接着将 RoI Align 与 RoI Pooling 进行比较以判断两者的优劣,最后补充说明了 RoI pooling 的详细操作与缺陷。

📎 参考文章

 
💡
有关本部分知识的问题,欢迎您在底部评论区留言,一起交流~
 
深度学习与Pytorch学习双系统Ubuntu开机wifi图标消失问题
  • Giscus
  • Cusdis
  • Utterance
Naipings
Naipings
一个普通的大学生,分享自己学习的“有趣”知识
Announcement
type
status
date
slug
summary
tags
category
icon
password
🎉 感谢您的支持 🎉
-- 点击收藏不迷路 ---
👏欢迎更新体验👏