Fast R-CNN论文阅读记录

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shiheyingzhe/article/details/83540178

Fast R-CNN:Fast Region-based Convolutional Network method
论文的链接:https://arxiv.org/abs/1504.08083

Fast R-CNN使用VGG16网络,在不考虑使用selective search提取区域建议框region proposals花费的很多时间,仅考虑深度网络时,训练速度比RCNN快9倍,测试速度快213倍(使用TSVD截断奇异值分解);和SPPnet相比较,训练速度快3倍,测试速度快10倍,而且检测结果更加准确。

论文中认为目前很多方法使用多阶段训练的方法很慢。目标检测需要定位类的位置,提高了复杂度。
具有的挑战主要是:
大量的候选目标区域(RoIs即region proposals)需要处理;
这些候选区域仅仅提供粗略的位置坐标,需要提升得到更接近ground truth的位置坐标。

R-CNN的明显不足:

    1、训练分几个阶段,不是端到端的系统,使用region proposals区域微调CNN网络(log loss),然后用输出的特征训练SVM分类器,替代softmax分类层,最后训练bounding-boxes回归模型;
   2 、训练在空间和时间上的花费都很大,每张图片提取约2000个region proposals区域,每个区域生成的特征都要保存到磁盘上,最后用来训练SVM分类器、回归模型。这样做的IO开销大,速度慢,对VGG16网络来说,网络每天只能处理5K张图片(2.5GPU),而且保存提取的特征,需要占用很多磁盘空间;
   3 、目标检测的速度慢,测试图片的每个region proposals都要提取特征。

R-CNN慢的主要原因在于没有共享特征计算,每来个区域,都要CNN重复计算,SPPnet提出的共享特征计算加速了R-CNN,SPPnet输入整张图片到网络当中计算特征图(多通道)。SPPnet全连接层之前的最后一层是空间金字塔池化层:
1、在每个通道中提取出每个候选区域(region proposals)对应的特征图区域;
2、将对应的特征图区域划分为相同大小的部分;
3、在每个部分使用max pooling提取该部分像素的最大值;
4、最后将提取出的最大值向量拼成一行向量。

图中所示就是SPPnet的空间金字塔层,在最后一层卷积层对region proposals对应的特征图,对每个通道分别使用4*4、2*2、1*1的蒙版,提取相应格子中的最大值,然后拼成(4*4+2*2+1*1)*256=21*256维的向量,作为全连接层的输入,256是通道数。SPPnet的主要不足在于:是多阶段训练,要将空间金字塔层提取的特征保存到磁盘中,最后训练SVM和回归器。而且不像R-CNN,SPPnet网络微调的时候,不能更新空间金字塔层之前的参数,梯度很难往后传递,这点限制了检测的准确率。

Fast R-CNN解决不能更新参数的方法是使用简化版本的SPP layer,例:只使用4*4的格子来提取一行向量,不使用金字塔的方式,称作RoI pooling层即感兴趣区域池化层。

贡献:弥补了R-CNN和SPPnet的不足,并且提高了训练、测试的速度和准确率
测试结果取得更好的mAP;训练是单阶段的,端到端的,使用多任务损失函数;训练过程中能更新所有层的参数;中间过程不需要保存特征到磁盘。

架构与训练

RoIs:regions of interest即感兴趣的区域,在原图中的矩形框形状的区域,和R-CNN中的region proposals意思基本相同。
假设需要检测的类有K个
1、使用SS提取感兴趣的区域RoIs,得到相应的位置坐标信息,并根据ground truth,计算和每类的IoU值,得到所属类的信息;
2、输入网络的有整张图片和候选区域(RoIs)的位置坐标信息、所属类信息,图片经过卷积层、pooling层的处理以后产生新的卷积特征图;
3、接着进入到RoI pooling层即感兴趣区域池化层,将RoIs中的候选区域映射到特征图中,然后将该区域划分为指定大小的格子(4*4),接着使用max pooling得出每个格子的值,所有的通道都排列成一行,作为全连接层的输入
4、全连接层有两个输出,一个是进入到softmax层产生属于某类的(K+1)个概率值(K+1类,其中有背景类),另一个输出层对每类产生4个值,共有(4*K)个值,每类的4个值用来提升bounding boxes的精确度,使之更接近ground truth。

