Fast R-CNN论文解读

妖精的绣舞 提交于 2019-11-28 14:05:19

论文链接:https://arxiv.org/abs/1504.08083
代码链接:https://github.com/rbgirshick/fast-rcnn.

Abstract

这篇论文提出了一种基于卷积神经网络做目标检测的算法——Fast R-CNN,它是建立在之前R-CNN的基础上使用深度卷积神经网络进行高效的目标检测。Fast R-CNN做了几点创新来提高训练和测试阶段的速度,同时提高了检测的准确率。

  1. Fast R-CNN使用的是VGG16网络,训练速度比R-CNN快了9倍,测试速度快了213倍,并且在PASCAL VOC 2012上实现了更高的map;
  2. 与SSPnet相比,Fast R-CNN训练速度快了3倍,测试速度快了10倍,并且准确率更高;

1. Introduction

目前深度神经网络已经极大的提高了图形分类和目标检测的精度,与图像分类相比,目标检测明显更为复杂,现在的方法在训练网络时会分多个阶段,这样会导致训练和运行时间过长。

目前检测有两个最基本的挑战:

  1. 如何产生候选框;
  2. 候选框只是提供了一个粗略的定位范围,所以需要进一步的修正才可以得到更精确的定位,这意味着我们的方法需要在速度、精度和简单性之间做权衡;

在本片论文中,我们简化了训练过程,提出了以一种单阶段的训练算法——分类和边框回归的loss合并,梯度回传。

1.1 R-CNN and SPPnet

在谈Fast R-CNN之前,我们先来说说R-CNN存在的问题:

  1. 训练分多步。通过上一篇博文我们知道R-CNN的训练先要fine tuning一个预训练的网络,然后针对每个类别都训练一个SVM分类器,最后还要对每个类别用regressor模型对bounding-box进行回归(分类和边框预测是分开的,但实际上两者之间是有联系的,是个待解决问题),另外region proposal也要单独用selective search的方式获得,步骤比较繁琐。
  2. 时间和内存消耗比较大。在训练SVM和回归的时候分别需要用网络训练得到的fc7和pool5层的特征作为输入,特征保存在磁盘上再读入的时间消耗还是比较大的。举个例子,当使用深度神经网络(如VGG16),对于5k张VOV07训练集上的图片做训练大约需要2.5GPU-days。这些特征需要上千GB的存储空间。
  3. 测试的时候也比较慢,每张图片的每个region proposal都要做卷积,重复操作太多。用VGG16做检测一张图片需要47s。

制约R-CNN速度的一个重要因素在于每个候选框(大约2000个)都需要经过卷积神经网络,这里面没有共享计算,里面有大量的冗余计算(有很多重叠部分)。空间金字塔层池化网络(Spatial pyramid pooling networks,SSPnets)可以通过计算共享来加速R-CNN,SSPnet是先对整张图片做卷积,由于卷积池化之后得到的特征图与原图片的特征位置是相对应的,所以直接在特征图上截取候选框,然后再使用做不同尺寸的最大池化将得到的特征向量拼接得到最终的特征向量。SSPnet相比于R-CNN测试速度加速了10-100倍,训练时间较少了3倍。
在这里插入图片描述
但SSPnet也有和R-CNN类似的缺点,训练过程是一个多阶段的,涉及特征提取、使用交叉熵损失函数调优、训练SVM,最后再做边框回归,特征向量需要写入磁盘。但是不像R-CNN,在SSPnet中的调优算法不能更新金字塔池化层之前的卷积层,不出意料,这使得我们网络的准确率受限很严重。

1.2 共享

我们提出了一种新的训练算法 ,它结合了R-CNN和SSPnet的优势,在提高速度的同时提高了精度。我们将这种方法叫做Fast R-CNN,它具有以下优势:

  1. 比SSPnet和R-CNN都高的map;
  2. 训练是单阶段的,使用了一个多任务的loss;
  3. 训练可以更新所有层的参数;
  4. 特征缓存不需要磁盘存储;

2. Fast R-CNN architecture and training

在这里插入图片描述
Figure1展示了Fast R-CNN的结构,其输入为整张图片和使用SS算法提取的2000个候选框的信息array([r, c, h, w]),其中(r, c)为某个region左上角的坐标,(h, w)为它的高和宽。下图表示了一个图片中的候选框经过一次卷积核池化之后的(r, c, w, h)的变化关系这说明我们根据2000个候选框的信息完全可以在经过多层卷积和池化之后的特征图上得到我们对应的候选框。

边和点映射的具体细节可以参加这篇文章:https://zhuanlan.zhihu.com/p/60919662
在这里插入图片描述接着由于这些候选框大小不一,我们将其送入ROI层(单层金字塔池化)得到统一维度的特征向量,之后再过两个全连接层(4096个神经元)接入两个分支,一个分支为(K+1)个神经元的FC层+softmax,这里的K指的是类别数;第二个分支为4个神经元的FC层,做回归。

2.1 The RoI pooling layer

RoI最大池化层就是将原来尺寸为 h x w的RoI窗口划分为 H x W的网格大小,然后在每个小格子范围内通道独立的做最大池化得到 维度为H x W x 通道数的特征。

2.2 Initializing from pre-trained networks

作者使用有5个最大池化层和5到13个不等的卷积层的三种网络进行预训练:CaffeNet,VGG_CNN_M_1024,VGG-16,使用这些网络初始化Fast R-CNN前,需要以下修改:

  1. 用RoI pooling layer取代网络的最后一个池化层;
  2. 最后一个FC层和softmax被替换成fast R-CNN框架图介绍的两个并列层;
  3. 输入两组数据到网络:一组图片和每一个图片的一组RoIs;

2.3 Fine-tuning for detection

为什么SPPnet不能更新金字塔池化之前的卷积池化的参数?论文中提到当每个训练样本(即RoI)来自不同的图像时,通过SPP层的反向传播非常低效。低效源于每个RoI可能具有非常大的感受野(接收区),通常包括整个输入图像。由于正向传播必须处理整个感受野,训练输入是非常大(通常是整个图像)。

我们提出了一种更加高效的训练方法,它可以在训练中共享特征。在Fast R-CNN训练中,一个minibatch的R个RoI来源于N张图片,即从每张图片中采样R/N个RoIs,而来自同一张图片的RoI在前向和反向传播中可以贡献计算和内存,通常N=2,R=128,这样的训练方案通常要比从128张不同图片中采样快64倍。

另外除了分层采样,Fast R-CNN将分类、回归放在一个网络中(loss合并),而不像原来那样单独训练分类器、回归模型。

Multi-task loss

Fast R-CNN有两个并列的输出层,第一个输出层的输出的是(K+1)维度的向量,它是由最后一个全连接层的输出再过一个softmax得到,p=(p0, p1,…,pk),分别代表该RoI属于背景类、第一类、…、第k类的概率;第二个并列层的输出边框回归的偏移量,对每个类k都输出四个偏移量:
在这里插入图片描述
对四个偏移量不了解参加我的博客:https://blog.csdn.net/h__ang/article/details/89071664

每个RoI都有一个ground-truth class u ( u 不是一个概率分布,而是一个数字,为0是代表是背景,为1-20是代表所属的类别)和一个ground-truth bounding-box 回归目标v。我们的多任务损失由分类损失Lcls和回归损失Lloc构成:
在这里插入图片描述
其中:
在这里插入图片描述
(1)式中的超参数 lamda用来控制两种任务损失的平衡,我们会对ground-truth regression targets vi归一化使之均值为0,方差为1的,实验中所有的 lamda = 1.

Mini-batch sampling

每个minibatch包含128个RoIs,来源于两张图片(随机抽取的),即从随机抽取两张图片的同时从每张图片各抽取64个RoIs。那么对于每个候选框的类别标签如何确定呢?如果一个候选框和这张图片里面所有的ground truth的IoU都小于0.1,那么就舍弃掉这个候选框,不会用它作为样本(低于0.1的IoU作为难例挖掘的启发式);[0.1, 0.5)的作为负样本,类别标签u=0;[0.5, 1]的作为正样本,u>=1(如果一个候选框和多个ground truth的IoU都大于等于0.5,那么该框的类别与IoU最大的groud truth的类别一致)。我们一个minibatch中的128个RoIs有25%是正样本,75%是负样本。另外只采用随机水平翻转的方式增加数据集。

Back-propagation through RoI pooling layers

先贴一个CNN卷积层和池化层如何进行反向传播的链接:https://blog.csdn.net/legend_hua/article/details/81590979

