Anchor-Based的目标检测算法我们已经讲了比较多了,另外Anchor-Free的目标检测我们也已经简单解读了一下DenseBox开了个头,而今天我们要来说说另外一个方向即实例分割。而实例分割首当其冲需要介绍的就是2017年He Kaiming大神的力作Mask-RCNN,其在进行目标检测的同时进行实例分割,取得了出色的效果,并获得了2016年COCO实例分割比赛的冠军。
Mask-RCNN是一个实例分割(Instance segmentation)框架,通过增加不同的分支可以完成目标分类,目标检测,语义分割,实例分割,人体姿态估计等多种任务。对于实例分割来讲,就是在Faster-RCNN的基础上(分类+回归分支)增加了一个分支用于语义分割,其抽象结构如Figure1所示:
稍微描述一下这个结构:
下图更清晰的展示了Mask-RCNN的整体框架,来自知乎用户vision
:
在Faster-RCNN中ROIPooling的过程如下图所示:
输入图片的大小为 800 × 800 800\times 800 800×800,其中狗这个目标框的大小为 665 × 665 665\times 665 665×665,经过VGG16网络之后获得的特征图尺寸为 800 / 32 × 800 / 32 = 25 × 25 800/32 \times 800/32=25\times 25 800/32×800/32=25×25,其中 32 32 32代表VGG16中的 5 5 5次下采样(步长为2)操作。同样,对于狗这个目标,我们将其对应到特征图上得到的结果是 665 / 32 × 665 / 32 = 20.78 × 20.78 = 20 × 20 665/32 \times 665/32=20.78\times 20.78=20\times 20 665/32×665/32=20.78×20.78=20×20,因为坐标要保留整数所以这里引入了第一个量化误差即舍弃了目标框在特征图上对应长宽的浮点数部分。
然后我们需要将这个 20 × 20 20\times 20 20×20的ROI区域映射为 7 × 7 7\times 7 7×7的ROI特征图,根据ROI Pooling的计算方式,其结果就是 20 / 7 × 20 / 7 = 2.86 × 2.86 20/7 \times 20/7=2.86\times 2.86 20/7×20/7=2.86×2.86,同样执行取整操作操作后ROI特征区域的尺寸为 2 × 2 2\times 2 2×2,这里引入了第二次量化误差。
从上面的分析可以看出,这两次量化误差会导致原始图像中的像素和特征图中的像素进行对应时出现偏差,例如上面将 2.86 2.86 2.86量化为 2 2 2的时候就引入了 0.86 0.86 0.86的偏差,这个偏差映射回原图就是 0.86 × 32 = 27.52 0.86\times 32=27.52 0.86×32=27.52,可以看到这个像素偏差是很大的。
为了缓解ROI Pooling量化误差过大的缺点,本论文提出了ROIAlign,ROIAligin没有使用量化操作,而是使用了双线性插值。它充分的利用原图中的虚拟像素值如 27.52 27.52 27.52四周的四个真实存在的像素值来共同决定目标图中的一个像素值,即可以将和 27.52 27.52 27.52类似的非整数坐标值像素对应的输出像素值估计出来。这一过程如下图所示:
其中feat. map就是VGG16或者其他Backbone网络获得的特征图,黑色实线表示的是ROI划分方式,最后输出的特征图大小为 2 × 2 2\times 2 2×2,然后就使用双线性插值的方式来估计这些蓝色点的像素值,最后得到输出,然后再在橘红色的区域中执行Pooling操作最后得到 2 × 2 2\times 2 2×2的输出特征图。可以看到,这个过程相比于ROI Pooling没有引入任何量化操作,即原图中的像素和特征图中的像素是完全对齐的,没有偏差,这不仅会提高检测的精度,同时也会有利于实例分割。
为了证明次网络的通用性,论文构造了多种不同结构的Mask R-CNN,具体为使用Backbone网络以及是否将用于边框识别和Mask预测的上层网络分别应用于每个ROI。对于Backbone网络,Mask R-CNN基本使用了之前提出的架构,同时添加了一个全卷积的Mask(掩膜)预测分支。Figure3展示了两种典型的Mask R-CNN网络结构,左边的是采用 R e s N e t ResNet ResNet或者 R e s N e X t ResNeXt ResNeXt做网络的backbone提取特征,右边的网络采用FPN网络做Backbone提取特征,这两个网络的介绍均在公众号的往期文章中可以找到,最终作者发现使用ResNet-FPN作为特征提取的backbone具有更高的精度和更快的运行速度,所以实际工作时大多采用右图的完全并行的mask/分类回归。
Mask分支针对每个ROI区域产生一个 K × m × m K\times m\times m K×m×m的输出特征图,即 K K K个 m × m m\times m m×m的二值掩膜图像,其中 K K K代表目标种类数。Mask-RCNN在Faster-RCNN的基础上多了一个ROIAligin和Mask预测分支,因此Mask R-CNN的损失也是多任务损失,可以表示为如下公式:
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表示预测框的回归损失, L m a s k L_{mask} Lmask表示Mask部分的损失。
对于预测的二值掩膜输出,论文对每一个像素点应用sigmoid
函数,整体损失定义为平均二值交叉损失熵。引入预测K个输出的机制,允许每个类都生成独立的掩膜,避免类间竞争。这样做解耦了掩膜和种类预测。不像FCN的做法,在每个像素点上应用softmax
函数,整体采用的多任务交叉熵,这样会导致类间竞争,最终导致分割效果差。
下图更清晰的展示了Mask-RCNN的Mask预测部分的损失计算,来自知乎用户vision
:
在Faster-RCNN中,如果ROI区域和GT框的IOU>0.5
,则ROI是正样本,否则为负样本。 L m a s k L_{mask} Lmask只在正样本上定义,而Mask的标签是ROI和它对应的Ground Truth Mask的交集。其他的一些训练细节如下:
mini-batch=2
,每张图片有 N N N个采样ROIs,其中正负样本比例为1:3
。batch_size=2
,迭代160k
次,初始学习率0.02
,在第120k
次迭代时衰减10倍,weight_decay=0.0001
,momentum=0.9
。测试阶段,采用的proposals
的数量分别为 300 300 300(Faster-RCNN)和1000(FPN)。在这些proposals
上,使用bbox
预测分支配合后处理nms
来预测box
。然后使用Mask预测分支对最高score
的100个检测框进行处理。可以看到这里和训练时Mask预测并行处理的方式不同,这里主要是为了加速推断效率。然后,Mask网络分支对每个ROI预测 K K K个掩膜图像,但这里只需要使用其中类别概率最大的那个掩膜图像就可以了,并将这个掩膜图像resize
回ROI大小,并以0.5
的阈值进行二值化。
非常的SOTA,Mask R-CNN打败了上界冠军FCIS(其使用了multi-scale训练,水平翻转测试,OHEM等),具体结果如Table1所示:
再来一些可视化结果看看,如Figure5所示。
Table2展示了Mask-RCNN的消融实验,(a)
显示网络越深,效果越好。并且FPN效果要好一些。而(b
)显示sigmoid
要比softmax
效果好一些。(c)
和(d)
显示ROIAligin效果有提升,特别是AP75提升最明显,说明对精度提升很有用。(e)
显示mask banch采用FCN效果较好(因为FCN没有破坏空间关系)。
从Table3可以看出,在预测的时候即使不使用Mask分支,结果精度也是很高的。可以看到ROIAligin直接使用到Faster-RCNN上相对于ROI Pooling提高了0.9个点,但比Mask-RCNN低0.9个点。作者将其归结为多任务训练的提升,由于加入了mask分支,带来的loss改变,间接影响了主干网络的效果。
和Mask-RCNN相比,关键点检测就是将Mask分支变成heatmap
回归分支,需要注意的是最后的输出是 m × m m\times m m×m形式的softmax
, 不再是sigmoid
,论文提到这有利于单独一个点的检测,并且最后的Mask分辨率是 56 × 56 56\times 56 56×56,不再是 28 × 28 28\times 28 28×28。
后面我会更新Mask R-CNN的代码详细解析,从代码角度详细分析Mask R-CNN的细节,论文解析暂时就讲到这里了。
欢迎关注GiantPandaCV, 在这里你将看到独家的深度学习分享,坚持原创,每天分享我们学习到的新鲜知识。( • ̀ω•́ )✧
有对文章相关的问题,或者想要加入交流群,欢迎添加BBuf微信: