检测之旧文新读(三)-Fast R-CNN

动机:

可以说这一篇论文,是进一步的优化SPP-Net在检测上面的工作。那么作者肯定是看到SPP-net针对检测的缺点,然后结合自己的解决方法得到的。那么SPP-Net的缺点有哪些呢,文中总结的有如下几点:
1)训练是多个步骤的(multi-stage)
2)由于要训练SVM所以事先要将特征保存到disk,即训练空间浪费大。
3)由于SPP的原因,RCNN提出的fine-tune的方法无法直接用在SPP-net,所以导致了fine-tune的时候卷积层无法得到更新(具体请看下面理解)
那么针对这些缺点作者提出了训练end2end的方法,提出了multi-task的loss,将直接用卷积网络的输出作为最后结果,这也解决了问题2需要保存特征来训练SVM的问题。

缺点3如何理解:

主要原因就在于,SPP-net 的ROI feature map的计算变成共享卷积特征的剪切操作。那么导致检测网络在训练的时候反向传播不能简单的使用一般的Pooling一样的公式来传播。所以SPP-net作者为了简单,只是fine-tune了最后的fc6和fc7两层。这样造成了卷积层无法随着fine-tune进行更新,fast RCNN作者认为这样会造成检测的精度下降,后面实验也确实验证了作者的观点。

整体算法流程与贡献:

检测之旧文新读(三)-Fast R-CNN_第1张图片
fast RCNN主题算法流程

简单的说一下贡献(文中有总结):

  1. 比R-CNN,SPP-net更高的检测精度
  2. 训练是单步的(single-stage), 并且使用了多任务学习的损失函数(multi-task loss):针对缺点1
  3. 训练的时候可以更新所有的网络参数:针对缺点3
  4. 在训练SVM的时候不需要额外的硬盘存储特征:针对缺点2

接下来就按照实验的顺序来一一来说明这些贡献。

实验:

数据集: 让提取出来的proposals和ground truth 的IOU>0.5 为正样本占比25%,然后在[0.1,0.5 )之间的样本占比75%,为负样本。你可能会问为什么会这样变得比例设置,因为一般情况下负样本的样本种类和情况远比正样本的多。为了使得训练采样尽量均衡,所以设置为1:2到1:5之间,1:3是经验上比较合理的设置。这里还有一个疑问为什么不让<0.1作为负样本呢?文中给的一句话是:The lower threshold of 0.1 appears to act as a heuristic for hard example mining[8],可能需要从另外一个文章中找到答案了(让我想起了图片的diversity images annotation,是否可以从imagenet几千万张图片中探索出仅需要几万张具有丰富信息图片就可以进行训练达到相同的效果呢?

基本检测的准确率的实验:

实验内容:对不同的检测方法进行比较,其中变量包括:模型和训练集(训练集不同主要是为了和之前的模型进行公平对比)
实验结果分析:

检测之旧文新读(三)-Fast R-CNN_第2张图片

可以看出FRCN(fast RCNN)效果均有提升,总结下有一下几个原因:
1).在进行fine-tune的时候同时更新了卷积层的参数(贡献3)
2).使用了single-stage来训练,使用了multi-task loss来进行训练,对效果也有一定的提升(贡献2)
3).使用更多的train data

实验对未来的帮助: 基本上上面的3个方面后面都成为了检测训练的标配,都被广泛的应用了。
接下来就对这几个原因做详细的介绍!!

fine-tune的时候同时更新了卷积层的参数(贡献3)

从缺点3知道这个SPP-net无法更新的主要原因是SPP-net 的ROI feature map的计算变成共享卷积特征的剪切操作。那么导致检测网络在训练的时候反向传播不能简单的使用一般的Pooling一样的公式来传播。所以作者提出了自己的ROI pooling的反向传播公式,具体如下,引自博客[2]:
解决问题:ROI pooling的剪切操作如何进行反向传播呢?
先看普通max pooling层求导:
设xi为输入层节点,yi为输出层节点,那么损失函数L对输入层节点xi的梯度为:


检测之旧文新读(三)-Fast R-CNN_第3张图片

