Mask R-CNN ——Faster R-CNN+ROI Align+FCN (目标检测+语义分割)(two-stage)(深度学习)(ICCV 2017)

论文名称:《 Mask R-CNN 》

论文下载:https://arxiv.org/abs/1703.06870

论文代码:https://github.com/facebookresearch/Detectron


一、算法概述:

Mask R-CNN是一个实例分割(Instance segmentation)算法,可以用来做“目标检测”、“目标实例分割”、“目标关键点检测”。

目标检测、语义分割、实例分割的区别

       Mask R-CNN是一个非常灵活的框架,可以增加不同的分支完成不同的任务,可以完成目标分类、目标检测、语义分割、实例分割、人体姿势识别等多种任务。

结构概览图

1、Mask R-CNN的特点:

(1)高速和高准确率:选用经典的目标检测算法Faster-rcnn和经典的语义分割算法FCN。前者可以既快又准的完成目标检测的功能,后者FCN可以精准的完成语义分割的功能,这两个算法都是对应领域中的经典之作。Mask R-CNN比Faster-rcnn复杂,但是最终仍然可以达到5fps的速度,这和原始的Faster-rcnn的速度相差不大。由于发现了ROI Pooling中所存在的像素偏差问题,提出了对应的ROIAlign策略,加上FCN精准的像素MASK,使得其可以获得高准确率。

补充:RCN即全卷积网络(语义分割)(CVPR 2015)——《 Fully Convolutional Networks for Semantic Segmentation 》

(2)简单直观:整个Mask R-CNN算法的思路很简单,就是在原始Faster-rcnn算法的基础上面增加了FCN来产生对应的MASK分支。即(Faster-rcnn) + FCN,更细致的是 (RPN + ROIAlign + Fast-rcnn) + FCN。

(3)易于使用:整个Mask R-CNN算法非常的灵活,可以用来完成多种任务,包括目标分类、目标检测、语义分割、实例分割、人体姿态识别等多个任务,这将其易于使用的特点展现的淋漓尽致。除此之外,可以更换不同的backbone architecture和Head Architecture来获得不同性能的结果。

       上图是文章中的示意图,也是下图中修改生效后的最终结果示意图。

结构细节示意图

2、上图中黑色部分为原来的 Faster-RCNN的结构,红色部分为Mask R-CNN在 Faster R-CNN网络上的修改:

1)将 Roi Pooling 层替换成了 RoiAlign; 2)添加并列的 FCN 层(mask 层); 

3、先来概述一下 Mask-RCNN 的几个特点(来自于 Paper 的 Abstract):

1)在边框识别(分类+回归)的基础上添加一个分支网络,用于 语义Mask 识别;
2)训练简单,相对于 Faster 仅增加一个小的 Overhead(花销),可以跑到 5FPS;
3)加入Mask后可以方便的扩展到其他任务,比如人的姿态估计 等;
4)不借助 Trick,在每个任务上,效果优于目前所有的 single-model entries;

Mask R-CNN具有灵活形式

图中上半块灰色部分是 原来的 R-CNN 结合 ResNet(左图) or FPN(右图) 的网络,下半块黑色部分为新添加的并联 Mask层,说明作者所提出的Mask RCNN 方法的泛化适应能力 ,即可以和多种 RCNN框架结合。

二、算法核心:(Faster R-CNN + ROIAlign + FCN) 

1、 强化的基础网络:
     通过 ResNeXt-101 + FPN 用作特征提取网络,达到最先进的效果。

2、ROIAlign:ROI Pooling点此进入
     采用 ROIAlign 替代 RoiPooling(改进池化操作)。引入了一个插值过程,先通过双线性插值到14*14,再 pooling到7*7,很大程度上解决了仅通过 Pooling 直接采样带来的 Misalignment 对齐问题(虽然 Misalignment 在分类问题上影响并不大,但在 Pixel 级别的 Mask 上会存在较大误差)。ROIAlign使得原图中的像素和feature map中的像素是完全对齐的,没有偏差,这不仅会提高检测的精度,同时也会有利于实例分割。

      RoiAlign是在Mask RCNN中使用以便使生成的候选框region proposal映射产生固定大小的feature map时提出的:

      先贴出一张图,接着通过这图解释RoiAlign的工作原理:

同样,针对上图,有着类似的映射:

     1)Conv layers使用的是VGG16,feat_stride=32(即表示,经过网络层后图片缩小为原图的1/32),原图800*800,最后一层特征图feature map大小:25*25

     2)假定原图中有一region proposal,大小为665*665,这样,映射到特征图中的大小:665/32=20.78,即20.78*20.78,此时,没有像RoiPooling那样就行取整操作,保留浮点数

      3)假定pooled_w=7,pooled_h=7,即pooling后固定成7*7大小的特征图,所以,将在 feature map上映射的20.78*20.78的region proposal 划分成49个同等大小的小区域,每个小区域的大小20.78/7=2.97,即2.97*2.97

      4)假定采样点数为4,即表示,对于每个2.97*2.97的小区域,平分四份,每一份取其中心点位置,而中心点位置的像素,采用双线性插值法进行计算,这样,就会得到四个点的像素值,如下图中间:

