目标检测5 - R-FCN

R-FCN

We propose position-sensitive score maps to address a dilemma between translation-invariance in image classification and translation-variance in object detection.

平移不变性和平移变换性

分类需要特征具有平移不变性(同一物体不管在哪都能检测为同一物体),检测则要求对目标的平移做出准确响应(bbox位置精准回归)。对于图像分类任务来说:分类问题往往会忽略位置信息,只需要判断是否为某个物体,所以要求提取出来的特征具有平移不变性,不管图片特征放大、缩小还是位移都能很好的适应,而卷积操作、pooling操作都能较好的保持这个性质,并且网络越深模型越对位置不敏感;。对于图像检测任务来说:更倾向于平移变换性。我们假设图像分类网络的卷积层越深,则该网络对平移越不敏感。现在的大部分CNN在分类上可以做的很好,但用在检测上效果不佳。SPP,Faster R-CNN类的方法在RoI pooling前都是卷积,卷积是具备平移不变性的(因为卷积核共享参数,一只猫在左上角和右下角都可以检测到是同一只猫),但一旦插入RoI pooling之后,后面的网络结构就不再具备平移不变性了(RoI池化之后原来相差4x4=16像素的两个点经过池化可能变为相邻,不在具有平移不变性)。

因此,R-FCN提出来了 position-sensitive score map (位置敏感分值图)这个概念,希望能把目标的位置信息融合进RoI pooling。它包含物体的位置信息,其顶端设有RoI Pooling层来处理位置信息,之后再没有权重层。这样,R-FCN就将几乎所有的计算都共享,可以达到比faster rcnn快2.5-20倍。

在此之前的R-CNN系列的目标检测框架通常包含两部分:

  • RoI Pooling之前的一个共享的全卷积子网络;
  • RoI Pooling之后的不共享的RoI-wise的子网络。

这主要是因为历史上先驱的分类网络如AlexNet,VGGNet等都是类似的结构:一个卷积组成的网络,接pooling层,再接几个fc层。这样物体分类网络中的最后一个pooling层可以方便地替换成RoI Pooling,然后用在物体检测网络中。

而现在的state of the art 的物体分类网络如ResNet,GoogLeNet都是全卷积网络,在目标检测方面也使用共享的全卷积网络是一个很自然的想法,然而,实践证明这个方案的检测精度极低。为了解决这个问题,在ResNet的文献中,Faster R-CNN中的RoI pooling layer被不自然的插入到两个卷积层集之间,大家插入类似RoI Pooling这样的层结构,一方面是的任意大小图片都可以输入,更重要的是一定程度上弥补了位置信息的缺失,带来了准确率的提升。但带来一个副作用是:RoI后每个Region都需要跑一遍后续子网络,计算不共享就导致训练和Inference的速度慢。

作者认为上述不合理的设计是由于图片分类任务中增长的平移不变性和目标检测任务中的平移变换性之间的矛盾引起的:

  • 图像分类任务侧重于平移不变性(在一幅图片中平移一个物体而不改变它的判别结果),因此深度全卷积网络结构在尽可能保存平移不变性上是最好的(源于卷积核共享参数的特性),在ImageNet分类task的良好表现得以证明;

  • 目标检测任务需要位置表示(translation-variant)。例如,某个候选框里的物体的平移应该产生有意义的responses,用来描述该候选框和物体的重叠度。我们假定在图片分类网络中,卷积层越深,对平移越不敏感。为了解决这个dilemma,Faster R-CNN在ResNet中插入了RoI pooling层,这个 region-specific 操作破坏了平移不变性,而且当evaluate across不同region时,post-RoI卷积层不再是平移不变的了。并且这个设计牺牲了训练和测试的效率,因为它引入了大量的region-wise layers。

    目标检测5 - R-FCN