我们先来假定一些符号:xi表示RoI池化前的特征图上的像素点,yrj表示第r个RoI池化后的第j个的像素点,RoI的前向传播是在做:
在这里插入图片描述
i*(r,j)的意思是如果第r个RoI的第j个像素点的来源,它是最大池化时选出的最大的那个点对应的坐标;这里类比到CNN中标准的最大池化层的反向传播,那它就应该是:
在这里插入图片描述
但是由于在这里,一个RoI池化前的像素点xi可能和多个不同的yrj有映射关系(因为存在多个候选框,候选框之前可能有重叠),因此反向传播过程的公式为:
在这里插入图片描述
到了这里,我想谈一下我遇到的坑,前面说到过,回归部分的输出是84个节点,也就是说对于每一个候选框会产生84个输出,分别代表每一个类的偏移量(21*4=84),那么就存在一个问题,回归时标签是什么?也是一个84维度的向量吗?而这个向量又是如何构造的?这个问题有很多种理解方式,训练时我们可以把回归的真实标签看作是4维的向量(该候选框与同类的ground-truth之间的偏移和缩放量),而对于每个候选框会输出一个84维度的向量,在计算回归部分的损失函数时,我们选择性截取该类别的对应的84维向量中的四个值,使用上面的等式(2)计算损失(比如对于类别1我们截取84维向量中的3-7位置上的值);再换个角度理解,真实标签也可以是84维的向量,可以将其余80个位置上的量全部置0,而在计算损失函数时根据类别分别截取两个84维向量中对应部分的值。

SGD超参数

  • 用于分类和回归的全连接层的权重按照0为均值,标准差为0.01和0.001初始化,偏置都初始化为0;
  • 在PASCAL VOC 2007和2012训练时,前30k次迭代全局学习率为0.001,每层权重学习率为1倍,偏置学习率为2倍,后10k次迭代全局学习率更新为0.0001;
  • 动量设置为0.9,权重衰减设置为0.0005;

2.4 尺度不变性

作者提出了使用两种方式对规模不变的对象进行检测:brute-force(单一尺度)和image pyramids(多尺度,图像金字塔)。

单一尺度直接在训练和测试阶段将image预先固定好像素大小,直接输入网络训练就好,然后期望在训练过程中网络自己能够学习到尺度不变性scale-invariance;多尺度在训练阶段随机从图像金字塔【缩放图片的scale得到,得到多尺度图片,相当于扩充数据集】中采样训练,通过一个图像金字塔向网络提供一个近似的尺度不变,在测试阶段图像金字塔用来对每个object proposal近似尺度归一化,训练阶段每次采样一个图像就随机采样一个金字塔尺度。

作者在5.2节对单一尺度和多尺度分别进行了实验,不管哪种方式下都定义图像短边像素为s,单一尺度下s=600【维持长宽比进行缩放】,长边限制为1000像素;多尺度s={480,576,688,864,1200}【维持长宽比进行缩放】,长边限制为2000像素,生成图像金字塔进行训练测试;实验结果表明AlexNet【S for small】、VGG_CNN_M_1024【M for medium】下单一尺度比多尺度mAP差1.2%~1.5%,但测试时间上却快不少,VGG-16【L for large】下仅单一尺度就达到了66.9%的mAP【由于GPU显存限制多尺度无法实现】,该实验证明了深度神经网络善于直接学习尺度不变形,对目标的scale不敏感。

第2中方法的表现确实比1好,但是好的不算太多,大概是1个mAP左右,但是时间要慢不少,所以作者实际采用的是第一个策略,也就是single scale。

SVD分解

在这里插入图片描述图像分类任务中,用于卷积层计算的时间比用于全连接层计算的时间多;而在目标检测任务中,要处理的RoI数量比较多,几乎有一半的前向计算时间被用于全连接层(Fig . 2)。就Fast R-CNN而言,RoI池化层后的全连接层需要进行约2k次(每个RoI都要计算),因此在Fast R-CNN中可以采用SVD分解加速全连接层计算;

实验结果

在这里插入图片描述
参考文章:
https://blog.csdn.net/Wonder233/article/details/53671018
https://zhuanlan.zhihu.com/p/60968116
https://blog.csdn.net/u014380165/article/details/72851319

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!