Mask RCNN整体介绍及部分细节讲解

    技术2022-07-10  189

    Mask RCNN基于Faster RCNN改进,所以若有看不懂的地方可以先去看看我上篇博客Faster R-CNN整体介绍及部分细节讲解 论文全称:Mask R-CNN


    目录

    一、整体总结1. general notes2. 整体架构 二、论文细节三、RoI Pool和RoI Align


    一、整体总结

    1. general notes

    主要性能提升是因为RoIAlign(双线性插值+对齐) 用FCN在faster rcnn基础上预测了mask(每类一个FCN) 两个backbone,分别是FPN和ResNet(对应faster rcnn中的conv layers) mask分支有改进空间,且时间效率可提高 可用于实例分割、位姿估计(每个mask是one-hot的的一个关键点位置)、检测工作

    2. 整体架构

    Mask RCNN的整体架构如图所示。 首先用backbone网络处理原始图像,得到特征图feature map,同时将backbone网络输出的特征输入到RPN网络中,得到相应的锚框,此处需要注意Faster RCNN使用resnet50时,从CONV4导出特征供RPN使用,而不是直接使用完整的resnet50所生成的特征供RPN使用。得到锚框和特征图了之后,采用RoIAlign的方式,将每个锚框对应的特征图统一为单一尺寸,也就是得到每个锚框的fixed size feature map。在得到每个锚框的特征图之后,将该特征图输入到全连接层中,再分别经过reg层和cls层得到box regression,也就是锚框位置矫正和classification,也就是该锚框中物体是每一类的概率。如上所讲的部分,除了RoIAlign层之外,均和faster RCNN的结构相同,所以具体讲解可参照上篇博客Faster R-CNN整体介绍及部分细节讲解,而RoIAlign层在本篇博客的第三部分有具体讲解。 本篇论文除了RoIAlign之外,还增添了mask分支,使得该网络可以做到实例分割。mask分支的架构如下图中黑色部分所示(图中方块显示的是数据大小,箭头表示conv层、deconv层或fc层)。在mask分支中,针对每一个锚框,均生成K个mask,其中K是目标类别数,然而只有检测模块检测出的类k(当前锚框中物体是类k物体)的mask才会被输出,并且对loss有贡献,其他的mask均被丢弃。

    二、论文细节

    每个ROI(region of interest,感兴趣区域)针对每一类生成一个mask,生成方式是FCN网络,也就是在目标类别数为k的时候,每一个ROI都经过k个不同的FCN生成k个不同的mask。然而只采用检测出的类别对应的mask计算损失函数。mask的损失函数Lmask是平均交叉熵,使用的激活函数是per-pixel sigmoid。类别预测、框偏差预测用全连接层(分别对应Faster RCNN中的cls层和reg层),提取mask的空域信息用卷积。将faster RCNN中的ROI Pooling换为了ROI Align,因为ROI Align能够更好保留像素级别的信息。在Align中用x/16来代替Pooling中的 ⌊ x / 16 ⌋ \lfloor x/16\rfloor x/16。用双线性插值的方法计算每个RoI框中的4个采样点的特征值,之后用max或average聚合结果(在本文第三部分有详细讲解)backbone用于特征提取,head用于目标框分类和回归。本文选用的backbone有ResNet、ResNeXt和FPN。选用的head是Faster RCNN的head。mask branch有改进空间。FPN和ResNet的head分别如图所示(另外加入了mask分支)。 Faster RCNN使用resnet50时,从CONV4导出特征供RPN使用,这种叫做ResNet-50-C4。图中的方块代表着数据的大小,箭头代表着卷积、反卷积和全连接层,具体每个箭头对应哪个层可以推断出来(卷积保留了空域维度信息,而反卷积扩大了空域维度的信息)。超参跟随Fast/Faster RCNN架构训练: 如果一个RoIl与真值框IoU至少0.5.则为正例,否则为负例;将尺寸统一变形为短边800像素;每GPU每mini-batch训练两张图;每图N个RoI,正例:负例=1:3;C4 backbone中,N=64,FPN backbone中,N=512;8个GPU训练(mini-batch=16),总共训练160k iter;初始时lr=0.02,120k iter后,lr=0.002;weight decay=0.0001,momentum=0.9;ResNeXt时,每个GPU1张图,iter数相同,初始时lr=0.01,120k iter后,lr=0.001;RPN利用5 scales,3 aspect ratio的锚框,RPN和Mask RCNN的backbone相同,可共享参数,然而本文中为了更好地做消融实验,除了特殊说明时,RPN单独训练且不和Mask RCNN共享特征。Inference: 测试时,C4 backbone的候选框数是300,FPN backbone的候选框数是1000。 实验1:实例分割 利用Mask IoU计算AP、AP50、AP75、APs、APm和APl 训练时采用80k训练集数据和35k验证集数据组成trainval35k进行训练,测试时使用5k的验证集(minival)进行测试。同时还在test-dev集上测试了结果。实验2:消融实验 将网络中一个部分换为其他的结构,查看哪一个部分对网络影响最大。实验3:候选框检测实验4:位姿估计 将位姿中关键点位置转化为one-hot mask(也就是每个mask中有1个点被当作前景,其他都是背景) 为K个关键点类型预测K个mask 在 m 2 m^2 m2个softmax输出上最小化交叉熵函数(图像大小为m*m)。 FPN更改后结构: 训练:trainval35k,为了避免过拟合,从[640,800]像素尺寸随机采样训练,总共90k iters。初始lr=0.02,60k iters后变为0.002,80k iters后变为0.0002。 测试:只用800像素尺寸测试

    三、RoI Pool和RoI Align

    RoIPool和RoIAlign都用于将候选框对应的特征图找出,之后将不同大小比例特征图处理为固定大小,从而能输入到后续大小固定的网络中。其中RoIPool和RoIAlign的操作流程分别如图(图中的VGG16的feat_stride=32,也就是经过网络层后图片缩小为原图的1/32)。 第一步是将候选框对应的特征图找出。由于经过VGG16后,特征图的大小变为了原始图像的1/32,所以要找原始图像中的候选框对应的特征图,按照理想状况来说,直接将原始图像上(x,y,w,h)锚框缩小32倍,也就是变为(x/32, y/32, w/32, h/32)就是该锚框在特征图上的位置了。

    然而现实情况是这四个参数不一定能够被32整除,所以在RoIPool中,直接将不能整除的部分舍去了,也就是在锚框大小665/32=20.78的时候,直接将小数舍去变为整数,再用舍去小数后的 ( ⌊ x / 32 ⌋ , ⌊ y / 32 ⌋ , ⌊ w / 32 ⌋ , ⌊ h / 32 ⌋ ) (\lfloor x/32 \rfloor, \lfloor y/32 \rfloor, \lfloor w/32 \rfloor, \lfloor h/32 \rfloor ) (x/32,y/32,w/32,h/32)来作为该锚框所对应的特征图。

    然而这一步的量化便会损失一些信息,所以RoIAlign对此做了一些改进,在RoIAlign中并没有将小数取整,而是仍然保留了小数位置 ( x / 32 , y / 32 , w / 32 , h / 32 ) (x/32, y/32, w/32, h/32) (x/32,y/32,w/32,h/32)来作为该锚框对应的特征图。

    第二步是将锚框对应的特征图统一处理为固定大小,上图中是将特征图处理为了7*7大小。按照理想状况来说,为了将上一步得到的x*y的特征图变为大小X*Y的统一尺寸特征图,将这x*y的特征图分为X*Y个块,每一块的大小为(x/X)*(y/Y),之后再分别取这X*Y个块中每个块的平均值或最大值作为该块的特征图输出即可。然而现实情况是,x和y不一定能被X和Y整除,所以又涉及到了上一步中出现过的量化问题。

    在RoIPool中,如图所示,在将20*20特征图变换为7*7特征图时,20/7=2.86,每一块的大小并不是整数,所以将每一块的大小进一步量化,也就是使得每一块的大小变为了2*2,之后再取这2*2大小的小块中的最大值作为该块的输出,再将7*7个这样的小块的输出拼接起来,就将原始20*20的特征图变为了7*7的特征图。然而这样的量化也会损失一些信息,如图所示,红框是锚框对应的特征图的真实大小,而做如此处理后,只利用了该框中绿色部分的信息。

    所以RoIAlign对其做了改进。在上一步中,RoIAlign将 ( x / 32 , y / 32 , w / 32 , h / 32 ) (x/32, y/32, w/32, h/32) (x/32,y/32,w/32,h/32)的位置作为特征图中锚框对应位置,该位置的大小是20.78*20.78。下图中的整个黑框,就是该锚框的特征图对应的位置,可以看出,该特征图并没有严丝合缝的压住原始特征图的每个像素。下图以将特征图处理为2*2大小的固定大小特征图为例,展示了RoIAlign的第二个步骤。首先将锚框的特征图分为2*2个小块,每个小块的大小不一定是整数,这样就不能直接用小块中的值的最大值或者平均值作为小块的输出。所以作者将每个小块又分为了4个小块,将这四个小块的中心作为采样点,也就是在每个小块中选取了4个采样点,将这4个采样点的特征值的平均或最大,作为该小块的输出,组成最终输出的2*2大小的固定大小特征图。然而这4个采样点又不是特征图中的已有值的点,所以为了求得这4个采样点的特征值,作者采用了双线性插值的方法,如图所示,用箭头的开始位置的四个点的特征值,双线性插值出采样点的特征值。这样就能够在不量化的情况下得到固定大小的特征图了。

    Processed: 0.022, SQL: 9