为了将平移变换性(translation variance)融合到FCN中,我们通过使用一组专用卷积层作为FCN的输出来构造一组位置敏感得分图(position-sensitive score maps)。每一个得分图对相对空间位置信息(例如,“在对象的左边”)进行编码。在这个FCN的顶层,我们附加了一个位置敏感的RoI pooling层(position-sensitive RoI pooling layer),从这些得分图中获取信息。这些得分图不带任何权重层(卷积层或全连接层)。整个结构是end-to-end的学习。所有可学习的层在整幅图片中都是可卷积并且可共享的,并且可以编码空间位置信息用于目标检测。

Main Approach

本论文的方法参考R-CNN的架构,也是使用two-stage的目标检测策略。

  • region proposal
  • region classification

虽然不依赖于region proposal的目标检测方法确实存在,如SSD和YOLO,但是region-based system依旧在一些benchmark上保持最好的准确性。

我们希望的是,耗时的卷积都尽量移到前面共享的subnetwork上。因此,和Faster RCNN中用的ResNet(前91层共享,插入ROI pooling,后10层不共享)策略不同,本文把所有的101层都放在了前面共享的subnetwork。最后用来prediction的卷积只有1层,大大减少了计算量。

核心思想

R-FCN思路就是利用最后一层网络通过FCN构成一个position-sensitive的feature map。具体而言,每一个proposal的位置信息都需要编码,那么先把每个proposal(图中的RoI)平均分成 k×k 个网格,然后对每一个网格进行编码。下图中,这里的feature map是过去RoI Pooling前的全卷积特征提取子网络,之后接着的(大彩色立方体)是position-sensitive score maps,它其实是一个普通的卷积层 ,只不过对位置信息进行了编码,它的输出是 C+1 个类别的分值。

位置敏感分值图和位置敏感RoI池化层配合,替代原先的全连接层类别推断的功能。

R-FCN 最后1个卷积层在整幅图像上为每类生成 k×k位置敏感分数图(position-sensitive feature maps),有 C 类物体加1个背景类,因此共有 k2(C+1) 个通道的输出层。k×k 代表分数图对应描述位置的空间网格数,假如 k=3 ,则每一类的 position-sensitive feature map会有 k×k=9 个,则9个分数图用来编码单个物体类的位置特征(如:左上、左中、左右、……,下右:从左到右从上到下扫描,图中用不同颜色代表)。

注意,score map尺寸等于图片尺寸,即position-sentitive score maps总共产生 K2(C+1)mn 的tensor。

目标检测5 - R-FCN

在position-sentitive score maps 以后跟着一个positive-sensitive的RoI pooling layer作为结束层,它将最后一个卷积层的输出结果聚集起来,然后产生每个ROI的score。positive-sensitive RoI pooling层不同于Fast R-CNN的RoI pooling,它采用的是selective pooling。

Selective pooling(选择性池化):RoI的左上角网格只取橙色块 (top−left)对应RoI左上角的区域,池化橙色方块 RoI 得到橙色小方块 (分数);右下角网格只取浅蓝色RoI区域;其它颜色的响应图像同理。得到薄的那个立方块(已池化过),对所有颜色的小方块投票 (或池化) 得到1个类别的响应结果。

整体架构

RPN 给出感兴趣区域,R-FCN 对该感兴趣区域分类。R-FCN 在与 RPN 共享的卷积层后多加1个卷积层。所以,R-FCN 与 RPN 一样,输入为整幅图像。但 R-FCN 最后1个卷积层的输出从整幅图像的卷积响应图像中分割出感兴趣区域的卷积响应图像。 R-FCN 最后用位置敏感 RoI 池化层,给每个 RoI 1个分数。最后在经过一个pool进行类别投票。

R-FCN就是把Faster R-CNN的Fast R-CNN的分支改进成R-FCN网络

目标检测5 - R-FCN

Backbone architecture

