- 论文链接: https://arxiv.org/pdf/1703.06870.pdf
- 论文题目:Mask R-CNN
Mask R-CNN
Abstract
我们提出一种概念上简单、灵活且普世的对于实例对象分割的框架。我们的方法能够有效地检测一张图像里的物体,并且同时对于每个实例都能生成一个高质量的实例mask。这个方法叫做Mask R-CNN,是在Faster R-CNN的基础上通过增加一个与已有的边框识别分支并行的一个用来预测物体mask的分支来实现的。Mask R-CNN训练简单,相比于Faster R-CNN只增加了很小的开销,依然能跑在5fps。而且,Mask R-CNN很容易被泛化到别的任务上去,如允许我们在同样的框架下预测人体动作。基于这个模型,我们已经在COCO系列挑战的三个分支上都取得了顶尖的结果,包括实例分割,边框物体检测,和人体关键点检测。没有使用什么tricks,Mask R-CNN已经在每个任务上超过了现存的所有单一模型,包括COCO 2016挑战的冠军模型。我们希望我们这一简单有效的方法能够作为一个基线,帮助未来关于实例识别的研究。
1. Introduction
在机器视觉领域,目标检测和语义分割任务在很短的时间内得到了很大的提高。其中大部分都得益于强大的基准系统,比如分别用于目标检测的Fast/Faster
R-CNN框架和用于语义分割的全卷积网络FCN框架。这些方法在概念上都很直观,符合直觉,还具有一定的灵活性和鲁棒性,同时在训练和infer的时候都很快。本文的目标是开发一种能够与之匹敌的用于实例分割的框架。
实例分割任务是非常具有挑战性的,因为它需要正确地检测一张图中所有的物体,同时还要精准地分割每个实例。也就是经典的计算机视觉任务目标检测和语义分割的结合。目标检测的目标是对于图像中每个单独的物体使用一个bounding box去定位它,并同时对它进行分类。语义分割的目标是将图像的每个pixel分类到已经固定的类别中,但是它并不区分每个实例。有了这样的定义,肯定有人会想到用一个非常复杂的方法来完成这个人物。然而,我们开发出了一种非常简单,灵活且快速的系统,同时还在实例分割任务上超过了目前最好的结果。
我们的方法叫做Mask R-CNN,是在Faster R-CNN的基础上通过增加一个在每个RoI上预测语义分割mask的branch来实现的,这个分支是与分类和回归branch并行的,如图1。mask branch是对每个RoI跑一个小的FCN网络来完成像素到像素的分割任务。Mask R-CNN在已有的Faster R-CNN框架下是很容易实现的。并且mask分支只增加了很小的计算量,对整体速度几乎没有影响。
图1. 用于实例分割的Mask R-CNN框架
原则上,Mask R-CNN是一个符合直觉的对于Faster R-CNN的一个扩展,但是只有正确的构建这个分支才会取得好的结果。Faster R-CNN框架的设计并没有保证输入与输出在像素级上的对齐。这一点在RoIPool中得到体现,在对实例进行操作时,这一粗糙的空间量化提取特征的方法引起的非对齐带来的影响就很明显了。为了弥补非对齐,我们提出一种简单的,无量化的层,叫做RoIAlign,这就能够确保准确的空间位置。尽管只是在RoIPool的基础上做了很小的修改,但是RoIAlign确实取得了很好的结果:它将mask的准确率相对提高了10%~50%。还有,我们发现有必要将mask和类别预测解耦合:我们对于每个类别单独进行一个二分类,并不让它们进行类间竞争,然后依赖网络的分类分支来进行分类预测。但是,一般来说,FCNs是对每个像素进行多类别分类的,是将分割任务和分类任务结合起来的,但是在我们的结构中实验下来结果并不好。
2. Related Work
R-CNN: R-CNN是在给出可以操作数量的预测框的基础上,对每个RoI单独送入网络进行评估。后来加入RoIPool实现了网络共享,提高了速度和准确率。Faster R-CNN在此基础上加入了学习注意力机制的RPN来进一步优化提升整个流程。
Instance Segmentation: 由于R-CNN的有效性,很多实例分割的方法都基于segment proposals。DeepMask以及后续的一些方法是先学习segment的候选,然后再经过Fast R-CNN进行分类。那么这些方法,分割任务是先于分类的,这就是使得速度慢且准确率低。相似地,Dai等人提出了一种复杂的多阶段的串联的结构,从bbox候选框里来预测segment,然后再分类。不同的是,我们的方法是一种平行结构,将mask的预测和分类分开,这就更加简单简单且灵活。
最近还有一种叫做 ‘‘fully convolutional instance segmentation’’ (FCIS)的方法,核心思想是通过全卷积的方式来预测一系列对于位置敏感的输出通道。这些通道同时进行物体分类,预测bbox,预测mask,这使得整个系统很快。但是FCIS在重叠实例上展现出了系统误差,会生成错误的边界。
另一类解决对于实例分割的方法是来自于语义分割的成功。从对于每个像素的分类结果(如FCN的输出)出发,这类方法企图去将同类的像素分割开来到不同的实例中。与这类以segmentation优先的策略方法相反的是,Mask R-CNN是基于instance优先的策略。
3. Mask R-CNN
Mask R-CNN在理论上是很简单的:Faster R-CNN对于每个候选物体会有两个输出,一个是分类的标签,一个是bbox的offset;在这个基础上我们增加第三个分支来输出目标的mask。Mask R-CNN的思想上很直观且自然的,但是mask的分支是独立于分类和box输出的,所以需要提取更加精细的空间信息。
Faster R-CNN: Faster R-CNN由两个阶段组成。第一阶段,RPN(Region Proposal Network)生成候选的bbox。第二阶段,也就是Fast R-CNN的精髓部分,使用RoIPool从每个候选框中提取特征,然后执行分类和bbox回归。两个阶段所使用的特征是共享的。
Mask R-CNN: Mask R-CNN采取同样的两阶段,并且第一个阶段是完全一样的RPN。在第二阶段,平行于分类和bbox回归,我们增加一个分支用来对每个ROI输出一个二分类mask,这个跟大多数现有的系统是相反的,它们是根据mask来完成分类的。我们的方法是继承了Fast R-CNN的结构,采用的平行结构。
在训练的时候,我们对于每个采样出的RoI定义了一个多任务的loss
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. 。那么分类和bbox的loss请参考前面的文章,而mask分支对于每个RoI会输出一个
K
m
2
Km^2
Km2维的向量,它编码了
K
K
K个分辨率为
m
×
m
m \times m
m×m 的二分类mask,每个都表征了K个类中的一个类。因此,我们对每个像素执行sigmoid,然后将
L
m
a
s
k
L_{mask}
Lmask定义为平均二分交叉熵loss。对于gt为
k
k
k的RoI,
L
m
a
s
k
L_{mask}
Lmask仅仅被定义在第
k
k
k个mask上(也就是其他类的mask输出并不计算loss)。
我们的
L
m
a
s
k
L_{mask}
Lmask的定义允许了网络对于每个类生成mask且没有类间的竞争。我们依靠专注于分类的分支来预测分类label,进而选择相应的输出mask。这是的mask和分类是解耦合的。这不同于普遍的采用FCNs来进行语义分割的做法,它们典型地是对每个像素执行softmax,然后进行一个多项式交叉熵loss。这样的方法就引入了类间的竞争。但是实验表明,我们的方法是好的实例分割结构的关键。
Mask Representation: 一个mask编码了一个输入物体的空间分布。因此,不像类标签和框补偿会在通过fc层时不可避免地折叠层低维的输出向量,提取空间结构的mask自然地是只能使用conv来保存像素间的关联的。
因此,对于每个RoI我们使用一个FCN来预测一个
m
×
m
m\times m
m×m的mask。这就使得在mask分支上的每一层都能明确地保存
m
×
m
m \times m
m×m的物体空间结构,而不被折叠为向量从而丢失空间维度信息。
这个像素级的行为就要求我们的RoI特征(本身是很小的特征图,因为经过了backbone的卷积)能够很好的对齐以保存每个像素的对应关系。接下来就要介绍在mask预测中起到关键作用的
R
o
I
A
l
i
g
n
RoIAlign
RoIAlign。
RoIAlign: RoIPool是一个标准的从每个RoI提出一个小特征图(如
7
×
7
7 \times 7
7×7)的操作。RoIPool,首先将float型的RoI量化成一个离散型粒度的特征图(也就是取整),然后这个经过量化的RoI再细分进一个空间bins里,最后将每个bin覆盖的特征图的值聚合(一般是采用max池化)。量化的过程如下举例说明:在连续坐标
x
x
x上计算
[
x
/
16
]
[x/16]
[x/16],这里16代表特征图的stride,然后
[
⋅
]
[\cdot]
[⋅]代表取整;那么同样的,在RoIPool中量化也是一样(如
7
×
7
7\times 7
7×7)(量化本质上是两步,第一步是proposal从原图到特征图的量化,原图上比如
300
×
200
300 \times 200
300×200的proposal,到特征图上除以stride,假设是16,那么就变成
18.75
×
12.5
18.75\times 12.5
18.75×12.5,这个时候RoIPool就会直接取整,第二次量化是取bins的时候,之前的
18
×
12
18\times 12
18×12再分别除以7又会是分数)。这样的量化会引入非对齐,使得提取出的特征并不准确。但是这并不会影响到分类,因为分类任务对于小的差别是鲁棒的。但是对于需要精准预测mask的分支来说就会有很大的负作用。
为了解决这个问题,我们引入RoIAlign层根据对齐输入来提取特征,这就移除了RoIPool的粗糙的量化。我们引入的变化很简单:我们避免了任何的量化,不管是RoI边界问题还是取bins的时候(使用
x
/
16
x/16
x/16 而不是
[
x
/
16
]
[x/16]
[x/16])。我们使用双线性插值来计算输入特征在每个RoI bin的四个采样点上的准确值,然后再进行聚合(使用max或者average),看图3获得更多细节上的信息。我们发现结果对于具体采样的位置没有特别敏感,只要不引入量化就行。
图3. RoIAlign:图中虚线网格代表了一张特征图,实线所画的是一个RoI(在这个例子里,是2x2的bins),每个bin里面的点代表了4个采样点(关于这个采样点,需要做一个说明,本身bins是2x2,也就是最后我们RoIAlign出来的特征图是2x2,然后每个bin里的2x2的点,代表的是采样点,这是一个超参数,可以使用1x1,也就是每个bin的中心,如果2x2,就是将bin平均分为4块,然后取每块的中心为采样,实验结果显示使用4个采样点效果最佳,最后再对这个4个采样点进行最大值池化)。对每个采样点,RoIAlign通过双线性插值来从该采样点临近的4个特征图网格点中计算得到该采样点的特征值。这样在这一过程中就不会引入任何的量化。
RoIAlign在实验中取得了非常好的效果,同时我们还比较了RoIWarp,但是RoIWarp忽略了对齐问题,即使它采用了双线性插值,效果也不如RoIAlign。
Network Architecture: 为了阐述我们方法的一般性,我们将Mask R-CNN实现在了多种结构上。为了简明,我们进行下面几点区分:(i)用于对整张图进行特征提取的backbone,(ii)对每个RoI进行分类,回归和mask的head。
我们使用术语network-depth-features来代表backbone结构。我们评估ResNet和ResNeXt网络结构的50层和101层。带ResNet的Faster R-CNN的最初的实现是从第4个stage的最后一个卷积层来提取特征的,我们称为C4。这个带ResNet-50的backbone,我们就取名为ResNet-50-C4。
同时我们也探索了另一个更为有效的backbone叫做特征金字塔网络(FPN)。FPN使用了一个带有横向连接的自上而下的结构来构建一个网络内的从单一尺寸输入得到特征金字塔的一个结构。使用了FPN的Faster R-CNN根据格子的尺寸从金字塔中的不同level来提取特征,它后面的部分就和普通的ResNet一样了。使用ResNet-FPN backbone作为特征提取的Mask R-CNN在速度和准确率上都取得了很明显的提升。
对于网络head,我们只是添加了一个预测mask的分支。尤其,我们是从ResNet和FPN的papers来扩展我们的Faster R-CNN head的。详细情况请参考图4。ResNet-C4 backbone的head包括了ResNet的第5个stage(名为,9层的‘res5’),是计算量很大的地方。而FPN的backbone就已经将res5包括了,所以这就允许使用更为有效,轻便的head。
图4. Head 结构:我们扩展了两种现有的Faster R-CNN head。左/右分别展示了从ResNet-C4和FPN backbone来添加mask分支。数字代表特征图的分辨率以及通道数。箭头代表conv,或者deconv或者fc层(自行从特征图的大小变化来区别)。所有的conv都是
3
×
3
3\times 3
3×3,除了输出层的conv是
1
×
1
1\times1
1×1,deconv是stride为2的
2
×
2
2\times2
2×2,隐藏层我们都使用ReLU。左:‘res5’表示ResNet的第5个stage,为了简化我们进行了一些修改,这样第一个conv就直接操作在
7
×
7
7\times7
7×7的RoI上。右:‘
×
\times
× 4’表示了4次conv。