《Fast R-CNN》论文阅读之Fast R-CNN

Fast R-CNN

Ross Girshick 
Microsoft Research 
[email protected]

paper:Fast R-CNN

论文翻译:点击这里

导读

Fast R-CNN在SPPNet的基础再跟进,进一步提升速度和准确率,提出了RoI层代替SPP层,实现了整个物体检测模型大部分网络的end-to-end,下面就来好好学习一下。

老套路,现回顾一下: R-CNN ,SPP-net

《Fast R-CNN》论文阅读之Fast R-CNN_第1张图片


《Fast R-CNN》论文阅读之Fast R-CNN_第2张图片


R-CNN和SPP-net在训练时pipeline是隔离的:提取proposal,CNN提取特征,SVM分类,bbox regression。

R-CNN存在的问题:

《Fast R-CNN》论文阅读之Fast R-CNN_第3张图片

  • 检测目标速度慢. 
    在测试阶段,特征来自于每张测试图片的每个候选区域.

  • 同样是要从每个测试图像上提取大量proposal,再从每个proposal中提取特征来进行检测过程,可想而知是很慢的

  • 每个候选区域都需要经过CNN的前向传播计算出特征向量。速度很慢.

  • 训练分为多个阶段(multi-stage pipeline)

    • 第一阶段,从原始图片中使用selective search获取约2000个候选区域
    • 第二阶段,训练CNN,获取候选区域的特征向量
    • 第三阶段,训练SVM和bbox回归 
      因为是分阶段训练,训练SVM和bbox回归时无法更新前面CNN的参数,模型精度上不去。首先要提取特征微调ConvNet,再用线性SVM处理proposal,计算得到的ConvNet特征,然后进行用bounding box回归
  • 训练花费大量的空间和时间(in space and time) 
    候选区域经过CNN得到的特征向量要存在到disk内,然后在训练SVM和bbox回归再取出来,这需要大量的磁盘空间,并且很耗费时间。

R-CNN速度慢是因为每个候选区域都需要塞入CNN里面做一次前向传播,而SPPNet实现了计算共享。

在SPPNet中,把全图塞进CNN得到一个完整的feature map,在将每个候选区域映射到feature map上,获得每个候选区域的特征向量。然后用SPP(Spatial pyramid pooling)对在没个候选区域的特征向量再提取得到了固定长度的特征向量,再实现SVM分类,bbox回归等.

SPPNet存在的问题:

SPPNet也有很明显的缺点:

  • 分阶段训练网络:选取候选区域、训练CNN、训练SVM、训练bbox回归器.
  • 特征需要写入磁盘
  • 训练SVM,bbox回归时算法不能更新卷积层的参数,这会影响网络的精度
SPP已有一定的速度提升,它在ConvNet的最后一个卷积层才提取proposal,但是依然有不足之处。 和R-CNN一样,它的训练要经过多个阶段,特征也要存在磁盘中,另外, SPP中的微调只更新spp层后面的全连接层,对很深的网络这样肯定是不行的 在微调阶段谈及 SPP-net只能 更新FC 层,这是因为卷积特征是线下计算的,从而无法再微调阶段反向传播误差。

Fast RNN的改进

针对上述的问题,Fast R-CNN的想法是将整个模型分成两步:

  • 第一步是选取候选区域;
  • 第二步就是提出一个RoI层,整合了整个模型,把CNN、变换层、SVM分类器、bbox回归这几个模块整一起,大家一起训练
  • 亮点

  • Fast R-CNN将整张整张图片归一化之后直接送入深度网络,邻接时才加入候选框信息,只有末尾的少数几层才处理每个候选框;相比之下,R-CNN框架中,一张图像内候选框之间大量重叠,需要重复地提取特征,耗时间。

  • Fast R-CNN把类别判断和位置精修统一到一个深度网络中,不需要额外存储;相比之下,RCNN中独立的分类器和回归器需要大量特征作为训练样本,耗空间。

《Fast R-CNN》论文阅读之Fast R-CNN_第4张图片