其中判决函数δ(i,j)表示输入i节点是否被输出j节点选为最大值输出。
不被选中【δ(i,j)=false】有两种可能:xi不在yi范围内,或者xi不是最大值。
若选中【δ(i,j)=true 】则由链式规则可知损失函数L相对xi的梯度等于损失函数L相对yi的梯度×(yi对xi的梯度->恒等于1),故可得上述所示公式;

对于ROI max Pooling 层的反向传播求导:
设xi为输入层的节点,yri 为第r个候选区域的第j个输出节点,一个输入节点可能和多个输出节点相关连,如下图所示,输入节点7和两个候选区域输出节点相关连;

检测之旧文新读(三)-Fast R-CNN_第4张图片

该输入节点7的反向传播如下图所示:
检测之旧文新读(三)-Fast R-CNN_第5张图片

对于不同候选区域,节点7都存在梯度,所以反向传播中损失函数 L 对输入层节点 xi 的梯度为损失函数 L 对各个有可能的候选区域 r 【 xi 被候选区域r的第j个输出节点选为最大值 】输出 yri 梯度的累加,具体如下公式所示:
检测之旧文新读(三)-Fast R-CNN_第6张图片

判决函数 [i=i∗(r,j)] 表示 i 节点是否被候选区域r 的第j 个输出节点选为最大值输出,若是,则由链式规则可知损失函数L相对 xi 的梯度等于损失函数 L 相对yri 的梯度×( yrj 对xi 的梯度->恒等于1),上图已然解释该输入节点可能会和不同的yrj j有关系,故损失函数L相对xi 的梯度为求和形式。
例如:在ROI max pooling反向传播示意图中,上面一个(r=1,j=2,黄色)下面一个(r=2,j=3,蓝色)但是反向传播对xi来说两个都是第7个,所以对于x7来说此时反向传播的梯度值为2,即为它们的累加

另外:ROI pooling中,如何在feature map的位置和最开始提出proposal的位置相对应起来:
具体可以看spp-net那个文章所讲,简单的就是将左上角坐标和右下角坐标都乘上一个尺度因子,这个尺度因子目前层所有stride的乘积。这里可以解决一个小问题,为什么使用了ROI 这种max pooling 作者不使用multi-level呢?

因为如果你的SPP使用的是max pool,multi-level的话,一维最大一定会出现在4维中,4维的最大应该是16维最大的里面。那么其实multi-level的作用就不明显了。相当于最大的相应值权值相加的效果,其实就没有什么效果了,这也是之前我解读spp-net的时候存有其效果提升的疑问。

训练是单步的(single-stage), 并且使用了多任务学习的损失函数(multi-task loss)(贡献2)

RCNN和SPP-net训练的时候CNN是先训练好,在用SVM训练分开的,在训练SVM的时候CNN是不更新的,其实这也是end-to-end的精髓,不同部分通过end-2-end的训练可以互相协调工作,但是这里仅适用了ROI和最后分类回归进行了single stage。从这里引发思考,是否可以将候选框的生成也作为统一的训练呢?所以后续作者又提出RPN的end-to-end的训练方法,同时faster rcnn也提出two-stage训练也可以达到协调的作用,那two stage和end-to-end本质上面是等价的吗?

multi-task的设计:


1.先回答一个问题:Multi-task为什么在这起作用?
1)首先从动机上面使用multi-task loss 可以将pipe line的任务变成end2end的,而且这种stage-wise是multi task loss 的suboptimal
2)因为回归和分类本质上可以共享特征,从RCNN的loc regression的做法上面可以看书对已d(*)实际上是输入的是线性模型输入的是feature map上面的值,和classification实际上也是用feature map上面的值,所以可以共享。 所以这个任务他们有理由共享使用卷积层的特征,所以可以放在一起进行multi-task。

另外,作者也从实验的角度阐述了multi-loss的作用:
实验如何做:
第一列将loss中的λ设置为0然后进行训练,在test的时候没有进行bbox regression
第二列:将loss中的λ设置为1,然后进行训练,在test的时候没有进行bbox regression
第三列:将loss中的λ设置为0,然后进行训练,然后固定网络权值,然后想RCNN一样训练loc regression
第四列:最后loss中的λ设置为1,然后进行训练,在test的时候进行了bbox regression
实验结果进行分析:

检测之旧文新读(三)-Fast R-CNN_第7张图片

