MSRA instance-aware semantic segmentation的思路线

最近从semantic segmentation坑又跳入了instance-aware semantic segmentation坑,发现在后面这个坑里挖掘的时候一个叫做Jifeng Dai的来自MSRA的人非常高产,连着刷新MSCOCO PASCAL等数据集成为state-of-the-art,所以我就想把这个人相关的几篇paper整理一下,其中的思路发展非常有意思~一共涉及到的思路相关的几篇,按照发表顺序:
  • Instace-sensitive Fully Convolutional Networks.ECCV 2016【2016.3月上传到arxiv】
  • R-FCN:Object Detection via Region-based Fully Convolutional Networks.NIPS 20162016.7月上传到arxiv
  • Fully Convolutional Instance-aware Semantic Segmentation.xxxx 2017【2016年11月上传到arxiv,MSCOCO2016的第一名】

一、InstaceFCNInstace-sensitive Fully Convolutional Networks.ECCV 2016

先来说这篇工作是针对什么问题:FCN网络只能产生semantic segmentation的结果,也就是说同样的物体类别,它不会区分物体实例【可以理解为两个人挨在一起的话,FCN输出的mask标记的都是people,但是instance-aware要求区分出来这两个人各自。我认为instance semantic segmentation =semantic  segmentation + object detection】之前的instance semantic segmentation方法通常诉诸于现成的分割proposal方法,本文打算一次性解决。

FCN为每一个物体类生成一个score map,map上每个pixel代表一个分类器(是不是这类物体),本文的方法为每一个物体类生成一系列instance-sensitive的score maps,map上每个pixel代表一个分类器(是不是在此类的一个物体实例的某个相对位置上)


1.网络结构

首先来看网络结构:


Image用VGG16的结构得到conv feature map,这里做了改动,把pool4的stride改为1,conv5的三个卷积层的filter都用dilated的,所以一个W*H大小的image会得到W/8*H/8大小的conv feature map。接着这个conv feature map走了两个并行的分支:一个分支负责估计segment instance,另一个分支负责对这个instance进行打分。

分支1:先经过1*1*512的卷积层生成W/8*H/8*512的输出【降维】,然后经过3*3*(k*k)的卷积层生成一系列Instance-sensitive score maps,也就是说一共有k*k个大小为W/8*H/8的score map喔~然后经过assembling模块,产生score map上m*m大小的sliding window内的object instance。

分支2:先经过3*3*512的卷积层生成W/8*H/8*512的输出,然后经过1*1*(k*k)的卷积层输出objectness score map,map上的每一个分数是以这个像素为中心的sliding window是否有一个实例。【这个objectness score map的大小是多少啊???

  • Instance-sensitive score maps
初衷是想表达出位置信息,所以想到用一个正方形sliding window上的k*k的规则网格来定义相对位置。所以就用卷积网路生成k*k个score maps
  • Instance assembling module
上面的Instance-sensitive score maps还没有产生object instance,我们可以用一个简单的方法来assemble instances:在score maps上滑动一个分辨率为m*m的window,每个大小为m/k*m/k的子窗口直接从对应score map上相同的子窗口copy数值【与下面第二篇文章比,下面的paper里每每个子窗口最后就得到一个值(准确的说是C+1长的向量),它完成的是从一个RoI即w*h*(k*k)*(C+1)的score map到k*k*(C+1)的score map的映射;本文完成的是一个sliding window即m*m*(k*k)的score map到m*m的window的映射】,然后这k*k个子窗口按照相对位置排列成m*m的窗口,这就是从这个sliding window里assemble出的instance。



2.有一些疑问

Instance-sensitive score maps的大小是W/8*H/8的,网络是按照每个m*m大小的sliding window来生成它的segment instance和instance score的,那么整个score map以及整个image【W*H啊啊啊】范围内的segmentation结果是怎么得到的呢???? 


我想一个合理的解释可能是:

这里的输入sliding window并不是由proposal method产生的,而是论文作者指定的:


