论文名:Fast R-CNN
论文作者:Ross Girshick
期刊/会议名:ICCV 2015
发表时间:2015-9
论文地址:https://arxiv.org/pdf/1504.08083
源码:https://github.com/rbgirshick/fast-rcnn
摘要
这篇论文提出了一个快速的R-CNN网络,也就是Fast R-CNN用于目标检测任务。Fast R-CNN使用了深度卷积神经网络来高效地对候选区域进行分类。并且与之前的工作相比,Fast R-CNN既能提高训练和测试时的速度,又能增加检测的精度。在当时比较典型的目标检测算法就是R-CNN和SPPnet,所以接下来就举了R-CNN和SPPnet这两个例子,来对比说明Fast R-CNN速度有多快。比如与R-CNN相比,Fast R-CNN在训练时能够快9倍,在测试时快了213倍。与SPPnet相比,Fast R-CNN训练时快了3倍,测试时快了10倍。所以说Fast R-CNN在当时与其他的目标点这模型相比,速度又快,精度又高,在当时是一个比较优秀的算法。
1.引言
1.1.R-CNN and SPPnet
分别写了R-CNN和SPPnet的缺点。
比如在这里先是R-CNN有一些缺点,然后在下面这里又写了SPPnet也有一些缺点。因此作者提出了一种新的训练方法来解决R-CNN和SPPnet的这个缺点,这个新的方法也被称为Fast R-CNN。
先来看一下R-CNN具体的这三个缺点,其中前两条都是在算法训练时的缺点,第三条是算法测试时的缺点。我们之前在讲R-CNN论文的时候,有提到AlexNet的算法在训练时是分了不同的多个阶段的。首先是训练了一个CNN用来提取候选区域的特征。等这个cnn训练好后再提取整个数据集上所有区域的特征,然后利用特征来额外训练一个SVM网络来对候选区域进行分类。如果是R-CNN BB算法的话,它还会有第三个阶段,也就是训练一个框回归的模型用来回归出候选框的精确位置。所以说整个网络的训练过程是一个多阶段的训练过程,因为它要先训练CNN再训练SVM,最后还要训练一个框回归器,在训练svm和框回归模型的时候,是不是需要把每一张图片上的每一个候选框的这个特征都给它去提取出来,等这些特征都被提取出来后才能训练后续的模型,所以利用CNN提取到这个特征需要先把它写到磁盘里,供后续训练使用。所以在训练过程中会耗费大量的空间来存特征,会耗费大量的时间来提取特征。
R-CNN测试流程:
对于一张测试图片,R-CNN也需要先产生2000个候选区域,每个候选区域都需要通过这个CNN的前向传播来提特征,因此测试一张图片的速度也会特别慢,导致一张图的测试时间可能会达到47秒。通过刚刚对这三条的分析,我们可以看出来,R-CNN它之所以慢,是不是很大程度上都是因为它需要使用一个CNN来前向传播,提取每一个候选区域的特征,没有用到共享计算。因此后续提出的SPPnet这个网络,就尝试通过共享计算来加速R-CNN的训练和测试过程。
SPPnet的改进思路:
这里是SPPnet论文里的一个网络结构图。它的核心其实就是引入了一个这个spp层,也叫空间金字塔池化层。R-CNN里的CNN它其实就是AlexNet或者VGG这种图像分类网络,它本质上就是几个CNN跟上一个最大尺化层,几个CNN跟上一个最大石化层,然后这样不断堆叠的这种形式,最后再跟上几个全连接层的形式,然后在这里是横着把这个网络画出来了。然后在SPPnet这里它是竖着画了一个网络,在这里也是这种卷积层加上最大石化层,不断的堆叠,...,在最后再跟上了几个全连接层的形式。所以说SPPnet的这个网络结构跟R-CNN里的CNN其实几乎是一样的,它们唯一的区别就是R-CNN里的这个CNN,它在原先的这个全连接层的前面是一个最大值化层,但是在SPPnet这个网络里,全连接层前面的最后一个最大石化给替换成了一个空间金字塔池化层,这个空间金字塔纸化层的优点就是当你传入一张图片,通过一些卷积层和池化层,在最后通过一个卷积层的时候,假如得到了一个13x13x256通道的这么一个特征图,在这里只画了其中的一个通道。
正常在R-CNN的情况下,它会使用一个3x3大小,步长为2的一个最大池化层把13x13x256通道的特征图变成6x6大小的一个特征图,然后再把最后池化的这个结果拉平后,传给全连接层,获取最终的一个图片特征。这个SPP层它本质上就是限制了输出尺寸,也就是说它采用了一个动态的池化和尺寸。比如想从13x13的这个图中得到4x4大小的特征图,那么只需要使用13÷4,再向上取整的这么一个值来作为池化合的一个尺寸,也就是43÷4,再向下取整的这个值也就是三来作为池化后的步长,然后以这个尺寸为4,步长为3的一个池化后去在13x13的特征图上做池化运算,最后就会产生一个4x4大小的输出特征图,这个2x2和1x11大小的输出特征图也是同理,通过这种方法可以算出来。所以说这个空间金字塔池化层的池化后的尺寸和步长是一个动态变化的过程,它会根据输出特征图的尺寸来动态的改变池化合的尺寸和步长,在得到4x4大小,2x2大小和1x1大小的一个特征图之后,再把这些特征给拼接起来,就形成了一个固定长度的一个特征了,然后再把这个特征给传给后续的全连接层来形成最终的一个候选区域的图片特征。所以说有了这种空间金字塔池化层,就可以输入任意大小的图片了,因为输入任意大小的图片后,不管最后得到这个特征图是多少,都可以通过这一层来把它产生一个固定大小的一个输出,最后得到一个固定大小的一个特征。
既然不需要像R-CNN这样去限制cnn的输入尺寸了,那是不是可以换个思路就是不传候选区域进去而是直接把整幅图片给传到CNN当中,比如在原图上候选区域是这一部分区域,原图最后产生的这个特征图,它这个候选区域的特征也就是这一部分的区域,因此就可以直接把候选区域的特征图抠出来就可以了,由于不同位置最后得到的候选区域的这个尺寸是不一样的,但是正好可以利用这个SPP层把不同尺寸的特征图给转换成特定大小的一个输出,就可以只用把一整张图传进去给CNN,然后在CNN里只使用这一整张图进行一次前向传播,然后计算整张图的一个特征图,最后再把各个候选区域的特征给抠出来就可以了,也就是在整张图上共享计算了,这就是SPPnet最终采用的一个方法。
SPPnet不是像R-CNN一样把每一个候选区抠出来后再传给CNN去进行一次前向传播提取特征。这就解决了R-CNN的第三个问题,也就是在测试图片的时候不需要把每个区域都给传入到CNN中进行预测了,只需要传一整张图进去就就可以了。虽然解决了第三个问题,但是SPPnet还是有一些缺点的,首先像R-CNN一样,SPPnet的训练过程还是一个多阶段的过程,因为在最后利用全连接层提取到特征之后还是像R-CNN一样额外单独训练一个分类器或者训练一个回归模型。所以它还是一个多阶段的训练过程,并没有解决R-CNN的第一个问题。既然是多阶段的,那么所有特征还是需要先存下来,写到磁盘里,以便后续训练使用,所以R-CNN的第二个问题也没有得到解决,并且虽然第三个问题通过特征共享解决了,但是它又引入了一个新的问题就是SPPnet的微调算法很难去更新这个卷积层。
因此本文就提出了Fast R-CNN的方法来尝试解决上述R-CNN和SPPnet的缺点,Fast R-CNN有非常多的优点:
1.2.Fast R-CNN的贡献
第一,它比R-CNN和SPPnet具有更高的一个检测精度。第二,它的训练过程是一个单阶段的过程而不再是多阶段了。第三,训练能更新所有的网络层而不是像SPPnet的第三个缺点不能更新卷积层。第四,由于训练过程变成单阶段了,所以说他也就不需要额外的磁盘空间来缓存特征了。
2.Fast R-CNN的模型结构和训练流程
图一展示了Fast R-CNN的模型结构,图一对于一整张输入图片,Fast R-CNN会先通过一个深度卷积神经网络来得到整张图片的一个图片特征,根据候选区域在原图上的一个图片位置,可以使用RoI投影来获取到候选区域在特征图上的这个候选区域特征,有了候选区域的特征图之后再通过RoI池化层来把这个尺寸不固定的候选区域特征图给转换成特定尺寸的一个特征图,然后再接上两个全连接层来得到每一个区域的特征向量,有了每一个候选区域的特征后再额外接上两个并行的全连接层,其中一个利用softmax函数负责预测类别,另一个直接预测和框的坐标相关的一个框回归,这个预测类别的分支,输出k+1个类别,也就是数据集的类别加上一个背景类。另一个预测坐标的分支直接输出4乘以(k+1)个值,也就是每个类别对应的坐标。
回顾SPPnet的网络结构,就可以发现他们两个的区别是不是就两点,第一点区别是SPPnet在最后一个卷积层后面跟上的是一个空间金字塔池化,但是Fast R-CNN在最后一个卷积层后面跟上的是一个RoI池化层。第二点区别就是SPPnet在提取到候选区域的特征之后会像R-CNN一样额外训练支持向量机进行分类或回归,但是Fast R-CNN在这里是后面直接接了两个并行的全连接层实现分类和回归。
2.1.RoI池化层
RoI池化层能将任意有效的候选区域内的这个特征给转化成一个小的特征图,并且这个小的特征图具有特定的一个空间范围,这不就是SPPnet的这个空间金字塔池化层所干的事吗。因为它本质上就是使用最大池化把不规则的一个特征图给转换成一个特定尺寸的输出,只不过在这个空间金字塔池化层这里,它是分别使用了三个不同的池化来得到三个不同大小的一个输出。但是在Fast R-CNN这里,作者只用了一个池化来得到一个输出,所以作者才在最后这里写到RoI池化层仅仅是空间金字塔池化层的一种特殊情况,因为金字塔池化层是有三个输出,但是RoI池化层在这里它只有一个输出。
2.2.从预训练的模型中初始化一个Fast R-CNN模型
作者试验了三个预训练的Imagenet网络,每个网络都具有五个最大池化层并且具有5到13个卷积层。这三个预训练模型的具体结构会在4.1小节给详细列出。
所以这个就是预训练网络,它其实指的就是在Imagenet上预训练好的一个图像分类模型,预训练的分类模型它一般都是这种结构,也就是说先传入一整张图片,给一个深度卷积网络然后这个深度卷积网络会得到这一整张图片的一个特征图,然后接上一个固定尺寸的最大值化层来对这一个特征图做最大池化,再接上几个全连接层,最后再跟上一个全连接层和softmax函数来输出Imagenet数据集上的1000个图像类别。这里的这个初始化指的其实就是把一个预训练的一个图像分类网络给变成Fast R-CNN网络的这么一个过程。
也就是从上面这个模型变成下面这个模型的过程,在变换的过程中一共经历了三个变换阶段。第一步先把最后的一个最大池化层给替换成RoI池化层。第二步是把最后的一个全连接层和softmax层给替换成了两个并行的全连接层,其中一个分支用来预测k+1个类别,另一个分支用来预测边界框回归。第三步是把网络给修改成了两个数据输入,除了输入图片外还需要输入图片中的一系列候选区域坐标以便于在最终的这个特征图中把这个根据这个候选区域的坐标,把这个候选区域的特征给提取出来。
2.3.在检测任务上进行微调
在初始化好模型之后就需要开始微调这个检测模型了。微调模型其实就是使用反向传播来训练整个网络的一个权重,Fast R-CNN具有很好的训练权重的能力,但是SPPnet却不能很好的更新网络权重,为什么呢?这就需要涉及到训练过程中样本的一个采样方法。
看一下模型结构,这里因为是测试一张图片,所以只有一张图片,但是在模型训练时它是需要一批一批的图片给这个卷积神经网络的一次会传入多张图片。在反向传播更新权重的时候是需要利用正向传播得到的中间每一层的值去更新权重的。假如是SPPnet在训练时,它传入的多张图片,一批样本是通过随机采样得到的,比如说需要128个候选区,这128个区域它可能是来自不同的图片,也就是说需要传入128张这种类似的原图进去,然后在128个特征图中各自提取各自所需要的这个后面区域。在前向传播和反馈传播的过程中会占用大量的显存,降低模型的训练效率,但是Fast R-CNN采用的是另一种方法。
在Fast R-CNN的训练过程中,随机梯度下降的这个mini batch它是通过一种按层抽样的方法,这里以n=2,r=128为例,它会首先采样两张图片然后在每张图片上各自采样64个候选区域,这样做的好处就是每次在前会传播的时候只传两张图片进去就可以了。因为每张图片的64个区域都是在一张图上去得到的,所以说只需要两张原图传进去,然后在两张原图的特征图上各自提取64个候选区域就可以了,而不是像SPPnet一样需要去传入128个原图。这就大大提升了训练效率,这也就是作者他为什么提到SPPnet不能够更新空间,金字塔池化层之前的一个网络权重,因为它因为它更新权重的效率实在太低了。
2.4.多任务损失函数
Fast R-CNN网络是有两个并行的输出层的。这第一个输出用来产生k+1个类别,其中p0 就表示某个候选区域是背景类的概率,p1-pk就表示属于k数据集类别的概率。第二个分支输出的就是一个框回归的一个偏移量,它预测出来的tx和ty就表示框的中心点归一化后的偏移量,tw和th就表示跟边界框的宽和高相关的一个值,它们四个的具体含义跟R-CNN中的定义是一样的。
求损失函数的时候除了要有预测值之外,还需要有一个提前标注好的一个目标值,也就是ground truth。作者在这里把标注好的候选区域类别给用u这个符号给表示出来,把边界框回归的这个目标值给定义成v这个符号。多任务损失的公式就可以写成这种形式,也就是类别损失和框回归损失相加的一个形式
在求类别损失的时候,它用到了类别的预测值和类别的一个目标值,类别损失的具体公式就写成了这种形式,它相当于是求了du类预测概率的log损失来作为分类的一个损失,在求框回归损失的时候,用到了du类目标的一个坐标,预测值和目标值,它的具体公式就写成了这种形式
通过求x y w h这四个值的预测值和目标值之间的一个smooth L1损失来作为框回归的一个损失公式,smooth L1的一个具体的公式就是下面的这种形式,在这里也回顾一下R-CNN中使用的L2 损失,L2损失是这种形式就是x平方,看一下它们的图像:
如果使用L2 损失,就这条曲线它是可以向两端无限延伸的。如果你预测出来的这个预测值和目标值偏差过大的话,就会导致这个x过大,这x过大的话就会导致你这个值一直无限的往上延伸,然后在这个图像上,它的这个斜率其实就是梯度,当无限往上延伸的时候这个梯度就会趋向于无穷大,就会产生梯度爆炸现象,没法训练。所以这个smooth L1损失在x大于等于1的时候把它写成了这种形式
因为这种形式它的梯度是恒等于1的,也就是说它相当于是给这个梯度它设置了一个上限就不会再像这种L2 损失是一样产生梯度爆炸的。因为这个梯度是恒等于1的,当x绝对值小于1的时候,这里多乘了一个0.5的这一个系数是为了让这个分段函数它在x等于1的这个点两端的一个梯度值是连续的。在公式中还有一个超参数就是lambda,这个lambda它其实就是用来控制你的分类损失和回归损失之间的一个平衡,这个lamba的值一般被设置为1。
在公式里面还有一个就是这个方括号,它表示只有当目标类别是大于等于1的时候,这个方框的值才等于1,表示需要去求这个回归损失。如果u等于0的话就表示这是一个背景类,这个值也就是零。所以最后求出一下这个回归损失就是0。因为背景类它是没有预测框的,也就不需要去求后边这个回归损失。
2.5.尺度不变性
尺度不变性指的就是有两个相同的目标,一个目标比较大,一个目标比较小。如果这两个目标都能够被模型识别出来,就说明这个模型具有比较好的尺度不变性。
作者实现了两种方法来实现目标检测的尺度不变性,第一种brute force,可以把它理解成单尺度训练,在单尺度训练过程中每一张图片都被处理成了一个预定义好的图片尺寸来进行训练或者是进行预测。它的目的是让网络来直接学会尺度不变形。第二种这种多尺度方法其实就是在训练期间,每一张图片都先被随机采样成一个特定的尺度而不是像第一种一样是采用一个预定义的固定尺度,然后这种多尺度的训练方法也是一种数据增强的方式。关于这两种方法哪种好,在第五章的时候会有实验结果做对比。
3.Fast R-CNN测试
一旦Fast R-CNN的网络被微调好后就可以进行目标检测了。整个网络只需要接收两个输入,分别是一张图片和这个图片中的一系列目标候选区域,就能够预测出候选区域的类别和精确坐标了。
3.1.截断SVD以便更快地检测
对于图像分类任务来说,花费在全连接层上的时间比花费在卷积层上的时间要小。相反的对于检测任务来说,由于这个RoI的数量非常非常的大,因此几乎一半的钱会传播时间都被花费在了计算全连接层上,这是因为在测试一张图片的时候只需要通过一次前向传播把这一整张图的一个特征图给提取出来就可以了。但是在后面进行全连接层运算的时候需要把这一张图上所有的候选区域抠出来后的这个候选区域特征图都给通过后面的全连接层去进行运算。所以说后面这个全连接层会占据大量的一个测试时间,所以必须要对后面这个全连接层进行加速,大的全连接层的一个加速方法就是通过这种阶段的奇异值分解方法
先理解这个SVD是什么?简单来说假如有一个u乘v大小的一个矩阵,可以通过奇异值分解把它分解成一个u乘n大小的矩阵,乘上一个n乘n大小的一个对角矩阵,再乘上一个n乘v大小的一个矩阵,并且中间的这个对角矩阵其实有一个性质就越靠近左上角的这个值越重要,越靠近右下角的这个值越不重要,既然右下角的这个值不重要,那就可以直接把这些值给去掉,让中间的这个矩阵它变成一个t乘t的一个矩阵,相当于把后面的元素都给去掉,然后只保留左上角这一部分变成一个t乘t的矩阵,相应的前面这个矩阵就把最后这几列给去掉,变成u乘t的一个矩阵,然后后面这个矩阵就把最后的这几行给去掉就变成一个t乘v的一个矩阵,相当于对原始的这么一个u乘v的矩阵做了一个压缩。我们把这个公式用字母表示就可以表示成左边的这种形式,也就是左边的这个矩阵跟你右边的这个压缩后的矩阵,其实两者是可以近似相等的。
现在回到全连接层的概念,全连接层本质上就是让参数矩阵w和一个输入特征x去进行相乘,既然左边乘x的,那么右边也可以乘上一个x,也就是说可以把单个全连接层w给替换成两个全连接层,这两个全连接层中的第一个是使用了一个权重矩阵,这个形式也就是这个来作为两个全连接层中的第一个,然后两个全连接层中的第二个就使用这个u来作为权重矩阵,也就是这个这个全中,这就可以把左边的这个和全连接层用右边两个更小的全连接层近似替换了,然后在替换前左边的这个参数是u乘w的参数,然后右边压缩后的参数其实是u乘t加上一个v乘t,并且在右边这个压缩的力度越大,最后在右边的这个参数是越小的,参数越少,模型的运行速度就会越快。所以说通过这种截断的奇异值分解法可以提高全连接层的一个推理速度。
4.实验结果
证明1. State-of-the-art mAP on VOC07, 2010, and 2012
证明2. Fast training and testing compared to R-CNN, SPPnet
证明3. Fine-tuning conv layers in VGG16 improves mAP
5.设计评价
5.1多任务训练有帮助吗
实验结果表明,这个多任务训练的一个结果确实是要比这个多阶段的训练效果要好的。
5.2单尺度训练和多尺度训练的一个效果对比
5.3Fast R-CNN是否需要更多的训练数据
证明了对Fast R-CNN来说,更多的训练数据确实会提高模型的精度而不会出现其他传统模型出现了这种精度饱和的情况。
5.4支持向量机是否比soft max的训练效果好
5.5候选区域是不是越多越好
参考视频
目标检测之Fast R-CNN论文精讲,Fast RCNN_哔哩哔哩_bilibili