从第一列和第二列可以看出multi-loss train对于分类还有大概0.8-1.0的提升
从第三列和第四列可以看出,multi-loss train对于stage-wise train来说效果也有较大提升
你可能会考虑为什么会出现这种结果呢?
个人感觉这个可能就是end2end的精髓了,前后之间可以相互影响反馈和调节。

2.作者对于loc 部分的loss进行了一定的优化,具体如下:
Bbox regression 在RCNN和SPP-net中是这样的:

检测之旧文新读(三)-Fast R-CNN_第8张图片

采用的是L2范数,在fast RCNN中采用的是:
检测之旧文新读(三)-Fast R-CNN_第9张图片

3.那么你就会疑问为什么用L1而不采用L2呢?
文中的回答是这样的L2求导后会存在f(x)-y 的乘积项,所以当预测和目标相差比较大的时候回出现梯度爆炸的问题。所以用L1范数貌似会更好一些。
可能我也存在疑问,为什么梯度大就会造成梯度爆炸,另外从另一个角度,如果两者目标相差大,梯度大一点不是可以加速收敛吗?从这个角度应该是有益处的?如何理解?

4.作者为什么会想到用L1代替L2,并且使用L1的近似smoothL1呢?
L1范数在0的位置他是不可导的,那么我们就选择另一个函数来代替他,熟悉的一个函数就是使用x2,然后为了和L1逼近所以选择了0.5*x2,这里可以画张图就大致明白了。
5.与RCNN结合的方式:在RCNN中loc回归是单独的步骤来实现的所以建模成w*φ(pool5)来进行学习w来进行回归。在fast RCNN中他w训练权值直接是全连接的权值。所以可以直接end2end的训练。
最后遗留了一个问题:文中说在进行regression的时候,他们进行了对ground truth的均衡化和反差单位化,这样做的作用是什么呢?(原文:We normalize the ground-truth regression targets vi to have zero mean and unit variance. All experiments use λ = 1.)

5.作者还做了softmax和SVM的对比实验:
实验如何做:在fine-tune的时候使用sotfmax classifier 来代替one vs rest SVM
实验结果分析:


从第一行和第二行可以看出,SVM更合适对于没有进行ROI pooling的R-CNN,(为什么呢?是不是因为难例挖掘的更合理呢?并且对于小模型其效果会优于fast RCNN,但是对于例如VGG16这种模型来说效果已经不如fast RCNN了。)从第二行和第三行可以看出softmax的效果略好于SVM,但是考虑到softmax是end2end训练比较方便,不需要额外的空间来存储中间的特征。所以后面的人都选择softmax。

对后面未来的作用:
1)从这个实验也可以看出,判断一个结构是否真的有效,还得在不通模型规模(S,M,L)上面进行实验。
2)softmax略好处SVM,基于其训练方便,不需要额外空间,后面建议使用softmax

训练的样本的选择:

这里实验一分别采用了三种训练集:
1)07\dif 这里面训练集去除了标记为difficult的样本进行训练,实验结果有提升,说明对于训练集中为difficult的样本确实是为噪声(这里可以继续研究difficult的样本的特性是什么,为什么会是噪声而不是提高难例可以提高样本的鲁棒性呢?)
2)07+seg:加上分割的信息可以提高检测的效果,具体方法可以参见:Exploiting segmentation and context in deep neural networks for object detection. In CVPR, 2015
3)扩大数据集,07++12,效果有提升,不过你可能会问,样本集是越多越好吗?在fast RCNN中作者也在5.3“Do we need more data?”说明在目前为止增加数据集是有效果提升的。

训练时间和测试时间的实验:

提升训练的时间:

