目录
- mask RCNN
- 1. Background
- 2. ROIAlign
- 3. Network Architecture
- 4. class-specific mask
mask RCNN
- 首先从introduction看起,mask RCNN是在Faster R-CNN的基础上添加了一个额外的分割分支(该分支和Faster RCNN的分类分支及回归分支并行运行)得到的。如下所示:
该分割分支采用FCN结构实现,作用于每一个ROI上。
这里的ROI是指经过RPN算法产生的候选框映射到特征图上的结果。
因此,有要点1:Mask RCNN是在Faster RCNN的基础上,添加了一个并行运行的分割分支实现的。
-
同时,Faster R-CNN应用了ROIpool层,以从不同大小的ROI得到固定大小的相应的feature maps,但是ROIpool引入了两次量化操作误差,从而无法实现像素级别的对齐。因此,mask RCNN采用了一个无量化层以取代ROIpool,也就是上图中的ROIAlign。
这里主要难理解的就是标红的地方。首先,什么是量化?量化,即一个将输入从一个大的值集(如实数)限制为离散的值集(如整数)的过程。
单对概念进行解释还是难以理解。建议阅读这篇Faster RCNN原理篇(二)——RoIPooling和RoIAlign的学习和理解,里面解释了ROIpool层的运行过程,以及为何会引入量化操作误差(即输入原图映射到特征图以及从特征图到全连接层时由于尺寸无法整除而出现的强行取整)。
量化操作误差导致了无法实现像素级别的对齐(misalignment),也就是经过ROIpool层被传送至分类和回归分支的ROI在对应到原图时会出现很大的误差,这其实很正常,因为卷积和池化操作会导致特征图上的一个点对应于原图的一个区域,但对于检测和分类来说,这又的确引入了误差。
因此,有要点2:为了解决这个问题,使得基于深度特征生成的ROI也能完美的对齐原图,提出了ROIAlign,来替代ROIpool层,这一改进使得分割的准确率提高了10%-50%。
-
最后,传统的FCN在预测分割mask的同时还预测了mask所属的种类。而作者认为,将分类和分割解耦合是至关重要的。因此,其在插入的FCN层上也进行了改进,这种改进也得益于Faster RCNN本身所具有的分类分支。
即,有要点3:新增的分割分支只做语义分割,而将分类任务交给Faster RCNN原本就有的分类分支。作者称其为class-specific mask。
基于上述改进,Mask RCNN在实例分割、目标检测上实现了SOTA的性能。除此之外,作者还提到mask rcnn是一个十分灵活的框架,可以通过增加不同的分支,来完成不同的任务,并报告了Mask RCNN在人体姿势识别竞赛中取得的成功。
接下来,将对这三个要点一一解析。
1. Background
目标检测→目标位置+目标类别(Faster RCNN=RPN+ROIpool+Fast RCNN)
语义分割→目标掩码(FCN)
实例分割→目标位置+目标类别+目标掩码(Mask RCNN=RPN+ROIAlign+Fast RCNN+FCN)
Mask RCNN的思路很简单:为了实现实例分割,因此其在Faster RCNN的基础上,添加了一个分割分支来输出目标掩码。但是考虑到分割分支和分类及检测分支存在不同,即分割需要更精细的空间信息(容易理解,比如说,目标是一只猫,如果存在位置上的轻微误差,算法仍然能够正确输出目标的类别,并且其位置预测仍然不受太大的影响)。因此,Mask RCNN在Faster RCNN的基础上,还进行了一项关键改进,以实现输入图像和特征图像素之间的对齐,也就是ROIAlign。
2. ROIAlign
参考这篇Faster RCNN原理篇(二)——RoIPooling和RoIAlign的学习和理解和笔记分享 : 一文读懂3个概念 : RoI, RoI pooling, RoI Align理解即可。其中,第二篇博文里面有详细的计算实例。
双线性插值参考:双线性插值(Bilinear Interpol)原理及应用。
有一个坑就是ROIAlign的反向传播,参照了这篇ROI-Align 原理理解,如下图所示:
要想理解这个过程,需要先理解池化层是怎么反向传播的,然后再理解ROIpool层的反向传播,然后再看这里。
3. Network Architecture
使用了不同的backbone:resnet-50,resnet-101,resnext-50,resnext-101,FPN。
其中,作者主要基于resnet-50和FPN设计了两种结构的mask RCNN,这两种结构都遵循前文的内容,只是实现细节有所不同,如下图所示:
ResNet-50-C4:ResNet-50的第四阶段的最终卷积层的输出被作为提取到的最终特征。
FPN:可以参考这篇FPN特征金字塔 完整详解 【论文笔记】和FPN(Feature Pyramid Networks)网络原理解析,原理挺好理解的,主要就是弄懂自顶向下过程中的几个关键点:深层特征图通过内插值等上采样方法恢复到和前一阶段特征图相同的高宽;前一阶段特征图通过1×1卷积使得其通道数和深层特征图经过上采样后的结果的通道数保持一致;为了避免混叠效应,在像素叠加后,应用了3×3卷积。
从上图中可以看到,使用ResNet-50-C4作为backbone提取到的特征,还需要再通过一层res5(resnet的第5阶段),才能被用于具体的network head。
而FPN已经包含了res5,因此其网络头部分不需要经过res5,因此作者认为FPN-mask RCNN的网络头部分具有更少的计算量,即更加高效,并且实验过程中证明了采用FPN作为backbone的Mask RCNN的精度也更高。
4. class-specific mask
由于Mask RCNN添加了一个分割分支,因此其损失函数也在Faster RCNN的基础上发生了一定变化,如下所示:
L = L c l s + L b o x + L m a s k L=L_{cls}+L_{box}+L{mask} L=Lcls+Lbox+Lmask
其中,分类损失 L c l s L_{cls} Lcls和 L b o x L_{box} Lbox的定义和Faster RCNN中的相同。
主要还是 L m a s k L_{mask} Lmask,作者并没有直接用原始FCN中的损失函数,而是进行了改进,这里也对应于要点3,即class-specific mask。
具体而言:
- 在分割分支中,对于每一个ROI,其输出为一个 K × M × M K\times M \times M K×M×M的矩阵。 K K K代表目标有 K K K个类别,并且每一个类别都会输出一个mask矩阵, M × M M\times M M×M则代表mask的大小。需要注意,每一个mask都为二值矩阵,也就是由0和1组成,每一个像素的具体值基于sigmoid二分类生成。
- 在训练阶段,假如某一个ROI的ground truth类别为 k k k,则 L m a s k L_{mask} Lmask为该ROI对应的输出中的第 k k k个 M × M M\times M M×M矩阵和ground truth的交叉熵损失,否则,假如该ROI不包含正样本,则不考虑 L m a s k L_{mask} Lmask。
- 而在推理阶段,假如分类分支预测某一个ROI的类别为 k k k,则只使用分割分支对该ROI预测的对应第 k k k个掩码作为输出。