论文:Mask R-CNN(CVPR 2017)
代码:MengTianjian/MaskRCNN(pytorch)
\qquad\;
facebookresearch/maskrcnn-benchmark
语义分割和实例分割
- 实例分割:每个目标用不同颜色标识
- 语义分割:每类目标用不同颜色标识
以VOC2007中的数据为例,左边为语义分割,可以看到多张图片中“人”均用粉色标识;右边为实例分割,多个目标就用多种颜色标识。
![]() |
![]() |
Mask R-CNN总体架构
Mask R-CNN是实例分割(Instance segmentation)算法,算法架构基本是在FasterRCNN
【
1
】
^{【1】}
【1】的基础上增加了一个mask预测分支,所以附带检测、分类
![]() |
![]() |
由mask_rcnn.py也可以看到:FasterRCNN
【
1
】
^{【1】}
【1】中只有一个ROIHEAD(对应坐标、分类预测),而MaskRCNN则还有一个MaskHead(mask预测):
class MaskHead(nn.Module):
def __init__(self, config):
super(MaskHead, self).__init__()
self.config = config
self.num_classes = config.NUM_CLASSES
#self.crop_size = config.mask_crop_size
#self.roi_align = RoIAlign(self.crop_size, self.crop_size)
self.conv1 = nn.Conv2d(256, 256, kernel_size=3, padding=1, stride=1)
self.bn1 = nn.BatchNorm2d(256)
self.conv2 = nn.Conv2d(256, 256, kernel_size=3, padding=1, stride=1)
self.bn2 = nn.BatchNorm2d(256)
self.conv3 = nn.Conv2d(256, 256, kernel_size=3, padding=1, stride=1)
self.bn3 = nn.BatchNorm2d(256)
self.conv4 = nn.Conv2d(256, 256, kernel_size=3, padding=1, stride=1)
self.bn4 = nn.BatchNorm2d(256)
self.deconv = nn.ConvTranspose2d(256, 256, kernel_size=4, padding=1, stride=2, bias=False)
self.mask = nn.Conv2d(256, self.num_classes, kernel_size=1, padding=0, stride=1)
def forward(self, x, rpn_rois):
#x = self.roi_align(x, rpn_rois)
x = ROIAlign(x, rpn_rois, self.config, self.config.MASK_POOL_SIZE)
roi_number = x.size()[1]
# merge batch and roi number together
x = x.view(self.config.IMAGES_PER_GPU * roi_number,
256, self.config.MASK_POOL_SIZE,
self.config.MASK_POOL_SIZE)
x = F.relu(self.bn1(self.conv1(x)), inplace=True)
x = F.relu(self.bn2(self.conv2(x)), inplace=True)
x = F.relu(self.bn3(self.conv3(x)), inplace=True)
x = F.relu(self.bn4(self.conv4(x)), inplace=True)
x = self.deconv(x)
rcnn_mask_logits = self.mask(x)
rcnn_mask_logits = rcnn_mask_logits.view(self.config.IMAGES_PER_GPU,
roi_number,
self.config.NUM_CLASSES,
self.config.MASK_POOL_SIZE * 2,
self.config.MASK_POOL_SIZE * 2)
return rcnn_mask_logits
RoIAlign
FasterRCNN 中 ROI Pool最直接的目的就是统一尺寸,因为后面有全连接层需要固定特征尺寸,在整个向前传播的过程中含两次量化(边界坐标取整):
- 第一次在ROI Pool之前:根据RPN预测坐标(浮点数)划分感兴趣区域,然后映射(1//16)到特征图上作为ROI Pool的输入,边界坐标均取整
- 第二次就ROI Pool操作过程中:ROI Pool 将RoI划分成 k × k k\times k k×k 个bins,每个bin的边界坐标均取整
两次量化过程对实例分割这种像素级任务显然太过于粗糙,进而提出RoIAlign,边界坐标直接采用浮点数进行计算。
取其中的一个bin如下图所示:每个bin均匀取四个点代表该bin,用 双线性插值
【
2
】
^{【2】}
【2】得到四个点的特征值,取平均即该bin 的 pooling 值
实验
参考文献
【1】Faster R-CNN
【2】双线性插值
【3】Mask RCNN 算法笔记
【4】『计算机视觉』Mask-RCNN_训练网络其二:train网络结构&损失函数
【5】MASK_RCNN代码详解(4)-Losses部分
【6】ROI Align 代码解析
【7】ROI Align原理及cuda源码阅读