之前RCNN和SPP-net构造mini-batch size为R,那么随机选择 R/4 的正类别样本,R*3/4的背景样本。这些样本可能来自很多张图片,但在这里,为了获得样本的深度特征,需要做的前传次数是 R 次。
1. Fast RCNN 的mini-batch,提出一个加快训练的方法
Hierarchical sampling :Sampling N images,then samping R/N ROIs from each image
具体做法:在一次batch个数为R,采样n个图片中,那么在每张图片采样R/n个ROI,这样相同图片里面的ROI可以共享权值计算,这样减少计算量,来加快训练。因为现在一次前传可以获得一张图片内所有 proposal 的深度特征,因此希望利用这个特性来加速训练过程。例如,对R=128,N=2,那么原有方式做128次前传,现在只做2次前传。实现了64倍的加速。(但是这样又会有一个小问题,当一张图片如何没有R/n个ROI怎么办?文中没提,不过这个应该只是工程上面的问题吧,一张解决方式是重复采样。另外,这样的话一个batch里面的ROI的多样性被限制了,这样会对训练结果的收敛有影响吗?文中有提到实际上影响不大,当N=2的batch=128的时候的已经取得了比RCNN更好的检测效果了)
2. 作者为什么可以想到这个方法呢?
作者可能也是看到了R-CNN的训练时候也出现了很多重复的计算,和检测的时候是费时是一个道理的,因为训练的时候也需要前向传播然后在反向推导。所以也可以如法炮制利用共享计算的方法来使得训练速度得到提高提出了分层采样的方法。

提升检测的时间:

实验内容:对模型进行训练时间和测试时间上面的进行度量,提出了SVD来加速全连接层的计算。
实验的原因: 由于fast RCNN一个主要的贡献也是速度比较快,提出了分层采样的mini-batch,所以对自己这一时间上面的贡献进行实验加以说明。
实验如何做:
1)作者分别设计了pre-trained的不同的3种模型,分别是S,M,L对应Alex Net CNN_M_1024,VGG16,然后用fast RCNN和RCNN和SPP-net进行对比。
2)设计了truncate SVD进行全连接进行网络的加速
你有可能会问:作者为什么要额外设计S,M,俩那个版本,不直接进行L版本的对比呢?
我觉得可能是因为最初的RCNN是使用S版本的进行。一方面也可以验证不同的pre-train的模型对检测效果有什么影响。
这也告诉我们实际上提出一个新的贡献实验最好在S,M,L不通网络结构复杂度上面进行实验,才能更有力的证明你的结构的有效性。

实验结果分析:

检测之旧文新读(三)-Fast R-CNN_第10张图片

从结果可以看出,速度比RCNN提升了大概100的量级。主要得益于ROI pooling,对比SPP-net速度提升了20左右,主要得益于SVD的加速。
1)VGG16对但是的目前来说,作为前置特征网络提取效果最好,现在是resNet用的比较多。
2)SVD的方法可以提高全连接层的速度,也为后来的模型加速提供一个方向。
但是针对加速来说,SVD如何进行加速的呢?下面进行说明.

Truncate SVD 加速

**实验目的(作者为什么做这个实验):对于网络的速度测试:


检测之旧文新读(三)-Fast R-CNN_第11张图片

作者发现卷积层虽然只有两层但是却占用了相当一部分测试的时间,所以就思考是否有办法进一步优化节省时间。

实验步骤:这一段解释说明也引之博客[2]
①物体分类和bbox回归都是通过全连接层实现的,假设全连接层输入数据为X,输出数据为Y,全连接层权值矩阵为W,尺寸为 u × v ,那么该层全连接计算为:Y = W × X
②若将W进行SVD分解(奇异值分解),并用前t个特征值近似代替,即:


U是 u × t 的左奇异矩阵,Σt 是 t × t 的对角矩阵 ,V是 v × t 的右奇异矩阵。
检测之旧文新读(三)-Fast R-CNN_第12张图片

截断SVD将参数量由原来的 u × v 减少到 t × (u + v) ,当 t 远小于 min(u,v) 的时候降低了很大的计算量。

在实现时,相当于把一个全连接层拆分为两个全连接层,第一个全连接层使用权值矩阵

(不含偏置),第二个全连接层使用矩阵U(含偏置);当RoI的数量大时,这种简单的压缩方法有很好的加速。
实验表明,SVD分解全连接层能使mAP只下降0.3%的情况下提升30%的速度,同时该方法也不必再执行额外的微调操作。

其他实验:

1.尺度不变性的实验:

实验内容:单一尺度的训练和测试和多尺度图片的训练和测试

实验的原因:因为现在fast RCNN是允许任意的图片输入的,那么输入多大才能有更好的检测呢?(遇到“任意”,往往都有必要进行进一步的研究。是否有什么指导性意见使得存在任意中较好的值呢?)