Image-set pre-trained ResNet 101——去掉原始ResNet101的最后一层的global average pooling和一个1000-class的fc层,仅仅保留前100层的卷积层用来计算feature map,ResNet-101中的最后一个卷积块是2048-d,再接一个随机初始化的1×1×1024 的卷积层以减少尺寸(第100层的输出是2048维,为了降维,再引入了一个1×1的卷积层,则输出为1024维)。然后使用了 k2(C+1) 个通道的卷积层来生成score maps 分数图。

Position-sensitive score maps & Position-sensitive RoI pooling

为了显式地在每个RoI中编码位置信息,我们将RoI矩形划分为k x k个bins。对于一个大小为 w×h 的 RoI 区域,每一个 bin 的大小 ≈ wk×hk。最后一个卷积层为每个类别产生 k2 个分数图,所以一共 C+1k2 的分值图。对第 i 行第 j 列的 bin(i,j) (0i,jk1) ,定义一个位置敏感 RoI 池化操作,仅仅池化第 (i,j) 个得分图:

rc(i,j|Θ)=1n(x,y)bin(i,j)zi,j,c(x+x0,y+y0|Θ)

目标检测5 - R-FCN

其中,rc(i,j|Θ) 为第 c 类第 (i,j) 个bin的池化响应,zi,j,ck2(C+1) 个分数图中的其中一个score map(某种颜色的块中的 1/(C+1) ?),(x0,y0) 为 RoI 的左上角坐标,n 为bin里的像素总数,Θ 为网络的所有可学习的参数。第 (i,j) 个bin的范围是:iwkx<(i+1)wk ,以及 jhky<(j+1)hk 。如下图,一个颜色的通道对应一个 (i,j) 网格,论文中采用的都是average pooling,当然max pooling也有良好表现。

  • k2(C+1)个score map的物理意义: Score map本身没有区域的概念,是人为的在 k×k 的通道数上进行编码表示九处位置,如共有 kk=9个颜色,则每个颜色的立体块WH(C+1)表示的是不同位置存在目标的概率值(第一块黄色表示的是左上角位置,最后一块淡蓝色表示的是右下角位置)。共有 k2(C+1) 个score map。每个score map z(i,j,c) 是第 i+k(j1) 个立体块( ij 列)上的第 c 个map(1<=i,j<=3)。(i,j) 决定了9种位置的某一种位置,假设为左上角位置(i=j=1),c 决定了哪一类,假设为 person 类。在 z(i,j,c) 这个feature map上的某一个像素的位置是 (x,y),像素值是 value ,则 value 表示的是原图对应的 (x,y) 这个位置上可能是人(c=person)且是人的左上部位(i=j=1)的概率值。

  • RoI pooling:就是faster RCNN中的RoI pooling,也就是一层的SPP结构。主要用来将不同大小的RoI对应的feature map映射成同样维度的特征,思路是不论对多大的RoI,规定在上面画 nn 个bins的网格,每个网格里的所有像素值做一个pooling(平均),这样不论图像多大,pooling后的RoI特征维度都是 nn。注意一点RoI pooling是每个feature map单独做,不是多个channel一起的。

  • position-sensitive RoI pooling的输入和输出: RoI pooling操作的输入(对于C+1个类)是k2(C+1)WH(W’和H’是ROI的宽度和高度)的score map上某RoI对应的那个立体块,且该立体块组成一个新的 k2(C+1)WH的立体块:每个颜色的立体块(C+1)都只抠出对应位置的一个bin,把这kk个bin组成新的立体块,大小为 (C+1)WH。例如,上图中的第一块黄色只取左上角的bin,最后一块淡蓝色只取右下角的bin(selective)。所有的bin重新组合后就变成了类似右图的那个薄的立体块(图中的这个是池化后的输出,即每个面上的每个bin上已经是一个像素。池化前这个bin对应的是一个区域,是多个像素)。池化每一个RoI时,各个网格(一共 k2 个),均由上一层中对应分组的对应位置区域通过平均池化获得。由此获得一组 C+1 张特征图。最后,将这些特征图经过全局平均池化,得到 C+1 维的向量,计算分类损失函数。 (注意有两次池化)