1 假设k*k个instance score maps大小为W/8*H/8(同样的,scoring分支的objectness score map的大小也是W/8*H/8

2 instance score maps上的每个pixel都产生一个以它为中心的sliding window,其大小为m*m(论文里m=21)

3 每个pixel,假设是(i,j)坐标位置的,根据它的sliding window(已经是投影在feature map上的sliding window了,这个需要注意,而不是从原图的sliding window投影到feature map上的),输出其instance-level的mask。


4 那么在objectness score map上对应的(i,j)位置的值,就是这个pixel的instance-level mask的objectness score【由此可以看出这个score不是class-specific的,它只是指出是否是物体】。


5 一共有W/8*H/8个mask和对应的object score,最后通过非极大值抑制方法留下那些合理的

但是楼主还有一个问题没有解决,最后得到的是在W/8*H/8个mask尺度上的mask,本篇paper也没说怎么变成整张image的mask呀,难道像DeepMask一样就用一个简单的双线性内插上采样??



--------------------------------------------------------我是分割线喵~------------------------------------------------------------

二、R-FCNR-FCN:Object Detection via Region-based Fully Convolutional Networks.NIPS 2016


先来说这篇工作是针对什么问题:首先,目前基于region proposal的物体检测框架存在一个问题就是会有subnetwork的重复计算,什么意思呢?我们回忆一下Faster RCNN,整张image计算conv feature map,然后通过ROI pooling把每一个region proposal变成一个大小固定的feature map,再经过若干次fc层得到结果,此时subnetwork指的就是这些分成层。假设一张image有N个region proposal,那么subnetwork的计算也会有N次,本文的想法就是丢掉这些fc层,使得所有的计算都可以由region proposal共享【博主一度不是特别理解这个共享的意义,但是最近突然开窍了,说一下我的看法。先说有fc层的情况下不能共享是因为,每个region proposal都得自己计算,但是卷积就不一样了:一张image只需要计算一次卷积流程得到一个conv map,然后对应不同region proposal,只需要“找到”它对应的conv map的位置就好了呀,没有多余的计算】。

对于上面的问题,一些解决方案是在两个卷积层集之间加一个ROI pooling层,前面的卷积共享,后面的不共享。本文认为这种做法是为了消除一对矛盾:分类时希望对位置不敏感【卷积就是不敏感的】,检测时又希望是translation-variant的【ROI pooling的作用就在此。顺便说一句fc层也是为了达到这个效果】。但是这样做呢,也牺牲了训练和测试的效率,因为引入了很多region-wise层。

所以为了解决这个问题,本文最大的亮点来了:position-sensitive score maps和position-sensitive RoI pooling


1.网络结构

首先来看网络结构:




Image先经过FCN生成conv feature map【本文选择的是ResNet-101,去掉最后的fc和average pooling层,然后接一个1*1的1024维的卷积降维,所以conv feature map的大小是W/8*H/8*1024】,这个feature map兵分两路:

(1)经过3*3和1*1卷积层生成ROI【也就是Faster R-CNNhttp://blog.csdn.net/u011718701/article/details/53758927里的RPN网络啦~】

(2)经过一系列特殊的卷积层生成position-sensitive score map集合,一共有k*k个score map,每个score map都是C+1维的(C是物体类别,1代表背景类),代表着一个相对位置上的score结果(比如物体的左上方啊,右方啊之类的)。然后结合RPN生成的ROI经过position-sensitive的ROI pooling层,生成这个ROI的检测结果。所谓position-sensitive pooling就是说,pooling只在某个位置的(C+1)维的score map中进行,然后放在对应的位置上。【对照结构图来看就是,橘色的score map内部进行pooling,跟其他颜色的没有关系】,还有更数学性的解释:

把每个w*h大小的ROI分成k*k个bin,每个bin的大小是w/k*h/k*(C+1)的,在第(i,j)个bin里,定义一个只在这个bin里进行的position-sensitive RoI pooling操作,本文用的是average pooling啦~即第(i,j)个bin的输出值是这个bin里所有位置score map的均值。对照图,每个颜色代表一个(i,j)bin,这样下来我们就得到了k*k个按照位置排列的通道数为C+1的score map啦~然后这k*k个scores就要来投票啦,本文的投票方式就是取均值,得到C+1维的向量,然后softmax处理一下,那么得到的就是这个ROI是各类别的概率了~


2.Bounding box regression

bbox回归又是物体检测框架下一个必不可少的环节,我们来看本文的处理方式:


前面部分和主网络都一样,从那个conv feature map开始。和k*k*(C+1)维的score maps并行,接上一个k*k*4维的卷积层,也就是说得到的maps一共是k*k个,每个map是4维的【因为是bbox嘛,中心坐标和长度宽度,所以是4】。然后每个w*h大小的ROI接position-sensitive RoI pooling层,那么每个RoI就得到了4*k*k的向量呀。再通过取均值的投票方式,得到4维的向量了,也就是bbox regression的结果~

3.一些细节

ResNet-101一共有5个conv block,原来的网络,一张W*H的image会输出W/32*H/32的conv feature map,现在本文做了改动,把conv5层第一个层的stride变成1,所有conv5层的卷积都用dilated,这样conv feature map的大小就变成了W/16*H/16。


还有就是,RPN网络生成的RoI的尺寸可是在原image上的,所以它需要投影到大小为W/16*H/16的score maps上,bbox regression的结果是基于尺寸W/16*H/16的,所以它需要反投影到原image上。【大家不要被它的网络结构图蒙蔽了.....feature  map、score map的大小它画的跟原image一样,这太过分了。。。根本就不一样啊。。。】

------------------------------------------------------------我是分割线喵~--------------------------------------------------------------------------

三、FCIS【Fully Convolutional Instance-aware Semantic Segmentation.xxxx 2017】

据作者说,这是第一篇fully sonvolutional end-to-end的解决方案来完成instance-aware segmentation任务的,也是MSCOCO2016数据集上的第一名~


是基于InstaceFCN【Instace-sensitive Fully Convolutional Networks.ECCV 2016这篇的工作。作者指出InstanceFCN只是用来产生mask proposal,不能区分semantic类别,而且需要一个downstream网络进行分类,也就是说它的mask proposal和classification两个子任务是分离的,因此不是end-to-end的方法。还有就是它操作的是正方的、固定大小的sliding window,所以找不同尺寸物体的时候要用image pyramid scanning,非常耗时。本文在InstanceFCN的基础上做改进,一方面用box proposal代替sliding window,另一方面把mask proposal和classification网络融合起来~


1.网络结构

首先来看网络结构:


重点关注两个改进:

  • position-sensitive inside/outside score maps
先说说这个改进的来源是什么:在FCN中,我们训练一个classifier来预测一个像素属于某个物体类的似然得分,它是平移不变而且无法区分单个物体实例的。比如同样的一个像素,它既可以是物体1的前景也可以是相邻物体2的背景,两个物体属于同一类,那么FCN产生的每个类只有一个score,是没有办法区分这两种情况的。
然后有了InstanceFCN的工作,它提出了positive-sensitive score map,每个score表示 一个像素在某个相对位置上属于某个物体实例的似然。所以本文也要采用position-sensitive score maps,只不过加了个在物体实例里面还是外面,目的是想引入一点context信息。
  • joint mask prediction and classification
InstanceFCN的objectness分类子网络只能够给出这个sliding window里的instance是物体还是背景,要完成instance-aware semantic segmentation还得用一个分离的downstream网络把这个sliding window里的mask proposal分成具体的物体类别,很麻烦~而且像SDS、Hypercolumn、CFM、MNC、MultiPathNet这些instance semantic segmentation方法都是用两个独立的网络来完成mask prediction和classification,不过作者认为分离网络的设计不能充分利用两个任务之间紧密的联系呀~所以本文作者希望两个子任务能够一起利用score maps。想法是酱紫的:

从conv feature map产生两组k*k个的score maps,每个score map是C+1维的【InstanceFCN里是一组k*k个的score map,而且是不区分类的,所以每个score map是1维的。R-FCN里也是一组 k*k个的score map,不过每个score map是C+1维的】,每个score表示 一个像素在某个相对位置上属于某个类的某个物体实例且在物体边界内的似然或者 一个像素在某个相对位置上属于某个类的某个物体实例且在物体边界外的似然【所以是两组嘛~】

从这2*(k*k)*(C+1)维的inside/outside score maps中,给定一个RoI假设是w*h大小的哈【由RPN网络输出的是在原image上的,所以需要投影到score map上】,我们先在 inside/outside score  maps上找到它的对应部分,然后把它划分成k*k个子窗口 ,每个大小为w/k*h/k的子窗口直接从对应score maps上相同的子窗口copy数值 ,然后这k*k个子窗口按照相对位置排列成w*h的窗口,得到的是两组(C+1)维的score maps,分别是inside和outside的score map。【比如想要生成inside score map左上角位置的,就挑第一组(k*k)*(C+1)维的score maps的第1个(C+1)维的score map复制过来;想要生成inside score map右上角位置的,就挑第一组(k*k)*(C+1)维的score maps的第3个(C+1)维的score map复制过来,以此类推......

现在我们有了2*(C+1)维的score maps,开始对每一类进行mask prediction和classification,比如第c类,我们找出它的两个score maps,然后:
(1)Mask prediction:现在score maps上每个像素位置有两个分数:inside和outside的,inside就代表是这个物体实例的前景了。这两个值softmax处理一下【其实就是变成概率意义】,得到 RoI里 每个像素属于c类的这个物体的前景部分的概率
(2)Mask classification: 现在score maps上每个像素位置有两个分数:inside和outside的,inside就代表是这个物体实例的前景了。这两个值取max,得到每个像素属于c类物体的似然【max操作的意义是,RoI里的每个像素都应该为整个RoI的类别做出贡献,不管它在物体里面还是外面,所以酱紫就相当于融合context信息】。整个RoI的分类结果就是对所有像素位置取均值,得到这个RoI是c类物体的似然

最后我们得到了什么呢?→→→对应于一个RoI的(C+1)维mask prediction【w*h大小】来表示这个RoI内每个像素属于每个类物体前景的概率和 (C+1)维mask classification【1个得分】表示 这个RoI属于每个类的似然


再来整体说说几个网络结构的细节:
(1)共享的卷积网的结构采用ResNet-101,做了两点改变:a.把最后的fc层去掉;b.把conv5 block的第一个卷积层的stride设为1,所有conv5 block的卷积层的filter都用dilation=2;c.加一个1*1的卷积层把feature map维度降到1024维。所以一张W*H*C的image经过这个网络输出的conv feature map是W/16*H/16*1024维,也就是conv5输出的feature map。
(2)为了与MNC算法对比,RPN网络的利用方式也和MNC一样:从conv4的W/16*H/16*1024维feature map出发,接一个3*3的卷积层降维,然后接两个并行的1*1卷积层一个输出4维的box location,一个输出objectness score。【MNC那篇文章并没有说从ResNet-101的第几个conv block,我也很纳闷为啥本文是从conv4开始??】
(3)conv5的feature map经过1*1的卷积层生成2*k*k*(C+1)维的score maps,大小是W/16*H/16哒~此时就要把RPN输出的RoI投影到这个与原图比小了16倍的score maps上,输出它的mask prediction和mask classification结果。
(4)conv5的feature map同时还走了另外一条路,经过1*1的卷积层生成4*k*k维的map,来进一步生成bbox regression的结果。

2.Bounding box regression

但凡是自己产生RoI的,bbox回归又是必不可少的:

前面部分和主网络都一样,从那个conv feature map开始。和2*k*k*(C+1)维的score maps并行,接上一个1*1*4*(k*k)的卷积层,输出维度是4*(k*k)。然后每个w*h大小的RoI接position-sensitive RoI pooling层,那么每个RoI就得到了4*k*k的向量呀。再通过取均值的投票方式,得到4维的向量了,也就是这个RoI进行bbox regression的结果~

3.Inference and Training

Inference:对一张image,先从RPN生成的RoI里面选出分数最高的300个,它们经过bbox regression分支,产生另外300个RoI,所以一共是600个RoI。对每一个RoI,得到它在各个类别的classification score和前景mask。用IoU阈值为0.3的非极大值抑制过滤掉高度重叠的RoIs,剩下的RoI就被分类为有最高classification score的类别呗~它们的前景mask通过mask voting的方式来获取:比如对某个RoI,我们从600个RoI中找到与它的IoU大于0.5的那些,每一个RoI在这个RoI类别的mask进行逐像素加权平均,权值是各自RoI在该类的classification score。平均后的mask再二值化作为输出。【二值化的阈值怎么确定的咯?cross-validation?】

Training:先说RoI的正负标签怎么确定,如果一个RoI与离它最近的ground-truth的IoU大于0.5就是正的【也就是说是物体】,否则就是负的。每个RoI有三个loss项目:softmax classification loss over C+1个类别;softmax segmentation loss overground-truth类别的前景mask;bbox regression loss。后面两个loss仅仅针对标签为正的RoI计算诶。训练图像最短边规定为600像素。


2.Bounding box regression

bbox回归又是物体检测框架下一个必不可少的环节,我们来看本文的处理方式:

前面部分和主网络都一样,从那个conv feature map开始。和k*k*(C+1)维的score maps并行,接上一个k*k*4维的卷积层,也就是说得到的maps一共是k*k个,每个map是4维的【因为是bbox嘛,中心坐标和长度宽度,所以是4】。然后每个w*h大小的ROI接position-sensitive RoI pooling层,那么每个RoI就得到了4*k*k的向量呀。再通过取均值的投票方式,得到4维的向量了,也就是bbox regression的结果

猜你喜欢

转载自blog.csdn.net/Bruce_0712/article/details/80292892