实验如何做:对于单一尺度的,保持长宽比,然后令最小边为600,最长边不超过1000(这个限制主要是因为GPU的容量),然后进行训练和测试。另一组是使用分别如下:(最短边分别为 {480, 576, 688, 864, 1200}) 最长边不超过2000。然后进行mAP结果的对比。

是你为怎么做: 作者制作了两组实验:一组训练与测试都是单一尺寸,一组训练和测试都是多尺寸。其实这里其实还缺少一组对比试验,就是训练使用多个尺度,但是测试就使用一个尺度。如果是我,我会加上这个实验。

实验结果分析:

检测之旧文新读(三)-Fast R-CNN_第13张图片

就是进过多尺度的训练和测试,所提升大概1mAP是比较有限的,但是时间上面牺牲了很多。所以神经网络在学习的时候,已经学习到一定的尺度不变性了。

这个实验对未来的帮助:其实后面训练的时候可以进行多尺度训练,检测的时候可以使用单一尺度为了提高速度。在速度要求不是很搞,精度要求很高的情况下,可以使用多尺度检测。

2.哪一层进行fine-tune的实验:

实验内容:验证一下fine-tune的时候不同的卷积层的更新对最后检测结果的影响(对于VGG16这种深层网络)。
实验动机:因为spp-net在fine-tune的时候只更新了全连接层而没有更新卷积层,而作者提出来的方法,可以即更新卷积层和全连接层,所以为了验证自己的这种方法的贡献,所以有必要进行这个实验
实验如何做:作者分别固定不同卷积层,让其无法更新学习,来比较最后的检测结果。
实验结果分析:

检测之旧文新读(三)-Fast R-CNN_第14张图片

可以看出从conv3_1 进行卷积层更新和值更新全连接层提升了>5.0mAP 所以fine-tune的时候是很有必要更新卷积层的。
你可能会问:是不是全部卷积层都要进行训练才好呢?
作者的回答是NO,但是NO主要是从训练时间和GPU空间时间上面进行考虑,如果对于S和M的模型,那么更新conv1其实对结果没有影响,对于VGG16 从conv2_1更新对比conv3_1更新,仅提升0.3,但是训练时间和GPU使用都上升了不少。但是总体来说效果没有下降。
你可能会问:为什么会造成这样的实验结果:
作者的回答是说在conv1浅层中,他们反向传播回来的梯度更新其实是很慢的,所以没有必要。
那么我们是否可以利用resnet(的skip layer)就有必要进行浅层的更新了呢?
这个实验对未来的帮助:
对于fine-tune如果训练时间和GPU训练空间没有顾忌的话,可以直接进行训练更新全部的卷积层,特别是对于resnet更是如此。如果对于训练时间和GPU有顾忌,那么对于S,M模型从conv2开始更新,对于VGG16从conv3开始更新。(对于resnet是否有这个特性,毕竟由于skip layer 提高了反向传播浅层的更新力度。所以可能为了达到效果最好需要进行全部网络的更新(有时间做个试验对比一下))

3.是否更多的proposal会更好(有认为因素2000proposals,所以也要做这个实验)

实验如何做:作者使用了selective search(sparse set) 滑动窗口(dense set)等来提取proposals 来进行实验,实验结果是,不需要更多的proposals来进行。而且proposals更多有的时候mAP还略有下降。
你可能会问:既然增加没有意义,那么至少需要多少proposal合适呢?但是这个问题文章没有做实验进行说明?有空也可以自己做做实验,但是感觉这个和具体的数据和实际环境有关系
1)We find evidence that the proposal classifier cascade also improves Fast R-CNN accuracy.(这句话说明级联的proposals貌似可以提升fast RCNN的性能,但是文中没有继续向西的说明)
2)文中提出一个关于检测proposal好坏的指标:Average Recall(AR),但是实验发现AR的提升不能mAP有很好的相关性。但是这篇文章已经被Tpami接收了,后面可以去补一下。

参考文献:

  1. Girshick R. Fast r-cnn[C]//Proceedings of the IEEE international conference on computer vision. 2015: 1440-1448.
  2. http://blog.csdn.net/wonder233/article/details/53671018

你可能感兴趣的:(检测之旧文新读(三)-Fast R-CNN)