MaskRCNN论文理解

文章目录

Abstract

在Faster RCNN的基础上又加了一个预测物体掩码的分支,和预测边界框并列存在。

Introduction

目标:
将每个像素分类为一组固定的类别,而不区分对象实例。
方法简介
在Faster RCNN每个ROI后面加了一个分支来预测分割掩码,和分类与回归并列。这个加入的新分支是一个小型FCN(Fully Convolutional Network),用一种像素到像素的处理方式。
前人不足之处
Faster RCNN不是为网络输入和输出之间的像素对像素对齐而设计的,为了克服不对齐的问题,作者提出了RoIAlign,能成功保存精确的空间位置。

RoIAlign的优点

  • 提高了10%50%10\%-50\%10%−50%的掩码精准度,在更严格的本地化度量下(就是说没用取整的方法,精确到了浮点数)得到了的收益。
  • 对decouple mask和类预测很重要:作者独立地预测每个类的二进制掩码,没有类之间的竞争(sigmoid ),并依靠网络的RoI分类分支来预测类别。

作者测试FCNs来执行每个像素的多类别(softmax)的方法,将分割和分类放到一块,但是根据实验结果来看,效果很一般

Realted Work

Instance Segmentation

在RCNN有效性的驱动下,许多实例分割的方法都基于 segment proposals
有一些逐像素的方法,将每个像素分类,然后将同类的像素放到实例里面。
Mask RCNN是 instance-first 策略

Mask RCNN

Faster RCNN对于每个候选框有两个输出:一个是class label,一个是b-box偏移。而Mask RCNN就是又加上了一个输出:目标掩码。但和前两个不同的是,新加的这一层需要更好的空间排列信息

Faster RCNN 回顾

分两阶段,第一阶段RPN,生成推荐区域;第二阶段,用RoIPool从每个候选框中提取出特征,然后分类和回归。特征能被两个网络使用,速度更快。

Mask RCNN

阶段组成

  1. 第一阶段是RPN。
  2. 第二阶段,和分类与回归并列,对每个RoI输出二进制掩码。

Loss计算

总的损失函数有三部分:L=Lcls+Lbox+LmaskL=L_{cls}+L_{box}+L_{mask}L=Lcls​+Lbox​+Lmask​
Lfinal=L(pi,ti)+(Lcls+Lbox+Lmask)L_{final}=L({p_i},{t_i})+(L_{cls}+L_{box}+L_{mask})Lfinal​=L(pi​,ti​)+(Lcls​+Lbox​+Lmask​)
注:其中LboxLmaskL_{box}和L_{mask}Lbox​和Lmask​都只对positive RoI起作用,Lcls+LboxL_{cls}+L_{box}Lcls​+Lbox​和Fast RCNN中的相同。
LmaskL_{mask}Lmask​计算细节

  • 使用逐像素的sigmoid,将LmaskL_{mask}Lmask​定义为平均二进制交叉熵损失。对于与ground-truth类别k相关联的RoI, LmaskL_{mask}Lmask​只在第k个掩码上定义(只有跟该类相匹配的RoI才参与loss计算)。
  • LmaskL_{mask}Lmask​的定义允许网络为每个类生成掩码,而不用在类之间竞争

用sigmoid生成分数,而不是用softmax选出最大的,这样的话应该是可以很大程度上提高精度,因为可能某些局部的像素特别像另一个类,softmax比较后如果得出不该有的类,那么就会丢失信息,对整体的分割产生不好的影响,而sigmoid这种互不影响的就不会如此。
softmax会产生FCIS的 ROI inside map与ROI outside map的竞争。

  • 作者的方法依赖专用的分类分支来预测用于选择输出掩码的类标签,这个操作将掩码和分类预测分开了。

MaskRCNN论文理解

耦合(左)和解耦(右)

MaskRCNN论文理解

图中红点对应被选中的k类

 \  

mask分支的输出为k×m×mk \times m \times mk×m×m维度,其中k代表每个类别,每一个类别都是一层m×mm \times mm×m掩码,然后通过0.5阈值来二值化,划分每个像素为前景或背景。分类网络分支预测 object 类别标签,识别出label之后,只选择对应该label的m×mm \times mm×m维度掩码输出,只使用该label分支的相对熵误差作为误差值进行计算。对每一个像素应用sigmoid,然后取RoI上所有像素的交叉熵的平均值作为LmaskL_{mask}Lmask​。

这里为什么不先得到分类的结果,再计算mask,这样不就只需要计算一层m×mm \times mm×m的mask了吗?

Mask Representation

和其他分支的区别和要求
一个mask编码一个输出物体的空间布局。因此,class label或box偏移量不可避免地被全连接(fc)层折叠成短输出向量,而提取掩码的空间结构可以通过卷积提供的像素到像素的对应关系自然地进行处理。
对每个RoI用FCN来预测一个m×mm \times mm×m掩码。这样的话每个在mask分支中的层都能保留精准的空间信息,而不用压缩成一个特征向量,压缩的话会缺少空间维度。FCN层用到很少的参数,但更精准。