上图中,四个红色 点的像素值是通过双线性插值算法计算得到的。最后,取四个像素值中最大值作为这个小区域(2.97*2.97)的像素值,如此类推,同样是49个小区域得到49个像素值,组成7*7大小的feature map。

        总结如下:ROIAlign技术并没有使用量化操作,没有引入量化误差,比如665 / 32 = 20.78,就用20.78,不用20来替代它,比如20.78 / 7 = 2.97,就用2.97,而不用2来代替。这就是ROIAlign的初衷。那么我们如何处理这些浮点数呢,我们的解决思路是使用“双线性插值”算法。双线性插值是一种比较好的图像缩放算法,它充分的利用了原图中虚拟点(比如20.56这个浮点数,像素位置都是整数值,没有浮点值)四周的四个真实存在的像素值来共同决定目标图中的一个像素值,即可以将20.56这个虚拟的位置点对应的像素值估计出来。如下图所示,蓝色的虚线框表示卷积后获得的feature map,黑色实线框表示ROI feature,最后需要输出的大小是2x2,那么我们就利用双线性插值来估计这些蓝点(虚拟坐标点,又称双线性插值的网格点)处所对应的像素值,最后得到相应的输出。这些蓝点是2x2Cell中的随机采样的普通点,作者指出,这些采样点的个数和位置不会对性能产生很大的影响。然后在每一个橘红色的区域里面进行max pooling或者average pooling操作,获得最终2x2的输出结果。

      ROI Pooling和ROIAlign最大的区别是:前者使用了两次量化操作,而后者并没有采用量化操作。

     总结:对于检测图片中大目标物体时,两种方案的差别不大,而如果是图片中有较多小目标物体需要检测,则优先选择RoiAlign。

3、Loss Function:

由于增加了mask分支,每个ROI的Loss函数如下所示:(其中L_cls和L_box和Faster r-cnn中定义的相同)

对于每一个ROI,mask分支有K*m*m维度的输出,其对K个大小为m*m的mask进行编码,每一个mask有K个类别。我们使用了per-pixel sigmoid,并且将L_mask定义为the average binary cross-entropy loss (二分类均值交叉熵损失)(  Lmask(Cls_k) = Sigmoid (Cls_k))。对应一个属于GT中的第k类的ROI,L_mask仅仅在第k个mask上面有定义(其它的k-1个mask输出对整个Loss没有贡献)。我们定义的L_mask允许网络为每一类生成一个mask,而不用和其它类进行竞争;我们依赖于分类分支所预测的类别标签来选择输出的mask。

       这样将分类和mask生成分解开来。这与利用FCN进行语义分割的有所不同,它通常使用一个per-pixel sigmoid和一个multinomial cross-entropy loss ,在这种情况下mask之间存在竞争关系;而由于我们使用了一个per-pixel sigmoid 和一个binary loss ,不同的mask之间不存在竞争关系。

       经验表明,这可以提高实例分割的效果。一个mask对一个目标的输入空间布局进行编码,与类别标签和BB偏置不同,它们通常需要通过FC层而导致其以短向量的形式输出。我们可以通过由卷积提供的像素和像素的对应关系来获得mask的空间结构信息。

       具体的来说,我们使用FCN从每一个ROI中预测出一个m*m大小的mask,这使得mask分支中的每个层能够明确的保持m×m空间布局,而不将其折叠成缺少空间维度的向量表示。和以前用fc层做mask预测的方法不同的是,我们的实验表明我们的mask表示需要更少的参数,而且更加准确。这些像素到像素的行为需要我们的ROI特征,而我们的ROI特征通常是比较小的feature map,其已经进行了对其操作,为了一致的较好的保持明确的单像素空间对应关系,我们提出了ROIAlign操作

补充概念:二分类问题的交叉熵损失函数;

        在二分类问题中,损失函数为交叉熵损失函数。对于样本(x,y)来讲,x为样本 y为对应的标签。在二分类问题中,其取值的集合可能为{0,1},我们假设某个样本的真实标签为yt,该样本的yt=1的概率为yp,则该样本的损失函数为:

                                                                    log(yt|yp) = - (yt*log(yp) + (1 - yt)log(1 - yp))  

         如果对于整个数据集上的模型而言:其损失函数就是所有样本的点的损失函数的平均值。

4、Mask R-CNN算法步骤:

(1)首先,输入一幅你想处理的图片,然后进行对应的预处理操作,或者预处理后的图片;

(2)然后,将其输入到一个预训练好的神经网络中(ResNeXt等)获得对应的feature map;

(3)接着,对这个feature map中的每一点设定预定个的ROI,从而获得多个候选ROI;

(4)接着,将这些候选的ROI送入RPN网络进行二值分类(前景或背景)和BB回归,过滤掉一部分候选的ROI;

(5)接着,对这些剩下的ROI进行ROIAlign操作(即先将原图和feature map的pixel对应起来,然后将feature map和固定的feature对应起来);

(6)最后,对这些ROI进行分类(N类别分类)、BB回归和MASK生成(在每一个ROI里面进行FCN操作)。

5、FCN——全卷积网络 (CVPR 2015)——《 Fully Convolutional Networks for Semantic Segmentation 》

FCN算法是一个经典的语义分割算法,可以对图片中的目标进行准确的分割。其总体架构如上图所示,它是一个端到端的网络,主要的模快包括卷积和去卷积,即先对图像进行卷积和池化,使其feature map的大小不断减小;然后进行反卷积操作,即进行插值操作,不断的增大其feature map,最后对每一个像素值进行分类。从而实现对输入图像的准确分割。关于FCN网络可以参考这篇论文;https://www.cnblogs.com/gujianhan/p/6030639.html.

三、实验结果:

发布了51 篇原创文章 · 获赞 207 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/Gentleman_Qin/article/details/84860919