Mask RCNN

Posted liuboblog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mask RCNN相关的知识,希望对你有一定的参考价值。

先看效果

仅仅用了50张训练照片,训练了1000步之后进行测试,发现效果好得令人称奇。

之前用YOLO训练很难收敛。(虽然two-stage方法精度更高,这种比较虽然有些不合理)

Mask RCNN沿用了Faster RCNN的思想,特征提取采用ResNet-FPN的架构,另外多加了一个Mask预测分支。

Mask RCNN沿用了Faster RCNN的思想,特征提取采用ResNet-FPN的架构,另外多加了一个Mask预测分支。可见Mask RCNN综合了很多此前优秀的研究成果。为了更好地讲解Mask RCNN,我会先回顾一下几个部分:

1.Faster RCNN
2.ResNet-FPN
3.ResNet-FPN+Fast RCNN

回顾完之后讲ResNet-FPN+Fast RCNN+Mask,实际上就是Mask RCNN。

一、Faster RCNN

Faster RCNN是两阶段的目标检测算法,包括阶段一的Region proposal以及阶段二的bounding box回归和分类。用一张图来直观展示Faster RCNN的整个流程:

技术图片
Faster RCNN使用CNN提取图像特征,然后使用region proposal network(RPN)去提取出ROI,然后使用ROI pooling将这些ROI全部变成固定尺寸,再喂给全连接层进行Bounding box回归和分类预测。

ResNet-FPN

多尺度检测在目标检测中变得越来越重要,对小目标的检测尤其如此。现在主流的目标检测方法很多都用到了多尺度的方法,包括最新的yolo v3。Feature Pyramid Network (FPN)则是一种精心设计的多尺度检测方法,下面就开始简要介绍FPN。
技术图片
FPN实际上是一种通用架构,可以结合各种骨架网络使用,比如VGG,ResNet等。Mask RCNN文章中使用了ResNNet-FPN网络结构。如下图:
技术图片
ResNet-FPN包括3个部分,自下而上连接,自上而下连接和横向连接。下面分别介绍。

3×3的卷积是为了消除混叠效应。

自上而下

从下到上路径。可以明显看出,其实就是简单的特征提取过程,和传统的没有区别。具体就是将ResNet作为骨架网络,根据feature map的大小分为5个stage。他们相对于原始图片的stride是{4,8,16,32}。需要注意的是,考虑到内存原因,stage1的conv1并没有使用。

三、ResNet-FPN+Fast RCNN

技术图片
将ResNet-FPN和Fast RCNN进行结合,实际上就是Faster RCNN的了,但与最初的Faster RCNN不同的是,FPN产生了特征金字塔技术图片 ,而并非只是一个feature map。金字塔经过RPN之后会产生很多region proposal。这些region proposal是分别由P2, P3,P4,P5,P6经过RPN产生的,但用于输入到Fast RCNN中的是 P2, P3,P4,P5(没有P6)也就是说要在 P2, P3,P4,P5中根据region proposal切出ROI进行后续的分类和回归预测。问题来了,我们要选择哪个feature map来切出这些ROI区域呢?实际上,我们会选择最合适的尺度的feature map来切ROI。具体来说,我们通过一个公式来决定宽w和高h的ROI到底要从哪个Pk来切:
$K = lfloor K0 + log_2( sqrt{wh} /224) floor$
这里224表示用于预训练的ImageNet图片的大小。 $k_0$表示面积为$w × h = 224 × 224$的ROI所应该在的层级。假设ROI的scale小于224(比如说是112 * 112), $k = k_0 - 1 = 4-1=3$就意味着要从更高分辨率的 P3 中产生。另外,k值会做取整处理,防止结果不是整数。

这种做法很合理,大尺度的ROI要从低分辨率的feature map上切,有利于检测大目标,小尺度的ROI要从高分辨率的feature map上切,有利于检测小目标。

四、ResNet-FPN+Fast RCNN+mask

我们再进一步,将ResNet-FPN+Fast RCNN+mask,则得到了最终的Mask RCNN,如下图:
技术图片
Mask RCNN的构建很简单,只是在ROI pooling(实际上用到的是ROIAlign,后面会讲到)之后添加卷积层,进行mask预测的任务。

下面总结一下Mask RCNN的网络:
1.骨干网络ResNet-FPN,用于特征提取,另外,ResNet还可以是:ResNet-50,ResNet-101,ResNeXt-50,ResNeXt-101;
2.头部网络,包括边界框识别(分类和回归)+mask预测。头部结构见下图:
技术图片

五、ROI Align

实际上,Mask RCNN中还有一个很重要的改进,就是ROIAlign。Faster R-CNN存在的问题是:特征图与原始图像是不对准的(mis-alignment),所以会影响检测精度。而Mask R-CNN提出了RoIAlign的方法来取代ROI pooling,RoIAlign可以保留大致的空间位置。

为了讲清楚ROI Align,这里先插入两个知识,双线性插值和ROI pooling。

1.双线性插值

在讲双线性插值之前,还得看最简单的线性插值。
已知数据$(x_0, y_0)$与$(x_1,y_1)$,要计算$[x_0, x_1]$区间内某一位置$x$在直线上的$y$值,如下图所示。
技术图片

计算方法很简单,通过斜率相等就可以构建y和x之间的关系,如下:
技术图片

双线性插值本质上就是在两个方向上做线性插值。
技术图片

如图,假设我们想得到P点的插值,我们可以先在x方向上,对Q11和Q21之间做线性插值得到R1,R2。然后在y方向上对 R1和R2进行线性插值就可以得到最终的P。其实知道这个就已经理解了双线性插值的意思了,如果用公式表达则如下(注意前面的系数看成权重就很好理解了)。
首先在 x 方向进行线性插值,得到:
技术图片
然后在 y 方向进行线性插值,得到
技术图片
这样就得到所要的结果 技术图片

技术图片

2.ROIpooling

ROI pooling就不多解释了,直接通过一个例子来形象理解。假设现在我们有一个8x8大小的feature map,我们要在这个feature map上得到ROI,并且进行ROI pooling到2x2大小的输出。
技术图片

假设ROI的bounding box为:$[x_1, y_1, x_2, y_2] = [0,3,7,8]$,如图:
技术图片
将它划分为2x2的网格,因为ROI的长宽除以2是不能整除的,所以会出现每个格子大小不一样的情况。
技术图片
进行max pooling的最终2x2的输出为:
技术图片

3. ROI Align

在Faster RCNN中,有两次整数化的过程:
region proposal的xywh通常是小数(注意这里四个值是小数),但是为了方便操作会把它整数化。
两次整数化的过程如下图所示:
技术图片
事实上,经过上述两次整数化,此时的候选框已经和最开始回归出来的位置有一定的偏差,这个偏差会影响检测或者分割的准确度。在论文里,作者把它总结为“不匹配题”(misalignment)。

为了解决这个问题,ROI Align方法取消整数化操作,保留了小数,使用以上介绍的双线性插值的方法获得坐标为浮点数的像素点上的图像数值。但在实际操作中,ROI Align并不是简单地补充出候选区域边界上的坐标点,然后进行池化,而是重新进行设计。

下面通过一个例子来讲解ROI Align操作。如下图所示,虚线部分表示feature map,实线表示ROI,这里将ROI切分成2x2的单元格。如果采样点数是4,那我们首先将每个单元格子均分成四个小方格(如红色线所示),每个小方格中心就是采样点。这些采样点的坐标通常是浮点数,所以需要对采样点像素进行双线性插值(如四个箭头所示),就可以得到该像素点的值了。然后对每个单元格内的四个采样点进行maxpooling,就可以得到最终的ROIAlign的结果。

技术图片
需要说明的是,在相关实验中,作者发现将采样点设为4会获得最佳性能,甚至直接设为1在性能上也相差无几。事实上,ROI Align 在遍历取样点的数量上没有ROIPooling那么多,但却可以获得更好的性能,这主要归功于解决了misalignment的问题。

六、损失

Mask RCNN定义多任务损失:
技术图片
技术图片

需要具体说明的是 $L_{mask}$,假设一共有K个类别,则mask分割分支的输出维度是$Kmm$,对于$m*m$中的每个点,都会输出K个二值Mask(每个类别使用sigmoid输出)。需要注意的是,计算loss的时候,并不是每个类别的sigmoid输出都计算二值交叉熵损失,而是该像素属于哪个类,哪个类的sigmoid输出才要计算损失(如图红色方形所示)。需要注意的是,计算loss的时候,并不是每个类别的sigmoid输出都计算二值交叉熵损失,而是该像素属于哪个类,哪个类的sigmoid输出才要计算损失(如图红色方形所示)。并且在测试的时候,我们是通过分类分支预测的类别来选择相应的mask预测。这样,mask预测和分类预测就彻底解耦了。这与FCN方法是不同,FCN是对每个像素进行多类别softmax分类,然后计算交叉熵损失,很明显,这种做法是会造成类间竞争的,而每个类别使用sigmoid输出并计算二值损失,可以避免类间竞争。实验表明,通过这种方法,可以较好地提升性能。

以上是关于Mask RCNN的主要内容,如果未能解决你的问题,请参考以下文章

mask-rcnn代码解读:mask_iou的计算

实现文字色彩渐变(Mask)

OpenCV中mask的设置方法?

CSS mask的用法

MASK-RCNN是什么?MASK(掩膜)又是什么?

Mask属性介绍