逐像素的行为需要RoI特征,虽然特征图很小,但是可以通过很好的排列来保留精准的逐像素空间对应。

什么样的对应关系?是反卷积对应回去吗?
这里是讲预测一个m×mm \times mm×m掩码,不是说mask分支只预测一个m×mm\times mm×m,而是说被选择之后,只选择了一个分辨率时m×mm\times mm×m的掩码。

RoIAlign

RoIPool的缺点
RoIPool从每个Roi提取小的特征图。RoIPool先将RoI量化成一些离散的粗粒,放到一些bin中,这些bin本身也是被量化过的,然后被每个bin包含的最终的特征值会被整合到一块(通常用最大池化)。(这里的量化就是取整操作)

  • 问题一:量化通过将xxx轴分成16份进行的:[x/16][x/16][x/16],但是,取整的话会导致某些像素偏差,对不上。如下图;
    MaskRCNN论文理解
  • 问题二:RoI将特征图转换成固定大小,比如7 x 7,如果原来是21 x 35,那么就会将对每3 x 5个格子取最大值,然后放到对应的bin中,如果不是整除的话,还是用的取整操作。

这些量化导致RoI和被提取的特征不重合。虽然这些不会影响分类,但是对预测像素级精准的掩码有很大的负面影响。

RoIAlign如何解决上述RoIPool缺点
引入RoIAlign,移除了RoIPool的量化,正确的将被提取的特征和输入对准。作者推荐的方法:

  • 针对问题一:避免任何关于RoI边界或bins的量化,作者使用x/16x/16x/16而不用[x/16][x/16][x/16]。
  • 针对问题二:作者使用双线性插值[22]来计算每个RoI bin中四个定期采样点的输入特征的精确值,然后用平均或最大池化来将结果整合到一起,如下图:

MaskRCNN论文理解

虚线网格代表特征图,方框代表ROI(图中是2×22 \times 22×2bins),点是每个bin的采样点。
RoIAlign用线性插值在特征图上从邻近的网格点计算每个采样点的值。
没有进行任何量化操作。

四个采样点的选择方法, 均分为四个小块,每个小块的中心就是采样点。
MaskRCNN论文理解

结果表明,最大的影响因素就是量化与否,而采样位置是否精准、有多少点被采样,影响都不大

MaskRCNN论文理解

Network Architecture

为了证明效果,列出两种框架:

  • 卷积主干架构用来做覆盖整个图片的特征提取
  • 为了做边界框回归和掩码预测的网络头被分别应用到每个RoI

Backbone命名方法:假定ResNet的深度是50层,如果Faster RCNN用了ResNets从第四阶段的最后一个卷积层提取卷积层,那么就叫做C4,那么这个主干就叫做 ResNet-50-C4。

ResNet和FPN分别结构:
MaskRCNN论文理解
数字,表示分辨率和通道。
箭头要么是卷积,反卷积,要么是全连接,根据前后文判断。
卷积保持维度,反卷积增加维度。卷积都是3 x 3,除了输出卷积是1 x 1,反卷积是2 x 2步长是2,隐藏层用的ReLU。
x4表示有四个连续的卷积。

Implementation Details

设置的超参数和那些现存的Fast/Faster RCNN工作差不多,也很鲁棒

Training

正负样本选择
RoI的和真实框的IoU超过0.5就算正样本,其他都是负样本。
掩码对象
RoI和与他相关的真实框的交集。
作者采用图像中心训练方法[12]。每个最小的batch有两个图片,一个图片取N个RoI,正负样本比例1:3。
在C4中N是64;在FPN中N是512。

Related knowledge

FCN

FCN可以接收任意尺寸的输入图像,采用反卷积层对最后一个卷积层的feature map 进行上采样,使它恢复到输入图像相同尺寸,从而可以对每个像素都产生了一个预测,同时保留了原始输入图像的中的空间信息,最后在上采样的特征图上进行逐像素分类。
最后逐个像素计算softmax分类的损失函数,相当于每个像素对应一个训练样本:
MaskRCNN论文理解
卷积、池化、卷积、池化、卷积、池化、反卷积、反卷积、反卷积、

CN将传统CNN中的全连接层转化成卷积层,对应CNN网络FCN把最后三层全连接层转换成为三层卷积层。在传统的CNN结构中,前5层是卷积层,第6层和第7层分别是一个长度为4096的一维向量,第8层是长度为1000的一维向量,分别对应1000个不同类别的概率。FCN将这3层表示为卷积层,卷积核的大小 (通道数,宽,高) 分别为 (4096,1,1)、(4096,1,1)、(1000,1,1)。看上去数字上并没有什么差别,但是卷积跟全连接是不一样的概念和计算过程,使用的是之前CNN已经训练好的权值和偏置,但是不一样的在于权值和偏置是有自己的范围,属于自己的一个卷积核。因此FCN网络中所有的层都是卷积层,故称为全卷积网络。