新的模型效果很好,因为多个训练阶段合并了,训练后面阶段的同时可以更新前面阶段的参数,模型收敛的更好了。同时因为多个阶段合并,候选区域的特征不需要在写入磁盘,一直在显存中,训练的速度大大的提升。

Fast R-CNN的架构

Fast R-CNN模型先把一张图片的候选区域整出来,整个模型的输入是全图片和一组候选区域.和SPPNet一样,首先全图片塞进一个CNN得到一个全图的feature map.


《Fast R-CNN》论文阅读之Fast R-CNN_第5张图片

然后,把图片的候选区域映射到feature map得到对应的patch(这和SPPNet的处理类似).然后把这个patch塞给ROI层(Region of interest)得到固定大小的的特征向量(feature vector).

每个特征向量会送到FC层,最后分为两个分支层:一个层是处理softmax概率,输出类别有K个类别和”背景”类;另一个层作bbox回归,输出回归的选框数据.联合一起训练整个网络。

大致流程

  • Selective Search在一张图片中得到约2k个候选框(这里称为RoI);
  • 使用卷积网络提取图片特征;
  • 在conv5出来的feature map上,根据之前RoI框crop出对应的patch(也就是所谓的映射回了原图),再用Rol pooling layer(好像也就是一个单层的SPP layer)来统一到一样的尺度;
  • 继续经过两个全连接层得到特征,然后分别经过一个新的全连接层,最后连接上各自的损失函数: 
    • 一个是分类,使用softmax函数;
    • 一个是回归,使用smooth的L1-loss范式。
《Fast R-CNN》论文阅读之Fast R-CNN_第6张图片



相比于SPPNet,Fast R-CNN简化了SPP层(RoI层是一个简化的SPP层),按论文的说法,Fast R-CNN是joint training

这里我们主要关注两个问题:

  • RoI层是个啥,怎么工作的?
  • 怎么就把几个阶段搞到一起的训练了?

RoI层是个啥

RoI层的作用和SPPNet中的SPP层作用类似:承上启下。

  • 承上: 接收在每个候选区域在feature map上投影出的特征patch,输出长度固定的特征向量。
  • 启下: 特征向量的长度固定的原因为了对付FC层的特殊要求。

说白了就是如何把不同尺寸的侯选区域提取特征变换成为固定大小的特征向量

做图片分类时,一般都是先将图片crop和resize到固定尺寸,然后输入网络,提取特征,最后进行分类。 
对于检测来说,这个方法不太适合,因为原始图像如果缩小到224这种分辨率,那么感兴趣对象可能都会变的太小无法辨认。 
而Fast R-CNN的数据输入并不对图片大小进行限制,实现这一点的关键所在,就是ROI Pooling层,它可以在任意大小的图片feature map上针对输入的每一个ROI区域提取出固定维度的特征表示,保证后续对每个区域的后续分类能够正常进行。

作用

  • 将原图中的RoI定位到feature map中对应的patch;
  • 将这个feature map中的patch下采样为大小固定的feature,方便传入后面的全连接层。

《Fast R-CNN》论文阅读之Fast R-CNN_第7张图片

RoI层是特殊的SPP层,RoI层是使用单个尺度的SPP层(为什么不用多个尺度的原因是多个尺度准确率提升不高,但是计算量成倍的翻)

ROI Pooling

与SPP的目的相同:如何把不同尺寸的ROI映射为固定大小的特征。ROI就是特殊的SPP,只不过它没有考虑多个空间尺度,只用单个尺度(下图只是大致示意图)。 《Fast R-CNN》论文阅读之Fast R-CNN_第8张图片


ROI Pooling的具体实现可以看做是针对ROI区域的普通整个图像feature map的Pooling,只不过因为不是固定尺寸的输入,因此每次的pooling网格大小得手动计算,比如某个ROI区域坐标为,那么输入size为 ,如果pooling的输出size为 ,那么每个网格的size为 。

《Fast R-CNN》论文阅读之Fast R-CNN_第9张图片



