简介

Mask R-CNN是2017年发表的文章, 一作是何恺明, 该论文也获得了ICCV 2017年最佳论文奖。并且网络提出后,又霸榜了MS COCO的各项任务,包括目标检测、实例分割以及人体关键点检测任务。

image-20231117034359378

Mask R-CNN是在Faster R-CNN的基础上增加了一个用于预测目标分割Mask的分支(即可预测目标的Bounding Boxes信息、类别信息以及分割Mask信息)

image-20231117034835252

Mask R-CNN不仅能够同时进行目标检测与分割, 还能很容易扩展到其他任务, 比如预测人体关键点信息。

image-20231117035116897

Mask R-CNN的结构也很简单, 就是通过RoIAlign(在原Fast R-CNN中是RoIPool)得到RoI基础上并行添加一个Mask分支(小型的FCN), 见下图,之前Faster R-CNN是在RoI基础上接上一个Fast R-CNN检测头,即图中class, box分支, 现在又并行了一个Mask分支。

image-20231117034359378

注意带和不带FPN结构的Mask R-CNN在Mask分支上略有不同, 对于带有FPN结构的Mask R-CNN它的class, box分支和Mask分支并不是共用一个RoIAlign。在训练过程中, 对于class, box分支RoIAlign将RPN(Region Proposal Network)得到的Proposals池化到7x7大小, 对于Mask分支RoIAlign将Proposals池化到14×14大小。

image-20231117061321377

RoI Align

在之前的Faster RCNN中, 会使用RoIPool将RPN得到的Proposal池化到相同大小, 这个过程会涉及到quantization或者说取整操作, 这会导致定位不是那么准确(文中称为misalignment问题)

下面的示意图就是RoIPool的执行过程, 其中会经历两次quantization, 假设通过RPN得到了一个Proposal, 它在原图上的左上角坐标是(10, 10), 右下角的坐标是(124, 124), 对于要映射的特征层相对原图的步距为32, 通过 RoIPool期望输出为2×2大小。

  • 将Proposal映射到特征层上, 对于左上角坐标10/32四舍五入后等于0, 对于右下角坐标124/32四舍五入后等于4, 即映射在特征层上的左上角坐标为(0, 0)右下角坐标为(4, 4)。对应下图特征层上从第0行到第4行, 从第0列到第4列的区域(黑色矩形框), 这是第一次quantization。
  • 对于期望输出的2×2大小,所以需要经映射在特征层上的Proposal划分成2x2大小区域, 但现在映射在特征层上的Proposal是5×5大小, 无法均分, 所以强行划分后有的区域大有的区域小, 如下图所以,这是第二次quantization。
  • 对划分后的每个子区域进行maxpool即可得到RoIPool的输出, 即下图中蓝色对应的四个数字。

image-20231117065102092

为解决这个问题, 作者提出了RoIAlign方法代替RoIPool, 以获得更加精细的空间定位信息。

作者提到将RoI替换成RoIAlign后,分割的Mask准确率相对提升了10%到50%, 并且将预测Mask和class进行了解耦, 解耦后也带来了很大的提升。

image-20231117071100480

下图就是RoIAlign的执行过程,同样假设通过RPN得到了一个Proposal, 它在原图上的左上角坐标是(10, 10), 右下角的坐标是(124, 124), 对应要映射的特征层相对原图的步距是32, 通过RoIAlign期望的输出为2×2大小。

将Proposal映射到特征层上, 左上角作为(0.3125, 0.3125)(不进行四舍五入), 右下角坐标为(3.875, 3.875)(不进行四舍五入)。为了方便理解, 将特征层上的每个元素都用一个点表示, 就能得到图中下方的gri网格, 图中蓝色的框就是Proposal。

由于期望输出大小为2x2, 故将Porposal划分成2×2四个子区域,接着根据sampling_ratio在每个子区域中设置采样点, 原论文中默认设置的sampling_ratio为4, 这里为了方便讲解, 将sampling_ratio设置为1.

然后计算每个子区域中每个采样点的值(利用双线性插值计算), 最后对每个区域内的所有采样点取均值即为该子区域的输出。

image-20231117073133360

以第一个子区域为例, 这里将sample_ratio设置为1, 所以每个子区域只需设置一个采样点, 第一个子区域的采样点为图中黄色的点(即该子区域的中心点), 坐标为(1.203, 1.203),然后找到离该采样点最近的四个点(即图中用红色箭头标出的四个黑点),然后利用双线性插值即可计算得到采样点对应的输出-0.8546, 又由于该子区域只有一个采样点, 故该子区域的输出就为-0.8546。

