R-FCN是对于Faster RCNN模型的改进,也是two stage model。同样也包括RPN模块和Fast RCNN模块,R-FCN所作出的主要改进就是ROI Pooling的操作。
R-FCN:object detection via region-based fully convolutional neural networks
NIPS2016 inspired by an intern form Tsinghua University in MSRA
considerable adv.相当的,非常的 considerate adj.考虑周到的,体贴的
candidate box候选框
一、摘要:
fast R-CNN、faster R-CNN 都是region-based detectors,先通过selective search算法或者region proposal network产生一些region proposals,再分别将这些region proposals对应的feature maps patch分别送入per-region subnetwork,由于对于每一张input image将会产生大量的region proposals,而detector是对于每个region proposal进行预测,故这样的过程会带来很大计算量,在训练阶段和测试阶段都会消耗大量时间。R-FCN同样是region-based object detection method,但是与fast R-CNN、faster R-CNN不同,R-FCN中region-based detector是一个全卷积网络,在整张图片上进行的是共享计算。为了实现这一目标,本文提出position-sensitive score maps 位置敏感分数图 to address a dilemma between 图像分类任务中的translation-invariance平移不变性 and 物体检测任务中的translation-variance。由于R-FCN中使用的还是全卷积结构,故可以使用fully convolutional neural network backbone(such as Resnet,Resnet50,Resnet101)。
Model | Year | Test dataset:VOC2007 | |
mAP | Detection speed(FPS) | ||
R-FCN(train with Resnet101) | NIPS2016 | 83.6% | 5.88(170ms per image) |
简介
之前用于object detection都是two-stage method,如fast R-CNN、SPPnet、faster R-CNN,由ROI pooling(region of interest pooling)层将个网络模型分成两个部分subnetworks,
①一个共享的fully convolutional neural networks,as the first subnetwork,这一部分通常用来产生region proposals,如fast R-CNN中的selective search算法或者faster R-CNN 中的RPN,或简单理解为是特征提取网络,也就是普通CNN分类网络中的卷积部分,用来提取共享特征,对于一张输入图片中的所有region of interest/region proposal都在最后一张feature map上提取特征,最后的feature map是所有region proposals共享的一张input image也只用前向传播一次就可以得到所有region proposal的特征块——通常整合成feature vector; ①中的feature extraction network使用的是全卷积结构,
②ROI pooling operation;
③ROI-wise subnetwork that does not share computation,卷积神经网络相比于全连接层的特征支持在于其权值共享,以对每个region proposal进行ROI pooling之后的fix-size region proposal(送入detector的这个proposal是原始图片上候选框所对应的一小块特征图),这里所说的共享计算应该并不是说ROI pooling之后的detector部分是全卷积网络,而是想说detector对于每个region proposal是单独predict的,就是对每个ROI单独地进行classification和regression,或者简单理解为:对于一张图片的多个region proposals,需要多次前向计算才能得到detection结果,并没有共享计算。
上述object detection的basic architecture源于image classification的state-of-the-art networks,如Resnet、GoogLenet(GoogLenet inception V3)采用的结构都是:fully convolutional network-flatten-fully connected,且fully connected layer只存在于最后一层分类层,当然,对于VGGnet则不是只有最后一层是全连接层,但是用于object detection中的网络都是flatten操作之前的全卷积网络,通常在训练时,是直接使用base network在Imagenet数据集上训练得到的权值参数作为初始权值,再进行fine-tune操作。Resnet、GoogLenet的分类accuracy非常高,然而,很自然的想法,将这些经典分类网络直接用于object detection,注意:这里用于object detection的网络都是卷积结构,并不使用全连接结构,以实现全卷积网络,源自于经典分类网络结构的object detection architecture:①全卷积网络(从input images到flatten操作之前的倒数第二层卷积层)用于提取特征,②即将最后一层卷积层之前的一个max pooling层改成ROI pooling,将最后一层卷积层的输出通道数改成(num_classes+4),则将会得到considerably inferior detection accuracy——相当低的检测准确率。这样做,是使得ROI-wise的detector只有一层卷积层,加快了检测速度,却牺牲了检测精度。为了解决这一问题,在Resnet-CVPR2016-paper中,将Faster R-CNN detector的ROI pooling layer放在Resnet(这里指的是去掉最后一层全连接层只剩下全卷积网络结构的Resnet)的两组(two set of)卷积层之间,这一操作被称为unnaturally是因为它不像classic classification network一样,只留作最后一层用于classification,这样一来,ROI-wise detector subnetwork层数更深,提高了检测accuracy,但是由于每个ROI是unshared computation,非共享计算部分的网络层数加深,会大大地增加计算量,从而降低检测速度。(深度学习中很多问题都是speed和accuracy之间的trade-off)
之所以object detector network的设计与经典分类网络结构不同,是由于在image classification task中,是需要模型存在translation invariance,而在object detection task中,需要模型存在translation variance。原因如下:①image-level classification task更偏向于translation invariance——在一幅图像中对物体进行平移shift应该对分类任务的结果没有影响;从深度卷积神经网络在imagenet分类数据集上的性能来看,deep (fully) convolutional architecture是具有很强的translation invariance性质,而且似乎越深的神经网络,其translation invariance性质越好;②object-level detection task更需要localization representation,这样的特征表达在一定程度上是translation-variant的。例如,在一个candidate box中对object进行平移,是会对candidate box的分类和回归结果造成影响的。假设在image classification network中,更深的神经网络对于translation变换是更不敏感的,故而Resnet论文中的detection pipeline将ROI pooling layers insert到卷积层中间,由于ROI pooling是一种position-specific的特定位置操作,故而使前面若干层卷积神经网络带来的translation invariance大幅减少了,而由于对ROI pooling之后的卷积层的输入是每个ROI feature patch,故而输出的预测结果一定是translation-variant。但是,这样的设计使region-wise layers的层数变多,牺牲了训练和测试时的efficiency,使训练和测试计算量变大,speed变慢。
本文提出的R-FCN:region based fully convolutional network for object detection。整体框架利用FCN,为了将translation variance加入FCN,we construct a set of position-sensitive score maps by using a bank of specialized convolutional layers as the FCN output。Each of the score maps encodes the position information with respect to a relative spatial position(eg.object的左边),在FCN的最顶端。
two stage detector中最早实现end-to-end使用深度学习模型实现物体检测的是faster RCNN。faster RCNN模型可以根据ROI Pooling layer分成两个部分,ROI Pooling之前的backbone网络,通常使用的是在分类任务上做到最好性能的Resnet101,得到共享特征图shared convolutional feature map,在最原始的faster RCNN论文中,RPN在共享特征图上预测出anchor boxes的类别和位置偏移量,而fast RCNN直接从共享特征图上ROI Pooling出一个特征块(比如14*14),则直接送到后面的两个全连接层分支,进行分类和回归。也就是说,ROI Pooling之后的region proposal特征块再没有经历过任何的卷积操作,直接就进行了全连接层,R-FCN的作者认为,由于分类网络必须具有translation invariance即平移不变性(可以理解成在做数据增强的时候,将图像左右平移,ground truth标签并不发生变化),但是检测网络中的回归位置任务则需要具有translation variance(比如在做数据增强的时候,将图像左右平移,ground truth label的类别标签不变,但是位置坐标会左右变化),也就是说,检测问题需要同时兼顾到分类问题的平移不变性和回归问题的对平移的敏感性。检测网络希望继承分类网络在分类任务上达到的较好性能,故而backbone的设计完全继承了当前最好的分类器resnet101,但是ROI Pooling之后对于每个ROI 的检测操作应该不能够直接使用那个与RPN共享的特征图,因为那个特征图是由分类网络直接输出的,并没有对于每个region proposal具有特别的位置敏感信息,针对这一问题,resnet论文的作者在使用resnet做faster RCNN实验时,在ROI wise分支上,将每个ROI从共享特征图上抠取下来特征块之后,并不是直接连入了分类器和回归器,而是再接了几层(现在大多是情况下跑的是1层)卷积层,这样能够保证ROI Pooling前后都有卷积层,ROI Pooling层之前的卷积层是针对于整张图像进行共享计算的,而之后的卷积层则是对每个ROI 单独计算特征的,故而这样就可以保证ROI之后的特征具有位置敏感性。
二、motivation总结
总结一下R-FCN的motivation:在原始的faster RCNN设计过程中,对于RPN和Fast RCNN共享的卷积特征图(由于一般使用的backbone网络是分类网络,故而卷积特征图上的特征倾向于是分类特征,具有平移不变性,但是这对于region proposal和anchor boxes的定位是很不利的,因为RPN分支要对anchor boxe实现分类和定位的任务,而Fast RCNN对于region proposal需要实现分类和定位的任务,故而在RPN和Fast RCNN的两个分支中,并不能直接只用共享的卷积特征图直接接上全连接层或者1*1的卷积实现classification prediction和regression prediction,需要分别在共享的卷积特征图上再应用卷积运算,实现对共享卷积特征图进一步的特征提取,希望给特征图加入位置敏感的信息,故而RPN和Fast RCNN对于共享的卷积特征图都分别应用了3*3的卷积操作,得到各自分支用于分类和回归的特征图),通常的做法是RPN和Fast RCNN在进行位置预测和类别预测之前,分别在自己的分支上加入3*3的卷积,但是作者认为,对于RPN而言,还是相当于在整张特征图上进行3*3卷积进一步提取特征,但是对于Fast RCNN而言,则是需要先从特征图上一个个抠取出region proposal的特征块,再分别对每个region proposal进行3*3的卷积提取特征,作者认为,这些region proposal的特征块之间有很多overlap,故而会导致对于每个region proposal的特征块再单独进行3*3的卷积操作会带来很多冗余计算(这点很类似于R-CNN中,从原始输入图像上抠取出图像块,将每个图像块分别前向传播,也会带来冗余的卷积运算)(他想表达的是,RPN可以通过对整张特征图卷积的方式获得位置敏感信息,为什么fast RCNN要这么麻烦,要先从特征图上抠取出region proposal,再对每个ROI获取位置敏感信息,为什么不能直接在特征图上一次性把所有的位置敏感信息都获取了,再进行抠特征),所以为了提高运算效率,作者提出的改进是,能不能还是在整张特征图上进行卷积运算,得到某种与位置敏感的特征之后,直接从特征图上抠取,进行分类和回归,也就是说通过在整张特征图上进行卷积运算得到位置敏感得分图后,直接从score map上抠取下来的特征,就是当前region proposal的特征(这个特征并不是之前分类网络的具有平移不变性的特征,而是带有一定位置敏感性的特征),然后将特征直接送入分类和回归,也就是说,获取到位置敏感得分图之后,不再进行卷积运算分别对每个region proposal提取特征了。(哇,从这段话的码字中,深切感受到,卷积神经网络就是一个很强大的特征提取器呀,卷积层的堆叠方式决定了所提取出来的特征)
三、网络结构
1.backbone architecture
R-FCN网络结构图是基于resnet101的,resnet101包含100个卷积层、接着一个global average pooling层和1000类别的fc层,这里将全局平均池化层和全连接层去掉,只留下100个卷积层,输出RPN和Fast RCNN的共享特征图(再次注意,虽然还是称为共享特征图,但是RPN和Fast RCNN都不是直接使用这个共享特征图进行检测结果的预测的,这是因为检测包含两个任务:分类和回归,但是这个共享特征图是完全由分类backbone产生的,故而带有很强的平移不变性,这对于回归任务而言是非常不利的,为了加入位置敏感信息,RPN的做法是直接在共享特征图后面接上3*3卷积,原本的fast RCNN也是会接上一层3*3的卷积,但是R-FCN对Fast RCNN提取位置敏感信息这里做出了改进),对于fast RCNN的分支而言,当前特征图的输出通道数是2048,再加上一层1*1卷积操作,将特征图通道数改变为1024,再进行3*3卷积操作,输出通道数为k^2*(C+1),C为前景类别数,就是说将会设置k^2个位置,获得的[batch_size,k^2*(C+1),H,W],在通道维度上切成 k^2个(C+1) ,分别表示当前特征图上的点是某个位置处某个类别的概率,会对(左上角,中上,右上,……一直到右下)的9个位置分别获得H*W*(C+1)的位置敏感特征图,表示当前位置(9个位置中的一个)是某个类别的概率值。
2.Position-sensitive score maps & Position-sensitive RoI pooling
将RPN输出的region proposal对应到位置敏感得分图上,先将建议框对应到特征图上的位置找到:将建议框size=(w,h)对应到特征图上位置挖出来,明确会对于当前特征块输出什么,输出的是k*k*(C+1)的得分图,一类别c为切片取出,表示当前类别下,k^2个位置的特征。将w*h的特征块均等划分为k^2份,即在w*h的特征块上划分出(w/k)*(h/k)的网格,i,j将会遍历网格中的每个位置点,为了得到在c个类别上第i,j个网格的特征值,需要首先找到i,j位置序号在k^2(假设有9个位置)中的编号(比如左上角为第0个位置),然后图1中找到第i,j个位置所对应的特征通道,比如就是第0个,深黄色,然后从深黄色中取出当前类别的那一个通道的特征图,也就找到了z_i,j,c,即网格上编号为i+j的属于类别c的特征图,然后从特征图上抠取处属于当前ROI特征块内第i,j个位置处的所有像素点,进行平均池化,得到一个数值。
对于每个位置,都会得到在C+1个类别的响应值,故而对于一个region proposal,位置敏感的ROI Pooling会输出k*k*(C+1)的特征图,最终怎么对于这个特征图进行类别评分呢?
对于当前region proposal所得到的k*k*(C+1)的特征图,首先对于每个类别上的k*k空间位置上的数值相加,作为当前ROI为该类别的投票数(在C+1通道的每个通道上,用k^2个score值求和,vote为该category的票数),也就是相当于在每个通道上进行全局求和,得到1*1*(C+1)的评分向量,然后进行softmax操作,inference阶段输出评分最大的类别,训练阶段将softmax之后的概率向量与one-hot编码的gt label分类向量做cross entropy
上面介绍了对于分类任务所使用的位置敏感得分图,则对于回归任务同样也会使用位置敏感得分图,对于在共享特征图上使用的1*1卷积操作得到的通道数1024的特征图,有两个分支,(1)使用3*3的卷积得到通道数为k^2*(C+1)的特征图,得到位置敏感得分图,通过在位置敏感得分图上使用ROI Pooling,输出预测的类别概率向量;(2)使用3*3的卷积得到通道数为k^2*4的特征图,通过类似的ROI pooling方式将会对每个ROI得到k*k*4的特征图,然后在4个通道上,每个通道上的k^2个位置进行求和/求全局平均值(在每个通道上的k*k个位置求全局平均值的这个过程称为vote),投票后将输出4维向量,这个4维向量所要预测的target value就是region proposal相对于ground truth boxes的偏移量。现在物体检测中通常的class agnostic(位置不指定)参数都设置为False,即在预测位置偏移量时,不会为每个类别都预测一个位置偏移量,如果要指定特定的位置,位置预测向量的维度硬改4*C。
R-FCN训练过程中使用到了OHEM,无论是OHEM或者是focal loss,都是针对分类任务进行的,物体检测中最常见的问题就是正负样本的不平衡,OHEM具体过程如下:对于每个region proposal,都会计算出分类损失loss值,然后将所有ROI的loss值从高到低进行排序,取出前面loss较高的B个region proposal相加,为最终的分类损失值,再加上regression loss,进行反向传播。
在这里需要补充一点:
物体检测中对于regression loss使用的是smooth L1 loss,即对ground truth boxes编码后的偏移量计算loss。
smooth L1表达式如下:
if abs(prediction-target)<=1:
smooth_l1_loss=(prediction-target)**2 #误差的平方
else:
smooth_l1_loss=abs(prediction-target)#误差的绝对值