Mask RCNN

论文:Mask R-CNN
发表时间:2018
发表作者:(Facebook AI Research)Kaiming He, Georgia Gkioxari, Piotr Dollar, Ross Girshick
论文链接:论文链接
论文代码:Facebook代码链接;Tensorflow版本代码链接; Keras and TensorFlow版本代码链接;MxNet版本代码链接

Mask R-CNN是一个实例分割(Instance segmentation)算法,可以用来做“目标检测”、“目标实例分割”、“目标关键点检测”。Mask RCNN以Faster RCNN原型,增加了一个分支用于分割任务。Mask RCNN比Faster RCNN速度慢一些,达到了5fps。
Mask R-CNN引入了RoI Align代替Faster RCNN中的RoI Pooling。因为RoI Pooling并不是按照像素一一对齐的(pixel-to-pixel alignment),也许这对bbox的影响不是很大,但对于mask的精度却有很大影响。使用RoI Align后mask的精度从10%显著提高到50%。引入语义分割分支,实现了mask和class预测的关系的解耦,mask分支只做语义分割,类型预测的任务交给另一个分支。这与原本的FCN网络是不同的,原始的FCN在预测mask时还用同时预测mask所属的种类。

结构

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

Mask R-CNN1

Mask R-CNN可以分解为如下的3个模块,Faster-rcnn、ROIAlign和FCN。分别对这3个模块进行讲解,这也是该算法的核心。

FCN

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

Mask R-CNN2

ROIAlign

OI Pooling和ROIAlign最大的区别是:前者使用了两次量化操作,而后者并没有采用量化操作,使用了线性插值算法,具体的解释如下所示。

Mask R-CNN3

如图9所示,为了得到固定大小(7X7)的feature map,我们需要做两次量化操作:1)图像坐标 — feature map坐标,2)feature map坐标 — ROI feature坐标。
我们来说一下具体的细节,如图我们输入的是一张800x800的图像,在图像中有两个目标(猫和狗),狗的BB大小为665x665,经过VGG16网络后,我们可以获得对应的feature map,如果我们对卷积层进行Padding操作,我们的图片经过卷积层后保持原来的大小,但是由于池化层的存在,我们最终获得feature map 会比原图缩小一定的比例,这和Pooling层的个数和大小有关。在该VGG16中,我们使用了5个池化操作,每个池化操作都是2Pooling,因此我们最终获得feature map的大小为800/32 x 800/32 = 25x25(是整数),但是将狗的BB对应到feature map上面,我们得到的结果是665/32 x 665/32 = 20.78 x 20.78,结果是浮点数,含有小数,但是我们的像素值可没有小数,那么作者就对其进行了量化操作(即取整操作),即其结果变为20 x 20,在这里引入了第一次的量化误差;然而我们的feature map中有不同大小的ROI,但是我们后面的网络却要求我们有固定的输入,因此,我们需要将不同大小的ROI转化为固定的ROI feature,在这里使用的是7x7的ROI feature,那么我们需要将20 x 20的ROI映射成7 x 7的ROI feature,其结果是 20 /7 x 20/7 = 2.86 x 2.86,同样是浮点数,含有小数点,我们采取同样的操作对其进行取整吧,在这里引入了第二次量化误差。其实,这里引入的误差会导致图像中的像素和特征中的像素的偏差,即将feature空间的ROI对应到原图上面会出现很大的偏差。原因如下:比如用我们第二次引入的误差来分析,本来是2,86,我们将其量化为2,这期间引入了0.86的误差,看起来是一个很小的误差呀,但是你要记得这是在feature空间,我们的feature空间和图像空间是有比例关系的,在这里是1:32,那么对应到原图上面的差距就是0.86 x 32 = 27.52。这个差距不小吧,这还是仅仅考虑了第二次的量化误差。这会大大影响整个检测算法的性能,因此是一个严重的问题。

Mask R-CNN4

如图所示,为了得到为了得到固定大小(7X7)的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的输出结果。我们的整个过程中没有用到量化操作,没有引入误差,即原图中的像素和feature map中的像素是完全对齐的,没有偏差,这不仅会提高检测的精度,同时也会有利于实例分割。

![Mask R-CNN5][base64str5]

LOSS计算与分析

由于增加了mask分支,每个ROI的Loss函数如下所示:

\[
L = L_{cls}+L_{box}+L_{mask}
\]

其中Lcls和Lbox和Faster r-cnn中定义的相同。对于每一个ROI,mask分支有$Kmm$维度的输出,其对K个大小为$mm$的mask进行编码,每一个mask有K个类别。使用了per-pixel sigmoid,并且将Lmask定义为the average binary cross-entropy loss 。对应一个属于GT中的第k类的ROI,Lmask仅仅在第k个mask上面有定义(其它的k-1个mask输出对整个Loss没有贡献)。
定义的Lmask允许网络为每一类生成一个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操作。

算法步骤

Mask R-CNN算法步骤:

  • 首先,输入一幅你想处理的图片,然后进行对应的预处理操作,或者预处理后的图片;
  • 然后,将其输入到一个预训练好的神经网络中(ResNeXt等)获得对应的feature map;
  • 接着,对这个feature map中的每一点设定预定个的ROI,从而获得多个候选ROI;
  • 接着,将这些候选的ROI送入RPN网络进行二值分类(前景或背景)和BB回归,过滤掉一部分候选的ROI;
  • 接着,对这些剩下的ROI进行ROIAlign操作(即先将原图和feature map的pixel对应起来,然后将feature map和固定的feature对应起来);
  • 最后,对这些ROI进行分类(N类别分类)、BB回归和MASK生成(在每一个ROI里面进行FCN操作)。

总结

Mask R-CNN论文的主要贡献包括以下几点:

  • 分析了ROI Pool的不足,提升了ROIAlign,提升了检测和实例分割的效果;
  • 将实例分割分解为分类和mask生成两个分支,依赖于分类分支所预测的类别标签来选择输出对应的mask。同时利用Binary Loss代替Multinomial Loss,消除了不同类别的mask之间的竞争,生成了准确的二值mask;
  • 并行进行分类和mask生成任务,对模型进行了加速。

参考:
Mask RCNN

最新文章

  1. Metaio获取当前追踪的对象的方法
  2. Linux内核实现中断和中断处理(二)
  3. linux ubuntu12.04 解压中文zip文件,解压之后乱码
  4. NOIP2009解题报告
  5. Send User to a Portal Folder
  6. Linux awk小记
  7. Tomcat安装与配置图文教程
  8. SQL server 使用触发器跨数据库备份数据
  9. Bootstrap 图标
  10. STM32的RFID射频读写控制装置
  11. bzoj3685普通van Emde Boas树 线段树
  12. 【基础】CSS实现多重边框的5种方式
  13. Android 面试100问- 0序0
  14. LR与SVM的异同
  15. umi中使用scss
  16. Css预处理器---Less(二)
  17. Kaggle(1):数据挖掘的基本流程
  18. 关于Javascript的des加密
  19. AlexNet网络结构特点总结
  20. InfluxDB 备份和恢复

热门文章

  1. 【c# 学习笔记】使用新成员隐藏基类成员
  2. JWT(JSON Web Tokens)操作帮助类
  3. 八个免费的Vue图标库
  4. javascript jssdk退出微信的方法
  5. iText输出中文
  6. 深入理解linux内核-进程和程序
  7. IO-file-06 文件夹的遍历
  8. [转帖]1A2C多口充 紫米USB充电器65W桌面快充版评测
  9. PHP和Memcached - Memcached的介绍及常用命令
  10. yii2中通过migration创建数据表