前言
- 目标检测(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的输出结果。