k2 个score maps用来对RoI区域进行投票,论文中仅仅通过对score取平均来投票。对于每个RoI产生 (C+1) 维的向量:rc(θ)=i,jrc(i,j|Θ) 。然后计算每个类别的softmax,用于训练时候计算交叉熵loss。

RoIC+1 的每一类上都会得到一个 k×k 网格,即生成一个 k×k×(C+1) 的feature map,对于这里来说 k=3 ,所以最后RoI pooling层产生 3×3×(C+1) 维的feature map。如下图:

目标检测5 - R-FCN

k×k×(C+1) 的 feature map 进行 average pooling,对于每一个RoI会产生 (C+1) 维的向量(置信度),然后通过softmax即可得到属于哪个类别的可能性(loss采用交叉熵)。

进一步地,论文用相似地方法定位了bounding box回归,除了上面的 k2(C+1) 个卷积层,还附加了一个sibling的 4k2-d 的卷积层用于bounding box回归。位置敏感RoI pooling在 4k2 的map中执行,对于每一个RoI,产生一个 4k2 维的向量,然后通过平均投票被聚合为一个4维向量,代表 (tx,ty,tw,th)

ResNet101的输出是WH1024,用K2(C+1)102411的卷积核去卷积即可得到channel=K2(C+1)个大小为WH 的position sensitive的score maps。这步的卷积操作就是在做prediction。k = 3,表示把一个RoI划分成 33,对应的9个位置分别是:上左(左上角),上中,上右,中左,中中,中右,下左,下中,下右(右下角)。

R-FCN训练过程

预先得到region proposals,R-FCN很容易进行端到端的训练。网络的损失函数和Fast R-CNN一样,采用了多目标的损失函数(Multi-task),同时考虑了分类的损失和位置的损失。

Loss Function

定义为在每个RoI上的关于类别的交叉熵loss和bounding box回归的loss的和。

L(s,tx,y,w,h)=Lcls(sc)+λ[c>0]Lreg(t,t)=log(erc(Θ)c=0Cerc(Θ))+λ[c>0]Lreg(t,t)

上式中:

  • c 代表RoI的 ground-truth label( c=0 代表背景类)
  • Lclssc=log(sc) 代表了分类的交叉熵损失
  • Lreg 表示位置的损失,定义同Fast R-CNN一样
  • t 表示ground truth的bounding box的参数
  • [c>0] 表示对于背景类不必进行bbox位置回归。训练时,由于proposal已知类别,所以直接送入对应类别的Regressor即可
  • 超参数 λ=1,用于平衡分类损失和位置损失。
  • 在softmax分类过程中,作者设定与ground truth 的IoU阈值>0.5的设定为正样本,其他的为负样本。

online hard example mining(OHEM)

Training Region-based Object Detectors with Online Hard Example Mining

论文笔记

训练时,在我们的方法中采用OHEM是非常容易的,对每个RoI区域几乎可忽略的计算代价使得example mining是cost-free的。假定每张图片有N个proposals,前向传播时,我们估算这N个proposal的损失,然后把所有RoI按照loss进行从大到小排序,然后只挑选B个具有最高loss的RoI(B/N)用于反向传播更新(loss越高的proposal说明网络没有兼顾这种proposal,类似boosting思想)。

因为我们的每个RoI的计算都是近似可忽略的,所以前向计算的时间几乎不会受N的影响。而OHEM Fast R-CNN可能是会花费双倍的训练时间。

在Fast R-CNN中,确定一个proposal是背景时也是根据IoU范围[bg_lo,0.5],这个范围的前提假设是与ground truth有重叠的样本是hard(很正的负的,难以区分的)的可能性较大,但是作者在此指出,这样得到的结果很可能是次优的,因为在其他位置可能存在更hard的样本,所以在本文提出的OHEM算法中移除了这个阈值。

