目录
1,概述
Mask RCNN沿用了Faster RCNN(https://blog.csdn.net/YOULANSHENGMENG/article/details/121850364)的思想,特征提取采用ResNet-FPN的架构,另外多加了一个Mask(用于生成物体的掩模)预测分割分支。 如下图1所示。其中黑色部分为原来的Faster-RCNN,红色部分为在Faster-RCNN网络上的修改。将RoI Pooling 层替换成了RoIAlign层;添加了并列的FCN层(mask层)。
图1 Mask RCNN基本结构
Mask RCNN的网络和faster_ecnn的结构最不相似的地方为:
2,ResNet-FPN
多尺度检测在目标检测中变得越来越重要,对小目标的检测尤其如此。现在主流的目标检测方法很多都用到了多尺度的方法,包括最新的yolov3。Feature Pyramid Network (FPN)则是一种精心设计的多尺度检测方法,FPN结构中包括自下而上,自上而下和横向连接三个部分,如下图所示。这种结构可以将各个层级的特征进行融合,使其同时具有强语义信息和强空间信息,在特征学习中算是一把利器了。
图2 FPN基本结构
FPN实际上是一种通用架构,可以结合各种骨架网络使用,比如VGG,ResNet等。Mask RCNN文章中使用了ResNNet-FPN网络结构。如图3所示:
图3 ResNNet-FPN网络结构
FPN的提出是为了实现更好的feature maps融合,一般的网络都是直接使用最后一层的feature maps,虽然最后一层的feature maps 语义强,但是位置和分辨率都比较低,容易检测不到比较小的物体。FPN的功能就是融合了底层到高层的feature maps ,从而充分的利用了提取到的各个阶段的Z征(ResNet中的C2-C5 )。
ResNet-FPN包括3个部分,自下而上连接,自上而下连接和横向连接。下面分别介绍。
自下而上
从下到上路径。可以明显看出,其实就是简单的特征提取过程,和传统的没有区别。具体就是将ResNet作为backbone,根据feature map的大小分为5个stage。stage2,stage3,stage4和stage5各自最后一层输出conv2,conv3,conv4和conv5分别定义为 ,他们相对于原始图片的stride是{4,8,16,32}。需要注意的是,考虑到内存原因,stage1的conv1并没有使用。图4为 两种常用的残差结构。ResNet(深度残差网络)实际上就是为了能够训练更加深层的网络提供了有利的思路,毕竟之前一段时间里面一直相信深度学习中网络越深得到的效果会更加的好,但是在构建了太深层之后又会使得网络退化。ResNet使用了跨层连接,使得训练更加容易。
图4 不同的残差单元
自上而下和横向连接
自上而下是从最高层开始进行上采样,这里的上采样直接使用的是最近邻上采样,而不是使用反卷积操作,一方面简单,另外一方面可以减少训练参数。横向连接则是将上采样的结果和自底向上生成的相同大小的feature map进行融合。具体就是对 中的每一层经过一个conv 1x1操作(1x1卷积用于降低通道数),无激活函数操作,输出通道全部设置为相同的256通道,然后和上采样的feature map进行加和操作。在融合之后还会再采用3*3的卷积核对已经融合的特征进行处理,目的是消除上采样的混叠效应(aliasing effect)。
实际上,上图少绘制了一个分支:M5经过步长为2的max pooling下采样得到 P6,作者指出使用P6是想得到更大的anchor尺度512×512。但P6是只用在 RPN中用来得到region proposal的,并不会作为后续Fast RCNN的输入。
总结一下,ResNet-FPN作为RPN输入的feature map是 ,而作为后续Fast RCNN的输入则是 。
3, ROI Align
实际上,Mask RCNN中还有一个很重要的改进,就是ROIAlign。Faster R-CNN存在的问题是:特征图与原始图像是不对准的(mis-alignment),所以会影响检测精度。而Mask R-CNN提出了RoIAlign的方法来取代ROI pooling,RoIAlign可以保留大致的空间位置。
要清楚ROI Align,需要知道两个知识,双线性插值和ROI pooling,可以参考博文:
RoIAlign的思想其实很简单,就是取消了取整的这种粗暴做法,而是通过双线性插值来得到固定四个点坐标的像素值,从而使得不连续的操作变得连续起来,返回到原图的时候误差也就更加的小。
RoIPooling,它的目的是为了从RPN网络确定的ROI中导出较小的特征图(a small feature map,eg 7x7),ROI的大小各不相同,但是RoIPool后都变成了7x7大小。RPN网络会提出若干RoI的坐标以[x,y,w,h]表示,然后输入RoI Pooling,输出7x7大小的特征图供分类和定位使用。问题就出在RoI Pooling的输出大小是7x7上,如果ROI网络输出的RoI大小是8*8的,那么无法保证输入像素和输出像素是一一对应,首先他们包含的信息量不同(有的是1对1,有的是1对2),其次他们的坐标无法和输入对应起来(1对2的那个RoI输出像素该对应哪个输入像素的坐标?)。这对分类没什么影响,但是对分割却影响很大。RoIAlign的输出坐标使用插值算法得到,不再量化;每个grid中的值也不再使用max,同样使用差值算法。
为了得到为了得到固定大小(7X7)的feature map,ROIAlign技术并没有使用量化操作,比如665 / 32 = 20.78,就用20.78,不用什么20来替代它,比如20.78 / 7 = 2.97,就用2.97,而不用2来代替它。这就是ROIAlign的初衷如下图所示。
下面使用一个实例来说明RoIAlign的处理方法:
4, mask
mask的预测也是在ROI之后的,通过FCN(Fully Convolution Network如下图所示,博文链接https://blog.csdn.net/YOULANSHENGMENG/article/details/121015109)来进行的。注意这个是实现的语义分割而不是实例分割。因为每个ROI只对应一个物体,只需对其进行语义分割就好,相当于了实例分割了,这也是Mask-RCNN与其他分割框架的不同,是先分类再分割。
FCN工作示意图
对于每一个ROI的mask都有80类,因为coco上的数据集是80个类别,并且这样做的话是为了减弱类别间的竞争,从而得到更加好的结果。
mask结构
5,训练及预测
该模型的训练和预测是分开的,不是套用同一个流程。在训练的时候,classifier和mask都是同时进行的;在预测的时候,显示得到classifier的结果,然后再把此结果传入到mask预测中得到mask,有一定的先后顺序。
1)训练的流程图
2)预测的流程图
6,损失
Mask RCNN定义多任务损失: