Mask R-CNN 学习笔记

Mask R-CNN是一个实例分割(Instance segmentation)算法。实例分割(Instance segmentation)和图像分类、目标检测、语义分割(Semantic segmentation)的区别与联系如下:


算法的框架:

由上图可以额看到:

  1. MaskR-CNN的网络结构是FasterR-CNN的扩展。
  2. MaskR-CNN在有效检测目标的同时输出高质量的实例分割mask。
  3. 使用了RolAlign代替了RoIPooling。RoIPooling使用取整量化,导致特征图RoI映射回原图RoI时空间不对齐明显,造成误差(量化误差);RolAlign不使用取整量化而是采用双线性插值,完成像素级的对齐。
  4. FasterR-CNN为每个候选对象ROI提供两个输出分支,一个类标签,一个边界框偏移量。而MaskR-CNN并行添加了第三个分割mask的分支,mask分支是应用到每一个ROI上的一个小的FCN(Fully Convolutional Network),以pix2pix(点到点)的方式预测分割mask。

算法的细化结构:

细化结构:

算法步骤:

  • 输入一张预处理后的图片(1024x1024x3)。
  • 送入一个已经预训练好的卷积网络(ResNeXt等)。该ResNet网络分为5个stage,但是没有利用其中的Stage1即P1的特征,官方的说法是因为P1对应的feature map比较大计算耗时所以弃用。相反,在Stage5即P5的基础上进行了下采样得到P6,所以利用了[P2,P3,P4,P5,P6]五个不同尺度的feature map。
  • 为了获得多尺度信息,利用FPN特征金字塔分别对[P5,P4,P3]的feature map进行2倍上采样,与Pi-1的feature map 进行融合,结合方式就是做像素间的加法。FPN可以参考:https://blog.csdn.net/xiamentingtao/article/details/78598027
  • 对这五个不同尺度feature map中的每一点设定K个ROI,从而获得多个候选ROI
  • 将这些候选的ROI送入RPN网络进行二值分类(前景或背景)和BB回归,NMS非最大值抑制操作后保留将近共2000个RoI。RPN可以参考:https://blog.csdn.net/qq_40755643/article/details/89243690
  • 由于步长stride的不同,分开分别对[P2 P3 P4 P5]四个不同尺度的feature map对应的stride进行RoIAlign操作。
  • 将经过RoIAlign操作产生的RoI进行Concat连接,随即网络分为三部分:全连接预测类别class、全连接预测矩形框box、全卷积预测像素分割mask。
  • 最后,对这些ROI进行分类(N+1类别分类)、B-Box回归和MASK生成(在每一个ROI里面进行FCN操作)。

FPN:

把高层特征做2倍上采样(最邻近上采样法,可以参考反卷积),然后将其和对应的前一层特征结合(前一层要经过1 * 1的卷积核才能用,目的是改变channels,应该是要和后一层的channels相同),结合方式就是做像素间的加法。重复迭代该过程,直至生成最精细的特征图。


RoIAlign

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

对于RoIpooling,经过两个量化过程:

  1. 从roi proposal到feature map的映射过程。方法是[x/32],这里x是原始roi的坐标值,而[ ]代表四舍五入。
  2. 从feature map划分成7*7的bin,每个bin使用max pooling。

例如:[665/32 x 665/32]= [20.78 x 20.78],结果是浮点数,含有小数,但是我们的像素值可没有小数,那么作者就对其进行了量化操作(即取整操作),即其结果变为[20 x 20],在这里引入了第一次的量化误差。我们需要将[20 x 20]的ROI映射成7 x 7的ROI feature,其结果是 [20 /7 x 20/7] = [2.86 x 2.86],同样是浮点数,我们采取同样的操作对其进行取整吧,在这里引入了第二次量化误差。

对于RoIAlign

双线性插值法:

假设我们已知函数 f 在 Q11 = (x1, y1)、Q12 = (x1, y2), Q21 = (x2, y1) 以及 Q22 = (x2, y2) 四个点的值,想得到未知函数 f 在点 P = (x, y) 的值。最常见的情况,f就是一个像素点的像素值

第一步:X方向的线性插值,在Q12,Q22中插入蓝色点R2,Q11,Q21中插入蓝色点R1:

第二步 :Y方向的线性插值 ,通过第一步计算出的R1与R2在y方向上插值计算出P点:

所以双线性插值的结果:

由于图像双线性插值只会用相邻的4个点,因此上述公式的分母都是1。

综上:已知p的坐标,求p点的像素值。双线性插值通过寻找距离p坐标最近的四个像素点,来计算该点的值(灰度值或者RGB值)。如果p对应坐标是(2.5,4.5),那么最近的四个像素是(2,4)、(2,5)、(3,4),(3,5)。 

为了得到为了得到固定大小(7X7)的feature map,ROIAlign技术并没有使用量化操作,即我们不想引入量化误差,解决思路是使用“双线性插值”算法。比如665 / 32 = 20.78,我们就用20.78,不用什么20来替代它,比如20.78 / 7 = 2.97,我们就用2.97,而不用2来代替它。

蓝色的虚线框表示卷积后获得的feature map

黑色实线框表示ROI feature

最后需要输出的大小是2x2,那么我们就利用双线性插值来估计这些蓝点(虚拟坐标点,又称双线性插值的网格点)处所对应的像素值,最后得到相应的输出。这些蓝点是2x2Cell中的随机采样的普通点,作者指出,这些采样点的个数和位置不会对性能产生很大的影响,你也可以用其它的方法获得。

每一个橘红色的区域里面进行max pooling或者average pooling操作,获得最终2x2的输出结果。

也就是:roi映射到feature map后,不再进行四舍五入。然后将候选区域分割成k x k个单元, 在每个单元中计算固定四个坐标位置,用双线性内插的方法计算出这四个位置的值,然后进行最大池化操作。

对上述步骤的第三点作一些说明:这个固定位置是指在每一个矩形单元(bin)中按照比例确定的相对位置。比如,如果采样点数是1,那么就是这个单元的中心点。如果采样点数是4,那么就是把这个单元平均分割成四个小方块以后它们分别的中心点。显然这些采样点的坐标通常是浮点数,所以需要使用插值的方法得到它的像素值。在相关实验中,作者发现将采样点设为4会获得最佳性能,甚至直接设为1在性能上也相差无几。 


Head Architecture 头部结构

如上图所示,为了产生对应的Mask,文中提出了两种架构,即左边的Faster R-CNN/ResNet和右边的Faster R-CNN/FPN

左边的架构,我们的backbone使用的是预训练好的ResNet,使用了ResNet倒数第4层的网络。输入的ROI首先获得7x7x1024的ROI feature,然后将其升维到2048个通道(这里修改了原始的ResNet网络架构),然后有两个分支,上面的分支负责分类和回归,下面的分支负责生成对应的mask。由于前面进行了多次卷积和池化,减小了对应的分辨率,mask分支开始利用反卷积进行分辨率的提升,同时减少通道的个数,变为14x14x256,最后输出了14x14x80的mask模板。

右边的框架,使用到的backbone是FPN网络,这是一个新的网络,通过输入单一尺度的图片,最后可以对应的特征金字塔。该网络可以在一定程度上面提高检测的精度,当前很多的方法都用到了它。由于FPN网络已经包含了res5,可以更加高效的使用特征,因此这里使用了较少的filters。该架构也分为两个分支,作用于前者相同,但是分类分支和mask分支和前者相比有很大的区别。可能是因为FPN网络可以在不同尺度的特征上面获得许多有用信息,因此分类时使用了更少的滤波器。而mask分支中进行了多次卷积操作,首先将ROI变化为14x14x256的feature,然后进行了4次相同的操作(不清楚这里的原理),然后进行反卷积操作,最后输出28x28x80的mask。即输出了更大的mask,与前者相比可以获得更细致的mask


Equivariance 等变化

Equivariance 指随着输入的变化输出也会发生变化。

即全卷积特征(Faster R-CNN网络)和图像的变换具有同变形,即随着图像的变换,全卷积的特征也会发生对应的变化。

ROIAlign操作保持了ROI变换前后的同变性。

 


Loss

Mask R-CNN的损失函数为:

损失函数为分类误差+检测误差+分割误差,分类误差和检测(回归)误差是Faster R-CNN中的,分割误差为Mask R-CNN中新加的。

对于每个MxM大小的ROI区域,mask分支有KxMxM维的输出(K是指类别数量)。对于每一个像素,都是用sigmod函数求二值交叉熵,也即对每个像素都进行逻辑回归,得到平均的二值交叉熵误差Lmask。通过引入预测K个输出的机制,允许每个类都生成独立的mask,以避免类间竞争,这样就能解耦mask和种类预测。
对于每一个ROI区域,如果检测得到属于哪一个分类,就只使用该类的交叉熵误差进行计算,也即对于一个ROI区域中KxMxM的输出,真正有用的只是某个类别的MxM的输出。如下图所示:

例如目前有3个分类:猫、狗、人,检测得到当前ROI属于“人”这一类,那么所使用的Lmask为“人”这一分支的mask。


Train

这里其实跟Faster R-CNN基本一致,IOU > 0.5的是正样本,并且Lmask ,只在正样本的时候才计算,图像变换到短边 800, 正负样本比例 1:3 , RPN采用5个scale以及3个aspect ratio。

inference细节

采用ResNet作为backbone的Mask R-CNN产生300个候选区域进行分类回归,采用FPN方法的生成1000个候选区域进行分类回归,然后进行非极大值抑制操作,** 最后检测分数前100的区域进行mask检测**,这里没有使用跟训练一样的并行操作,作者解释说是可以提高精度和效率,然后mask分支可以预测k个类别的mask,但是这里根据分类的结果,选取对应的第k个类别,得到对应的mask后,再resize到ROI的大小, 然后利用阈值0.5进行二值化即可。(这里由于resize需要插值操作,所以需要再次进行二值化,m的大小可以参考上图,mask最后并不是ROI大小,而是一个相对较小的图, 所以需要进行resize操作。)未完!
 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值