image-20231117075332516

Mask Branch(FCN)

对于带有FPN和不带有FPN的Mask R-CNN, 它们的Mask分支不太一样, 下图是左边不带有FPN结构的Mask分支, 右侧是带有FPN结构的Mask分支(灰色部分为原Faster R-CNN预测的box, class信息的分支,白色部分为Mask分支)

image-20231117061321377

下图为带有FPN的Mask分支结构示意图。

Mask_r-cnn_fpn

之前的FCN中提到过, FCN是对每一个像素对每个类别都会预测一个分数, 然后通过softmax得到每个类别的概率, 哪个概率高就将该像素分配给哪个类别, 但在Mask R-CNN中, 作者将预测Mask和class进行了解耦, 即对输入的RoI针对每个类别单独预测一个Mask, 最终根据box, cls分支预测的classes信息来选择对应类别的Mask。解耦后得到很大的提升, 下表是原论文中给出的消融实验结果,其中softmax代表原FCN方式, sigmoid代表Mask R-CNN采取的方式(Mask和class进行了解耦)。

image-20231117081349378

在训练网络的时候输入Mask分支的目标是由RPN提供的, 即Proposals, 但在预测的时候输入Mask分支的目标是由Fast R-CNN提供的(即预测的最终目标)。并且训练时采用的是Proposals全部是Fast R-CNN阶段匹配到的正样本。在训练时Mask利用RPN提供的目标信息能够扩充训练样本的多样性(因为RPN提供的目标边界框并不是很准确, 一个目标可以呈现出不同的情景,类似于围着目标做随机裁剪。从另一个方面来看, 通过Fast R-CNN得到的输出一般都比较准确了, 再通过NMS后剩下的目标就更少了)。在预测时为了获得更加准确的目标分割信息以及减少计算量(通过Fast R-CNN后的目标数会更少), 此时利用的是Fast R-CNN提供的目标信息。

Mask R-CNN损失

Mask R-CNN损失就是在Faster R-CNN的基础上加了Mask分支上的损失, 即:

关于mask分支上的损失就是二值交叉熵损失(Binary Cross Entropy)

Maskf分支损失

在理解Mask分支损失计算之前, 要弄清楚logist(网络预测的输出)是什么, targets(对应的GT)是什么。前面有提到训练时输入Mask分支的目标是RPN提供的Proposals, 所以网络预测的logits是针对每个Proposal对应每个类别的Mask信息(注意预测的mask大小都是28×28)。并且这里输入的Proposals都是正样本(在Fast R-CNN阶段采样得到的), 对应的GT信息(box, cls)也是知道的。

如下图所示, 假设通过RPN得到了一个Proposal(图中黑色的矩形框), 通过RoIAlign后得到对应的特征信息(shape为14×14×c)。接着通过Mask Branch预测每个类别的Mask信息得到图中的logits(logits通过sigmoid激活函数后, 所有的值都被映射到0和1之间)。通过Fast R-CNN分支正负样本匹配过程我们能够知道该Proposal的GT类别为猫(cat), 所以将logits中对应类别猫的预测mask(shape为28×28)提取出来。然后根据Proposal在原图对应的GT上裁剪并缩放到28×28大小,得到图中的GT mask(对应目标区域为1, 背景区域为0),最后计算logits中预测类别为猫的mask与GT amsk的BCELoss(BinaryCrossEntropyLoss)即可。

Mask_r-cnn_1

Mask Branch预测使用

在真正预测推理的时候, 输入Mask分支的目标是由Fast R-CNN分支提供的。

Mask_r-cnn_1_1

如上图所示, 通过Fast R-CNN分支, 我们能够得到最终的预测目标框架框信息以及类别信息。接着将目标边界框信息提供给Mask分支就能预测得到该目标的logits信息。再根据Fast R-CNN分支提供的类别信息将logits对应类别的Mask信息提取出来,即针对该目标预测的Mask信息(shape为28x28, 由于通过sigmoid激活函数, 数值在0都1之间), 然后利用双线性插值将Mask缩放到预测目标框大小, 并放到原图对应区域。接着通过设置的阈值(默认为0.5)将mask转换成一张二值图,比如预测值大于0.5的区域设置为前景剩下区域设置为背景。现在对预测的每个目标就可以在原图中绘制出边界框信息, 类别信息以及目标Mask信息。

image-20231117174543776