MaskRCNN论文理解

CNN结构

CNN是固定resize成统一尺寸,每层的大小都固定。在传统的CNN结构中,前5层是卷积层,第6层和第7层分别是一个长度为4096的一维向量,第8层是长度为1000的一维向量,分别对应1000个类别的概率。FCN将这3层表示为卷积层,卷积核的大小(通道数,宽,高)分别为(4096,1,1)、(4096,1,1)、(1000,1,1)。所有的层都是卷积层,故称为全卷积网络。

MaskRCNN论文理解

FCN结构

经过5次卷积(和pooling)以后,图像的分辨率依次缩小了2,4,8,16,32倍(heatMap)。对于最后一层的输出图像,需要进行32倍的上采样,以得到原图一样的大小。
FCN是按照比例来的(第一个应该是H/2而不是H/4),最后的H/32 x W/32的就是我们要得到的最高维特征图,然后队这个图进行上采样工作,将图片还原到原来的图像大小(HxW)(1000张),但是这样的操作还原的图片仅仅是conv5中的卷积核中的特征,限于精度问题不能够很好地还原图像当中的特征,因此在这里向前迭代。把conv4中的卷积核对上一次upsampling之后的图进行反卷积补充细节(相当于一个差值过程),最后把conv3中的卷积核对刚才upsampling之后的图像进行再次反卷积补充细节,最后就完成了整个图像的还原。
然后逐个求1000张图像中,某个像素的最大分类概率,把这个概率的类作为这个像素的类。
MaskRCNN论文理解

缺点:

  • 结果不够精细,上采样结果还是比较模糊和平滑的,对图像的细节不敏感
  • 没有考虑像素之间的关系

Deconvolution

MaskRCNN论文理解
卷积层的前向传播过程就是反卷积层的反向传播过程,卷积层的反向传播过程就是反卷积层的前向传播过程
MaskRCNN论文理解

Upsampling

线性插值

  1. 单线性插值
    已知数据 (x0, y0) 与 (x1, y1),要计算 [x0, x1] 区间内某一位置 x 在直线上的y值。
    MaskRCNN论文理解
    MaskRCNN论文理解
  2. 双线性插值
    在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。
    MaskRCNN论文理解
    假如我们想得到未知函数 f 在点 P = (x, y) 的值,假设我们已知函数 f 在 Q11 = (x1, y1)、Q12 = (x1, y2), Q21 = (x2, y1) 以及 Q22 = (x2, y2) 四个点的值。最常见的情况,f就是一个像素点的像素值。
    MaskRCNN论文理解
在x方向上计算

MaskRCNN论文理解

在y方向上计算

MaskRCNN论文理解

总公式

 \  

RoIAlign中没有对坐标进行取整操作,而非整数的坐标是无法在图像这种离散数据上使用的。双线性插值通过寻找距离这个对应坐标最近的四个像素点,来计算该点的值(灰度值或者RGB值)。如果你的对应坐标是(2.5,4.5),那么最近的四个像素是(2,4)、(2,5)、(3,4),(3,5)。
若图像为灰度图像,那么ij(i,j)(i,j)点的灰度值可以通过一下公式计算:
f(i,j)=w1p1+w2p2+w3p3+w4p4f(i,j)=w_1*p_1+w_2*p_2+w_3*p_3+w_4*p_4f(i,j)=w1​∗p1​+w2​∗p2​+w3​∗p3​+w4​∗p4​;
其中,pi(i=1,2,3,4)p_i(i=1,2,3,4)pi​(i=1,2,3,4)为最近的四个像素点,wi(i=1,2,3,4)w_i(i=1,2,3,4)wi​(i=1,2,3,4)为各点相应权值。

参考文章

关于k×m×mk\times m \times mk×m×m
全卷积网络详解
全卷积网络(FCN)与图像分割
上采样,反卷积,上池化
双线性插值

思考

优秀的地方

  • 相比于Faster RCNN,提出了RoIAlign,更适合处理像素级别的分割问题;还在backbone使用了FPN,能更好处理不同尺度物体的检测。
  • 相比于FCNs,提出了预测k个m×mm\times mm×m分辨率的掩码,而不是只预测一个m×mm\times mm×m分辨率的掩码,更好的提高了精度

一些有疑问的地方,看看代码应该就能解决了 ,等有时间了看一下。

上一篇:【MaskRCNN】训练自己的数据集


下一篇:2021-09-26-关于如何把使用nxsd组件的OSB代码转化为使用JavaCallout组件的代码