RoI pooling

使用最大池化将任何RoI区域对应的卷积特征图转化为固定大小的比较小的特征图(H*W),H和W是独立于RoI pooling层的参数,不需要学习。
本篇论文中RoI区域是在原图中的一个矩形框的区域,有相应的坐标信息(r,c,h,w),左上角的坐标(r,c),h、w分别是高和宽,找到这个RoI区域对应的卷积特征图,也是矩形的。假设这个特征图是64*64大小的,想得到的是4*4的输出,那么就有16个格子,每个格子(64/4,64/4)是256个像素,对每个格子使用max pooling,就得到4*4的输出。对256个通道进行同样的操作,得到的输出向量是4*4*256维,作为全连接层的输入。

使用预训练网络初始化Fast R-CNN

1、将VGG16网络最后一层max pooling层更改为RoI pooling层,设置H、W为7*7(VGG16),这样设置是为了和第一层全连接层的输入维度保持一致。
2、网络最后的全连接层和softmax(ImageNet中是1000类分类)更改为两个同级的输出,包括全连接层+softmax分类(K+1)类,类独立的bounding boxes回归层(4*K)
3、网络调整为两个输入:一个mini-batch的整张图片数据,以及相应图片相应的RoIs区域信息(位置坐标和所属的类)

微调fine-tuning

参数传播:Fast R-CNN网络中的所有参数都可以被更新,SPPnet网络不能更新SPP层之前层的参数,原因是当每个训练样本来自不同的图片时,SPP层向后传播的效率不高,多个金字塔层会导致梯度几乎无法向后传播。

mini-batch组成:训练的时候使用特征共享即输入是整张图片,每次SGD随机梯度下降迭代,mini-batch中采用层次抽样,每次抽取N张图片,然后从每张图片的RoIs当中分别抽取(R/N)个RoIs,当N=2和R=128时,从每张图片抽取64个RoIs。这样输入训练的速度比N=128,R=128(每张图片抽取一个RoI),快64倍。实验表明,N=2,R=128的效果优于R-CNN。
训练的过程是端到端的,fine-tuning的同时加上softmax分类层和bounding boxes回归层一起训练,而不是像R-CNN那样分三个阶段:微调、SVM、bounding-boxes回归

多任务损失:有两个输出层,那么就有两个损失loss函数,第一个输出层是在(K+1)类的概率分布(每个RoI都有),p=($p_0,p_1,...,p_K$),p是由全连接层+softmax层的(K+1)个输出。第二个输出层是bounding boxes回归层,$t^k=(t_x^k,t_y^k,t_w^k,t_h^k),k\in(1,2,...,K)$$t^k=(t_x^k,t_y^k,t_w^k,t_h^k),k\in(1,2,...,K)$$t^k$的定义是目标移动量,在SS确定RoIs的时候,每个RoI区域都会包含真实的类标签信息u和相应的bounding boxes回归信息v,对每个打好标签的RoI区域,使用多任务损失Loss(分类损失+回归损失):
L(p,u,$t^u,v$)=$L_{cls}(p,u)+\lambda [u\geqslant 1]L_{loc}(t^u,v)$$L_{cls}=-logp_u$
其中p是分类中softmax产生的(k+1)个概率值,其中p和$t^u$是目标值,uv是网络的输出。

第二项Loss中的[u\geqslant 1]的计算是:如果u\geqslant 1,则为1则为1,否则为0。因为u的值只在是背景类的时候才会被记做0,所以[u\geqslant 1]理解起来就是非背景类的就是1,背景类是0。当为0时,不计算第二项损失值就是不计算回归的损失,背景类当然是没有位置信息的,所以背景类的$L_{loc}$被忽略。\lambda是控制两个损失的占比,这里使用的是\lambda =1