OHEM是一种boosting策略,目的是使得训练更加高效,简单说,它不是使用简单的抽样策略,而是对容易判断的样本做抑制,对模型不容易判断的样本重复添加。
在检测中,正样本定义为:与ground-truth的IoU>0.5的,反之为负样本,应用过程为:

  • 前向传播:所有候选框在Inference后做损失排序,选取B(共N个)个损失最高的候选框,当然,由于临近位置的候选框的损失相近,所以还需要对其做NMS(如取IoU=0.7),然后再选出这B个样本;
  • 反向传播:仅用这B个样本做反向传播更新权重。

训练细节

  • decay = 0.0005,momentum = 0.9
  • 单尺度训练:图片resize到短边600
  • 使用8个GPU进行训练,每个GPU 1张图,选择B=128(B/N)个ROIs进行反向传播(OHEM)
  • fine-tune learning rate = 0.001 for 20k mini-batches, 0.0001 for 10k mini-batches on VOC.
  • 为了让R-FCN共享RPN的特征,采用4步交替训练 RPN 和 R-FCN(参见Faster R-CNN训练过程)

测试(Inference)

如Figure 2所示,计算input image(600x600)后得到的feature map由RPN和R-FCN共享。然后RPN网络提出RoI区域建议,而R-FCN网络计算类别得分和bbox回归。在测试阶段,我们评估了300个RoI区域,并对结果进行非极大值抑制(0.3的IoU阈值)。

目标检测5 - R-FCN

多孔算法(A trous)

将mAP提高了2.6个点

  • 将ResNet-10的有效stride从32减为16像素,提高了score map的分辨率。
  • conv4阶段之前(stride=16)的所有层都没有改变。
  • 第一个conv5块儿的stride从2改为1,并且conv5阶段的卷积核都被改为hole algorithm,(Algorithme à trous)以补偿减少的步幅。
  • 为了公平比较,RPN在conv4之上进行计算。从而RPN不被à trous影响

可视化

Figure 3和Figure 4中,我们展示了KxK=3x3时,通过R-FCN学习到的position-sensitive score maps。这些特征图受到物体的具体相对位置的强烈影响。例如,“top-center-sensitive” score map(九种颜色块之一)对那些大致接近目标的top-center位置的显示了较高的分数(白色)。如果一个候选框与真实物体精确的重合了(Figure 3),那么RoI中大多数的bins(of k2 bins)会被强烈的**,最后投票时得到较高的分数。相反,如果候选框和真实物体位置存在较大偏差,那么在RoI里有些 bins不会被**(黑色),从而导致得分很低。

RoI 分类的可视化。RPN 刚好产生包含 person 类的 RoI。经过 R-FCN 的最后1个卷积层后产生9个相对空间位置的分数图,对 person 类的每个相对空间位置通道内的 RoI bin平均池化得到3×3的池化分数,投票后送入分类器判断属于 person 类。当分类正确时,该类通道的位置敏感分数图 (中间) 的大多数橙色实线网格内的响应在整个 RoI 位置范围内最强(白色)。

如图Figuire 3,共九张图,代表 C+1 个类中 person 这个类的 k2 个score map,每个score map的卷积结果都是不一样的,但它们在自己相对位置(黄色实线小方框)上的响应都比较高(白色),位置敏感RoI pooling的九个网格取对应位置的score map中对应的黄色实线小框中的像素做均值池化,得到右边 3x3的pooling 结果在3。这9个池化结果再做一个均值投票,得到该RoI是否属于 person 类的结果。

3*3的区域内,每一个区域内都预测(C+1)类的得分,比如下图左上角的bin预测的是可能是人这个类且是人的左上部位的score(也预测是其他C个类且是该类左上部位的score)。

目标检测5 - R-FCN

实验结果

  • 网格越细(7x7),mAP越高。
  • Test时间提升2.5x。
  • OHEM没有带来时间开销。