前言
- 目标检测(object detection)是识别目标属于哪个类别并用边界框对每个目标进行定位,也就是把它们“框”起来。如下图(b)所示。
- 语义分割(semantic segmentation)是对每个像素进行分类,而不考虑目标实例。如下图(c)所示。
-
实例分割(instance segmentation)需要先将目标正确地检测出来,然后对每个目标进行精细地分割。如下图(d)所示。它和语义分割的区别是,语义分割是逐像素分类,而实例分割需要在语义分割的基础上对属于不同的类别的目标进行更精细的分割。因此实例分割可以看成是目标检测和语义分割的结合。
本文提出的Mask R-CNN是一种实例分割方法,它是在Faster R-CNN的基础上扩展的。它向Faster R-CNN中添加了一个为每个RoI(region of interest)预测分割mask的分支,这个分支与原有的分类分支和边界框回归分支是并行的。这个mask分支是一个小型的FCN,并且计算开支很小。
在Faster R-CNN中,网络的输入和输出之间并不是按照像素一一对应的,RoI Pooling层采用的是粗略的空间量化来提取特征。这对bbox(bounding-box,边界框)的影响不是很大,但对mask的精度有很大影响。因此本文引入RoIAlign层代替RoI Pooling层,RoIAlign层没有用量化,它保留了确切的空间位置。使用RoIAlign后将mask的精度从10%提升到50%。
在Mask R-CNN中,mask和类别的预测是分开的,mask分支只做语义分割,而类别预测由另一个分类分支来完成。每个类别都有一个单独的二值mask,这样类别之间不会存在竞争,同时依赖于分类分支预测的类别标签。这与FCN是不同的,在FCN中,预测mask的同时还要预测mask所属的类别。
Mask R-CNN的具体设计
首先对Faster R-CNN做一个简单的回顾。Faster R-CNN包括两个阶段,第一个阶段称为RPN,用来生成候选bbox;第二个阶段本质上是Fast R-CNN,用RoI Pooling层从每个候选bbox中提取特征,然后进行分类与bbox回归。两个阶段的特征是共享的。Mask R-CNN就是在Faster R-CNN的基础上添加了第三个mask分支,这个分支需要更精细的特征。
Mask R-CNN同样也是two-stage,第一个阶段也是RPN,第二个阶段在分类和回归的同时,为每个RoI输出一个二值mask。在另外一些分割方法中,是在预测mask之后再进行分类的,而Mask R-CNN中预测mask和分类是同时进行的。
1. mask的表示形式
一个mask是对一个目标的空间布局(spatial layout)的编码。类别标签或者bbox偏移值是通过全连接层得到的,最终呈现形式是一个短的输出向量。而mask的空间结构需要被像素一一对应的卷积层进行处理,这就是Mask R-CNN中引入的RoIAlign层。
具体来说,用FCN为每个RoI预测一个m × m的mask,这使mask分支中的每一层都可以保持m × m的空间布局。与用全连接层预测mask的方法不同,用全卷积表示mask需要更少的参数。
2. RoIAlign
在Faster R-CNN中,RoI Pooling层之前共有两次量化操作,如下图:
- 输入图像——特征图。可以看到,输入图像大小为800×800,其中狗狗对应的RoI是665×665。在上图所示的VGG16中,有5个池化层,每个池化层的池化单元都是2,因此最终得到的特征图大小为800/32 × 800/32 = 25×25,是整数;而狗狗对应的RoI经过池化操作后的大小为665/32 × 665/32 = 20.78×20.78,是浮点数。这里进行第一次量化操作,将结果变为20×20,引入第一次量化误差。
- 特征图——RoI feature。最终RoI Pooling层将每个大小不同的RoI都转换为固定的7×7的RoI feature,因此需要将20×20的RoI转换为7×7的RoI feature,即20/7 ×20/7 = 2.86×2.86,还是浮点数。因此进行第二次量化操作,对2.86取整为2,把原来的20变为7的倍数,才能得到最终的7×7的RoI feature。这里引入了第二次量化误差。
这些量化操作会造成RoI和经过RoI Pooling层提取的RoI feature之间的偏差,也就是说,如果将RoI feature对应到原始输入图像上,并不能和图像上的RoI对应起来。这可能对目标分类的影响很小,但对预测精确到像素的mask来说影响是很大的。
为了解决这个偏差问题,本文提出了RoIAlign层,它移除了RoI Pooling层中的所有量化操作,可以很好的将RoI feature与输入图像中的像素对齐,如下图所示:
图中蓝色虚线框表示特征图,黑色实线框表示RoI feature,最后需要输出的大小为2×2。在RoIAlign中,保留浮点数,比如665/32=20.78,就用20.78,而不是用20来代替它,用双线性插值(bilinear interpolation)来处理这些浮点数。具体来说就是,用每个RoI bin中的四个真实存在的像素值来共同确定RoI feature中一个虚拟坐标点所对应的像素值,由此可以将这个20.78×20.78所对应的特征图输出出来。如上图,蓝色的点是虚拟坐标点,橘色的区域是RoI bin,计算时就是用双线性插值估计蓝点对应的像素值,然后在每个RoI bin里面进行max pooling或average pooling操作,以得到最终2×2的输出结果。
3. 损失函数
在每个RoI上定义一个多任务损失函数:
其中和和Fast R-CNN中的一样,这里重点说一下。对于每个RoI,mask分支有维的输出,其中是mask的大小,是类别个数,因为每个类别对应一个mask,因此输出的维度是。定义为平均二值交叉熵损失函数(average binary cross-entropy loss)。计算过程是这样的,mask分支为每个RoI输出一个通道数为的mask,其中每个通道的mask对应一个类别,共有个类别。然后用sigmoid函数进行二分类,判断mask是否是这个类别。然后在计算loss的时候,假如RoI对应的ground-truth的类别是,则计算第个mask对应的loss,其它mask对这个loss没有贡献。
选择哪个mask作为最终的输出呢?论文中说是依赖分类分支预测的类别标签来选择输出的mask。这就将mask预测和类别预测分离开来。与FCN不同的是,在FCN中是per-pixel softmax,并且mask中存在类别竞争;而在Mask R-CNN中是per-pixel sigmoid,并且允许网络为每个类生成一个mask,因此类别之间不存在竞争。
Mask R-CNN的网络结构
文中提出了两种MaskR-CNN架构,如上图所示,一种是Faster R-CNN/ResNet,另一种是Faster R-CNN/FPN。图中上半部分灰色的部分是原始的网络,下面的部分是添加的mask分支网络。接下来介绍一下这两种结构。
上图左边的结构的主网络是ResNet-50,是从ResNet第四阶段的最后一个卷积层的输出中提取特征,又被称为ResNet-50-C4。输入的RoI首先获得7×7×1024的RoI feature,然后经过res5(这里res5经过修改,使得能够以步长为1在7×7的RoI上进行操作,原始的卷积层是14×14,步长为2)将通道上升到2048,然后经过分类和bbox回归两个分支。mask分支利用反卷积来提升分辨率,同时减少通道的个数,变成14×14×256,最后输出的是14×14×80的mask。
上图右边的结构的主网络是FPN,由于FPN中已经包括了res5,因此效率更高并且需要用到的filter更少。在mask分支中首先将RoI变为14×14×256的RoI feature,然后经过4个连续的卷积(图中的×4),也就是进行了5次相同的操作,最后输出28×28×80的mask。实验证明用FPN作为主网络会获得更高的精度和速度。
训练
在Fast R-CNN中,当RoI与一个ground-truth box的IoU至少为0.5时,这个RoI就是正样本,否则就是负样本。只定义在正样本上。输出的mask是RoI与其对应的ground-truth mask之间的交集。
在训练时,图像的大小被变换为800像素,每个GPU的每个mini-batch中有两个图像,每个图像有N个RoI,其中正负样本比为1:3。如果以ResNet-50-C4作为主网络,N为64;如果以FPN作为主网络,N为512。在8个GPU上进行训练,共进行160k次迭代,初始学习率为0.02,在第120k次迭代时上升到10。
测试
在测试时,ResNet-50-C4主网络有300个RoI,FPN主网络有1000个RoI,bbox回归分支对这些RoI进行NMS操作,然后mask分支对其中得分最高的100个RoI进行操作。虽然这与训练时三个分支的并行操作不同,但仍然加快了测试速度并且提升了精度,这是由于使用了更少但是更精确的RoI。mask分支为每个RoI预测K个mask,但只用其中的第k个mask,k就是分类分支预测的那个类别。
对于目标检测的结果
上表是Mask R-CNN执行目标检测的结果与其他目标检测方法的对比。在训练时是训练了一整个Mask R-CNN,但在测试时只用了分类分支和bbox回归分支的输出结果,mask分支的输出结果被忽略了。可以看到,Mask R-CNN比其他所有目标检测的方法的性能都要好。
为了进一步对比,训练了一个没有mask分支的Mask R-CNN,也就是Faster R-CNN+RoIAlign,即用RoIAlign层代替Faster R-CNN中的RoI Pooling层。如上表的第5行所示。可以看到,检测性能比原始Faster R-CNN要好,但是比Mask R-CNN还是低了0.9个点。作者将Mask R-CNN的提升归因为多任务训练,由于加入了mask分支,改变了loss,间接影响主干网络的效果。
参考
https://blog.csdn.net/WZZ18191171661/article/details/79453780