$L_{loc}(t^u,v)$=\sum_{i\in\{x,y,w,h\}}$smooth_{L_1}(t_i^u-v_i)$      $smooth_{L_1}(x)\left\{\begin{matrix} 0.5$x^2$ & if\mid x\mid< 1\\ \mid x\mid-0.5&otherwise, \end{matrix}\right.$
回归使用的损失函数$L_{loc}(t^u,v)$是平滑以后的平方和,在0处可导,不至于使用绝对值损失在0点处没有导数,这么做更加健壮。

mini-batch抽样的细节:
微调的时候说过N=2张图片,mini-batch=128,每张图片抽取64个RoIs区域。和R-CNN论文中抽样方法一致,128个RoIs当中,有1/4的是正样本(32个),也就是说每张图片需要拿出16张正样本(IoU>0.5)和48张负样本(背景)的RoIs,这25%的正样本是从和ground truth的IoU值大于0.5的RoIs中抽取的,这些RoIs由带有标签的前景类组成。剩下的75%的RoIs是从和ground truth的IoU值在[0.1,0.5)之间的RoIs当中抽取的,这些类$i^*(r,j)=argmax_{i'\in R(r,j)}x_{i'}$被记做是背景类。当损失函数中的u=0时(即为背景类),不计算回归的损失。0.1的由来,似乎是受到困难样本的启发。在训练过程当中,会有0.5的概率会水平翻转图片,没有使用其它的数据增强。

梯度从RoI pooling层反向传播,个人的理解是反向传播的时候,RoI pooling层的梯度会传到相应的激活值那里,假设之前的卷积特征图的一个通道是64*64,分割为4*4的格子,对每个格子应用max pooling,每个格子都会有最大的像素值,这些像素值在原特征图中对应的索引就是(a11,...,a14,...,a44),得到输出16维向量,这16维向量反向传播梯度的时候,只将梯度传给索引所在的像素值(a11,...,a14,...,a44)。
公式化的表达:这里的输出指RoI pooling层的输出,在一个mini-batch中,一张RoI标记为r,整张图片经过最后一个卷积层以后会产生多通道特征图,同样r相对应的特征图也是多通道的。r的第j个输出(共 4*4*通道数 维)记做$y_{rj}$$R(r,j)$是第j个输出对应特征图的对应格子的所有像素索引(包括通道数,格子中的像素坐标)集合。

$i^*(r,j)=argmax_{i'\in R(r,j)}x_{i'}$,由于$R(r,j)$是r第j个输出对应的格子索引,这个式子表达的是该格子中最大值的索引,所以r的第j个输出$y_{rj}=x_{i^*(r,j)}$。即r第j个输出对应的格子的最大值是输出。

RoI pooling层的反向传播函数计算损失函数相对于多通道特征图中每个像素$x_i$的偏导数
\frac{\partial L}{\partial x_i}=\sum _r\sum _j\left [ i=i^*(r,j) \right ]\frac{\partial L}{\partial y_{rj}}
\left [ i=i^*(r,j) \right ]这个式子的意思是如果像素x_i是一个格子中的最大值,则为1累加偏导数,不是则为0。对每个mini-batch中的r中的每个RoI pooling层的第j个输出,如果i是对应格子中最大值的索引导数会累加。

尺度不变
有两种方法实现检测过程中的尺度不变,通过“蛮力”学习;通过图像金字塔。提供近似的尺度不变。测试的时候,对每个目标区域使用图像金字塔近似尺度规范化。在多尺度训练过程中,由于论文作者的GPU限制,仅在小网络中使用,每次对一张图片随机应用金字塔尺度。

Fast R-CNN检测

在微调完成以后,检测仅仅只是运行前向计算(假设所有的RoIs都已经提前计算好),网络的输入是整张图片或者图片金字塔集合,以及相应的RoIs类别和坐标信息。
测试的时候,输入包含大约2000个RoIs信息,也有可能更多,当使用图片金字塔的时候,每个RoI分配比例,这样缩放以后的RoI更接近224*224。对每个测试的RoI r输出一个(K+1)类的后验概率p(softmax),以及相对于r的包围盒预测量(每个类都会给出提升后的包围盒预测结果),r属于每一类的置信度为Pr(class=k\mid r)\triangleq p_k,接着对所有RoI的结果,设定阈值删除置信度过低的RoIs,然后以类为组,分别使用NMS删除该类中和top得分IoU值过大的RoIs区域。

截断SVD(TSVD)加快计算
在常规的图像分类中,计算全连接层所用的时间远远小于计算卷积层花的时间。相反的是,目标检测中,网络处理大量的RoIs所用的时间长,计算全连接层几乎占据了前向计算时间的一半。使用TSVD可以不使用全部的奇异值,通过压缩加速全连接层的计算。减少将近30%的计算时间。

主要的实验

微调的网络层
SPPnet只有全连接层进行了微调,已经足够取得较好的准确率(不太深层的CNN),猜想对深层网络(VGG16)是不够的。
验证微调卷积层是重要的:对网络VGG16,模拟单尺度SPPnet训练,冻结第13个卷积层,只微调全连接层,结果显示mAP下降,表明仅仅只微调全连接层是不够的,还需要微调卷积层的参数。对较深网络训练时通过的RoI pooling层是重要的。但不是微调所有的卷积层都是重要的,在小网络当中,发现第一层卷积层是泛型的且和任务无关,对于卷积层1,微调或者不微调,对mAP没有影响。
论文发现对VGG16,更新con3_1及以上的参数(13层中的9层)是必要的。
一些实验结果:卷积层con2_1及以后微调会减慢训练速度(和con3_1相比较),mAP只增加了0.3%。论文中的(VGG16)结果均是为微调con3_1及以后层的结果,对于小网络和中型网络微调con2_1及以后。
包括些在不同数据集VOC07, 2010, and 2012、不同网络、不同训练集中的验证结果。

设计验证

多任务训练是否有帮助?为什么两个损失值要加在一起?为什么要分类和回归一起训练,而不先训练分类,再训练回归?
至少是方便的,因为可以避免管理按顺序训练的多任务流程,而且它也有改善结果的潜力,因为任务之间通过共享网络层相互影响。
设计对照实验,训练基准网络仅仅只有分类损失,没有回归损失\lambda =0。S、M和L分别代表小网络、中型网络和大网络(VGG16)。实验表明先单独训练分类,然后固定网络和分类的参数,训练回归,效果没有一起训练的好。
表格中每行的意思是:多任务同时训练?分阶段训练?测试时使用回归?VOC2007数据的mAP。像52.2这一列,就是基准网络训练的结果。没有多任务,也没有分阶段,只单独训练分类。第3列是分阶段,先训练分类然后训练回归,测试使用回归,效果没有第四列的好(Fast R-CNN)。

尺度不变:蛮力训练或者使用图像金字塔(多尺度缩放)
实验表明:单尺度训练的结果和多尺度训练的表现几乎一致,深度卷积网络更擅长直接学习尺度不变,多尺度训练的结果仅仅提高一点点mAP,但花费在计算上的时间更多,得不偿失。因此单尺度训练在精度和速度上都有很好的表现。

是否需要更多的训练数据:这个是肯定的,深度学习本来就是数据驱动的,一个好的检测模型在得到更多的训练数据以后,应该有更好的表现。

SVM分类和softmax分类哪个更好:softmax比SVM略好,端到端的训练表现更好,而且给RoIs打分时引入了类间的竞争

更多的候选区域是否更好
有两种类型的目标检测器,一种使用稀少数目的目标区域(SS);另一种是使用密集型目标区域(DPM)。前一种使用稀少区域训练的检测器是级联的。级联分类提高了Fast R-CNN的准确率。
使用SS(质量模式),网络是M中型网络,提取的RoIs数量从1k到10k,发现mAP上升以后会轻微下降(蓝色实线)。当RoIs增加时,对分类没有太多的帮助,甚至会有损准确率。
mAP和Average Recall没有太多联系,(红色线)AR只表明有更多的区域被选到,需要谨慎使用AR。
当使用密集型boxes,效果下降很多(蓝色虚线),boxes的数量从2k到45k。后期mAP下降的很多。其中Fast R-CNN仅仅使用密集型boxes(45k个)训练时,mAP=52.9%,(蓝色菱形框)。如果还使用SVM,效果更糟糕。
尽管如此仍然有可能存在尚未发现的技术,能让密集型数据集训练的效果和松散型数据集训练的效果相同。

 


 

猜你喜欢

转载自blog.csdn.net/shiheyingzhe/article/details/83540178