RoI层的测试 Forward

引用shenxiaolu1984.

RoI层将候选区域分为H×WH×W块。对每个小块做max-pooling.将候选区的局部特征映射转变为大小统一的数据,送入下一层。

RoI Pooling层将每个候选区域均匀分成M×N块,对每块进行max pooling,这样一来将feature map上大小不一的候选区域转变为了大小统一的特征向量,然后送入下一层。 
尽管ROI Pooling可以看做是针对ROI区域的feature map的Pooling操作,但因为不是固定尺寸的输入,因此每次的pooling网格大小得手动计算。 
举例来说,某个ROI区域坐标为 (x1,y1,x2,y2) ,那么输入size为 (y2−y1)∗(x2−x1) ;如果pooling后输出的size为 pooledheightpooledheight pooledwidthpooledwidth  ,那么每个网格的size为 y2y1pooledheightx2x1pooledwidthy2−y1pooledheight∗x2−x1pooledwidth  
《Fast R-CNN》论文阅读之Fast R-CNN_第10张图片


RoI Pooling层的训练(backward)

考虑到普通的的max pooling层,设xixi为输入层的节点,yiyi为输出层的节点. 

Lxi={0    δ(i,j)=falseLyi  δ(i,j)=true∂L∂xi={0    δ(i,j)=false∂L∂yi  δ(i,j)=true

其中判决函数δ(i,j)δ(i,j)表示ii节点是否被jj节点选为最大值输出。不被选中有两种可能:xixi不在yjyj范围内,或者xixi不是最大值

对于RoI的max pooling,一个输入节点可能和多个输出节点相连。设xixi为输入层的节点,yrjyrj为第rr个候选区域的第jj个输出节点。 
《Fast R-CNN》论文阅读之Fast R-CNN_第11张图片

Lxi=r,jδ(i,r,j)Lyrj∂L∂xi=∑r,jδ(i,r,j)∂L∂yrj

判决函数δ(i,r,j)δ(i,r,j)表示ii节点是否被候选区域rr的第jj个节点选为最大值输出。代价对于xi

xi的梯度等于所有相关的后一层梯度之和.

另外,实际实现时采用的是Max Pooling,具体每个网格中哪个点的值最大,在Forward过程中就已经记录,存储在了argmax_data变量里。 
《Fast R-CNN》论文阅读之Fast R-CNN_第12张图片

把几个阶段搞到一起

前面我们讲了RoI层的反向传播,这就让整个模型能从FC层传播到卷积层了,剩下的就是把SVM分类器和bbox回归整到一起就大功告成了。

《Fast R-CNN》论文阅读之Fast R-CNN_第13张图片


多任务损失(Multi-task loss)

Fast R-CNN在FC层后有两个分支,一个是SVM分类器,一个是bbox回归。 
这里直接给结论,论文把这两个分支的损失弄到一起: 

L(p,u,tu,v)=Lcls(p,u)+λ[u1]Lloc(tu,v)L(p,u,tu,v)=Lcls(p,u)+λ[u≥1]Lloc(tu,v)

Lcls(p,u)Lcls(p,u)是一个分支softmax层输出概率分布:p=(p0,...,pk)p=(p0,...,pk),这是一个K个分类,加上1个背景的softmax层。

λ[u1]Lloc(tu,v)λ[u≥1]Lloc(tu,v)另一个分支bbox回归的位移: tk=(tkx,tky,tkw,tkh)tk=(txk,tyk,twk,thk),k表示类别,这里对于bbox回归的loss,是一个K个输出的regressor.每个类别都会训练出一个回归器,且这里的回归器用的损失函数为: 

Lloc(tu,v)=i{x,y,w,h}smoothL1(tuivi)Lloc(tu,v)=∑i∈{x,y,w,h}smoothL1(tiu−vi)

其中
smoothL1(x)={0.5x2    if|x|<1|x|0.5  otherwisesmoothL1(x)={0.5x2    if|x|<1|x|−0.5  otherwise

使用L1L1正则损失的原因是对outliers(离群点)的敏感度低,模型更具有鲁棒性。

R**oI层加上多任务损失函数,把除了proposal以外的整个模型整到一起了,大家可以一起训练了,没有特征存/取硬盘的操作,整个训练和测试过程又全线提速了!**

作者这样设置的目的是想让loss对于离群点更加鲁棒,控制梯度的量级使得训练时不容易跑飞。
最后在5.1的讨论中,作者说明了Multitask loss是有助于网络的performance的。

Mini-batch sampling
在微调时,每个SGD的mini-batch是随机找两个图片,R为128,因此每个图上取样64个RoI。从object proposal中选25%的RoI,就是和ground-truth交叠至少为0.5的。剩下的作为背景。

分层数据

在调优训练时,每一个mini-batch中首先加入N张完整图片,而后加入从N张图片中选取的R个候选框。这R个候选框可以复用N张图片前5个阶段的网络特征。 

实际选择N=2, R=128-> 每一个mini-batch中首先加入2张完整图片,而后加入从2张图片中选取的128个候选框。这128个候选框可以复用2张图片前5个阶段的网络特征。 


Fast R-CNN的训练技巧

预训练网络

SGD的样本选取

这里针对fine-tuning阶段指出了SPPNet存在的问题。

SPPNet在使用BP算法训练效率低的原因:

  • 每个训练样本来自于不同的图片.
  • The inefficiency stems from the fact that each RoI may have a very large receptive field, often spanning the entire input image. Since the forward pass must process the entire receptive field, the training inputs are large (often the entire image).

SPPNet只能微调SPP层后面的全连接层,再采用SGD方法训练的过程中,而SPPNet的会在多张图片上选取候选区域,这里在反向传播的过程中会大量耗费内存和时间

在Fast R-CNN的做法:

Fast R-CNN采用SGD训练,每次采样在N个图片的基础上选取R个候选区域,实验选取的N=2,R=128.这样样本数据来自与2张图片,这比R-CNN和SPPNet选取的样本在训练速度上快了很多倍

这里存在一个问题,训练样本大多数取自同一张图片,样本之前关联性很大,这可能会造成训练不收敛,但是在论文的实验过程中,没有出现这种情况,所以就采用这个方法了

小批量采样(Mini-batch sampling)

在网络微调,每个SGD mini-batch是由N=2,R=128,首先加入N张完整图片,而后加入从N张图片中选取的R个候选框。从object proposal中选25%的RoI,就是和ground-truth的IoU至少为0.5的。剩下的75%取IoU至少为在0.1到0.5的样本作为背景。

N张完整图片以50%概率水平翻转。 R个候选框的构成方式如下:

类别 比例 方式
正例 25% 与Ground-Truth的IoU大于0.5
反例 75% 与Ground-Truth的IoU在0.1到0.5之间

使用奇异值分解为FC层提速(Truncated SVD for Fast detection)

在检测过程中,因为要处理的RoIs较多,几乎过半的时间都耗费在FC层的计算上了,这里是用SVD分解加速FC层的计算。

我们对一组尺寸u×vu×v的权重矩阵WW可分解为:使用t个特征值. 

WUΣtVT=U(:,1:t)Σ(1:t,1:t)V(:,1:t)TW≈UΣtVT=U(:,1:t)Σ(1:t,1:t)V(:,1:t)T

将原来的前向传播分为两步,降低了计算复杂度: 

y=Wxy=(UΣtVT)x=Uzy=Wx→y=(UΣtVT)x=Uz

计算复杂度从u×vu×v变为u×t+v×tu×t+v×t

在实现时,相当于把一个全连接层拆分成两个,中间以一个低维数据相连。

在分类中,计算全连接层比卷积层快,而在检测中由于一个图中要提取2000个RoI,所以大部分时间都用在计算全连接层了。文中采用奇异值分解的方法来减少计算fc层的时间.

具体来说,作者对全连接层的矩阵做了一个SVD分解,mAP几乎不怎么降(0.3%),但速度提速30%

Scale invariance

SPPnet用了两种实现尺度不变的方法: 
1. brute force (single scale),直接将image设置为某种scale,直接输入网络训练,期望网络自己适应这个scale。 
2. image pyramids (multi scale),生成一个图像金字塔,在multi-scale训练时,对于要用的RoI,在金字塔上找到一个最接近227x227的尺寸,然后用这个尺寸训练网络。 
虽然看起来2比较好,但是非常耗时,而且性能提高也不对,大约只有%1,所以这篇论文在实现中还是用了1

Which layers to finetune?

对应文中4.5,作者的观察有2点

  1. 对于较深的网络,比如VGG,卷积层和全连接层是否一起tuning有很大的差别(66.9 vs 61.4)
  2. 有没有必要tuning所有的卷积层?
    答案是没有。如果留着浅层的卷积层不tuning,可以减少训练时间,而且mAP基本没有差别。

全连接层提速

分类和位置调整都是通过全连接层(fc)实现的,设前一级数据为后一级为,全连接层参数为,尺寸。一次前向传播(forward)即为: 


计算复杂度为

将进行SVD分解,并用前t个特征值近似: 

原来的前向传播分解成两步: 


计算复杂度变为。 
在实现时,相当于把一个全连接层拆分成两个,中间以一个低维数据相连。 
《Fast R-CNN》论文阅读之Fast R-CNN_第14张图片


Data augment

在训练期间,作者做过的唯一一个数据增量的方式是水平翻转。
作者也试过将VOC12的数据也作为拓展数据加入到finetune的数据中,结果VOC07的mAP从66.9到了70.0,说明对于网络来说,数据越多就是越好的。


实验与结论

实验过程不再详述,只记录结论 
- 网络末端同步训练的分类和位置调整,提升准确度 
- 使用多尺度的图像金字塔,性能几乎没有提高 
- 倍增训练数据,能够有2%-3%的准确度提升 
- 网络直接输出各类概率(softmax),比SVM分类器性能略好 
- 更多候选窗不能提升性能

Results for VOC2007

method mAP S M L train time(h) S M L test rate (s/im) S M L
SPPnet BB — — 63.1 — — 25 — — 2.3
R-CNN BB 58.5 60.2 66.0 22 28 84 9.8 12.1 47.0
FRCN 57.1 59.2 66.9 1.2 2.0 9.5 0.10 0.15 0.32


Fast R-CNN 两大主要贡献点 :

  • 1 实现大部分end-to-end训练(提proposal阶段除外): 所有的特征都暂存在显存中,就不需要额外的磁盘空。
    • joint training (SVM分类,bbox回归 联合起来在CNN阶段训练)把最后一层的Softmax换成两个,一个是对区域的分类Softmax(包括背景),另一个是对bounding box的微调。这个网络有两个输入,一个是整张图片,另一个是候选proposals算法产生的可能proposals的坐标。(对于SVM和Softmax,论文在SVM和Softmax的对比实验中说明,SVM的优势并不明显,故直接用Softmax将整个网络整合训练更好。对于联合训练: 同时利用了分类的监督信息和回归的监督信息,使得网络训练的更加鲁棒,效果更好。这两种信息是可以有效联合的。)
  • 2 提出了一个RoI层,算是SPP的变种,SPP是pooling成多个固定尺度,RoI只pooling到单个固定的尺度 (论文通过实验得到的结论是多尺度学习能提高一点点mAP,不过计算量成倍的增加,故单尺度训练的效果更好。)
《Fast R-CNN》论文阅读之Fast R-CNN_第15张图片




参考文献:

1.https://blog.csdn.net/u011974639/article/details/78053203#r-cnn

2.https://blog.csdn.net/u011534057/article/details/51241831

3.https://blog.csdn.net/xiaqunfeng123/article/details/78716060

4.https://zhuanlan.zhihu.com/p/24780395


你可能感兴趣的:(目标检测,卷积神经网络,Paper,Reading,目标检测/跟踪)