文章目录
- ROI Pooling和ROI Align:
- 一篇好的文章
- ROI Pooling 如何计算?
- AdaptiveMaxPool2d 在做啥
- Fast RCNN或者Faster RCNN中都使用了ROI Pooling
- ROI Align
ROI Pooling和ROI Align:
(1)ROI Pooling 是为了让特征图输出等尺寸大小的特征图而发明的粗暴Pooling 方法,在Pooling 过程中取整数个数像素点进行操作,导致在Mask RCNN实例分割的时候效果不好,所以凯明大神在Mask RCNN中提出ROI Align。
(2)ROI Align 采用双线性插值方式,获取原特征图中一个插值的像素结果。
(3)Faster-RCNN 中使用ROI Pooling ,存在2次取整量化 操作,一是SS的bbox是原理里的,射影到特征图的时候取整量化;二是做了如同AdaptiveMaxPool2d 的ROI Pooling 的时候。2次取整量化 导致在原图中像素差距很大,这样小目标将受到极大影响。Mask RCNN作者把它总结为”不匹配问题(misalignment)。
一篇好的文章
https://zhuanlan.zhihu.com/p/73113289
ROI Pooling 如何计算?
pytorch也有实现:https://pytorch.org/vision/main/generated/torchvision.ops.RoIPool.html
下面程序截取了Fast RCNN中的代码:
import numpy as np
import torch
from torch import nn
class SlowROIPool(nn.Module):
def __init__(self, output_size):
super().__init__()
self.maxpool = nn.AdaptiveMaxPool2d(output_size)
self.size = output_size
def forward(self, images, rois, roi_idx):
"""
:param images: shape is (n, C, H, W,)
:param rois: exam [[0.00078125, 0.00138889, 0.39140624, 0.6958333 ]]
:param roi_idx: [0]
:return:
"""
n = rois.shape[0]
h = images.size(2)
w = images.size(3)
x1 = rois[:, 0]
y1 = rois[:, 1]
x2 = rois[:, 2]
y2 = rois[:, 3]
x1 = np.floor(x1 * w).astype(int)
x2 = np.ceil(x2 * w).astype(int)
y1 = np.floor(y1 * h).astype(int)
y2 = np.ceil(y2 * h).astype(int)
res = []
for i in range(n):
img = images[roi_idx[i]].unsqueeze(0)
img = img[:, :, y1[i]:y2[i], x1[i]:x2[i]]
img = self.maxpool(img)
res.append(img)
res = torch.cat(res, dim=0)
return res
roipool = SlowROIPool(output_size=(7, 7))
print(roipool(images=torch.Tensor(np.random.randn(2, 3, 720, 1280)),
rois=np.asarray([[0.00078125, 0.00138889, 0.39140624, 0.6958333],
[0.00078125, 0.00138889, 0.39140624, 0.6958333]]),
roi_idx=[0, 1]).size())
输出 torch.Size([2, 3, 7, 7])。 # n C H W
程序中定义了ROI Pooling层,输出固定7*7的宽高特征图。
重点是AdaptiveMaxPool2d 。
AdaptiveMaxPool2d 在做啥
举例输入:
想输出2*2固定尺寸:
除了最大池化,还有平均池化。
有趣的是,原特征图宽高(10,10),想要输出(20,20),AdaptiveMaxPool2d 也可以,是一种映射查找。
; Fast RCNN或者Faster RCNN中都使用了ROI Pooling
Fast RCNN或者Faster RCNN中都使用了ROI Pooling,如下是Fast RCNN的过程:
回顾Fast RCNN或者Faster RCNN:
(1)Fast RCNN采用Selective Search 方法生成1K~2K个候选区域,
Faster RCNN采用RPN 方法生成1K~2K个候选区域。
(2)两者都只需要做一次特征提取,bbox做projection映射提取特征图中的对应子特征图(ConV feature map),然后将子特征图用ROI Pooling形成 固定大小输出,再然后经过FC网络去做分类和回归。
(3)RCNN中是Selective Search 方法出来的每个区域,都从原图中crop出区域,然后直接resize后给入VGG网络提取特征。
ROI Align
利用双线性插值就能取到想要的”浮点数像素点坐标位置”的对应值,就能正常pooling操作。
很好的一个视频:https://www.bilibili.com/video/BV1ZY411774T?spm_id_from=333.999.0.0
下图表示:
(1)原理图和特征图比例是32,原图里bbox左上角是[10 10],右下角是[124 124] ;
(2)ROI Pooling 就会两次取整,第一次算bbox映射是[0 0 ],[3 3],第二次是做AdaptiveMaxPool2d,如果是奇数就会遇到不均分取整;
(3)ROI Align 在下图中,第一次求bbox映射是[0.3125 0.3125 ],[3.875 3.875],不会取整。 对应到特征图后,如果想要2 _2的特征图输出,直接把[0.3125 0.3125 ],[3.875 3.875]这个对应框直接均分,不会取整。
(4)ROI Align 在下图中,对于想要2_2的特征图输出,每一块输出数值取决于sampling ratio的数值。比如在下图中取sampling ratio=1,也就是只用取一个点,这个点的数值是利用双线性插值由它最近的四个像素点共同决定得到的。原Mask RCNN是sampling ratio=2,也就是取4个点,但作者也说采样位置和采样数量对于结果并不是由很大影响。
(5)双线性插值如何计算:
(6)原论文的 ROI Align是取sampling ratio=2,也就是4个采样点,每个采样点数值都是靠双线性插值计算得到:
参考:
https://blog.csdn.net/x1131230123/article/details/123660382
https://zhuanlan.zhihu.com/p/73138740
https://github.com/gary1346aa/Fast-RCNN-Object-Detection-Pytorch/blob/master/README.ipynb
https://www.bilibili.com/video/BV1ZY411774T?spm_id_from=333.999.0.0
https://arxiv.org/pdf/1703.06870.pdf
Original: https://blog.csdn.net/x1131230123/article/details/124196093
Author: XD742971636
Title: 【深度学习】ROI Pooling 和 ROI Align 计算机视觉 目标检测
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/682447/
转载文章受原作者版权保护。转载请注明原作者出处!