这篇是 RCNN 系列的第三篇,主要是将除了 region proposal 部分之外,通过提出一种多任务目标函数,将SVM分类(实际上用的是 softmax)以及区域回归的部分也都放在了 CNN 网络中,因此不但进一步的加快了检测的时间,由于分类任务也在同一个网络中,因此也消除了之前的网络需要占用大量本地存储空间的问题。
1.综述
总的来说,Fast R-CNN 的提出,主要解决了之前的 R-CNN 以及 SPP-Net 的下面这几个问题
- 检测是速度慢,因为R-CNN过程中一张图向内候选框之间是大量重叠的,提取特征时会出现大量的操作冗余。
- 训练时速度慢,主要的原因大致同上,虽然后续的 SPP-Net 对 R-CNN 的速度有了一定的提升,但依旧不能用于实际情况。
- 训练需要的本地空间巨大。这是因为 R-CNN 和 SPP-Net 训练都需要经过多个阶段,特征也要存在磁盘中。
- 在SPP-Net 中的微调只能更新 spp Layer 后面的全连接层,对于很深的网络这样的效果肯定达不到最优。
因此,Fast R-CNN 的提出,主要改进的方面如下所示:
- 比 R-CNN 更高的检测质量
- 把多个任务的损失函数写到一起,实现了单级训练的过程
- 在训练时可以更新所有的层
- 不需要磁盘中存储大量的特征
对于上面所说的这些改进方面,解决的方案大致如下:
- R-CNN在训练的时候,pipeline 是隔离的,先提出 proposal,然后进行 CNN 特征提取,之后用 SVM 分类,最后再做 b-box 回归。而 Fast R-CNN 在训练阶段 实现了 end-to-end。也就是说,整个网络流程除了最开始的 region proposal 外,全部统一在了同一个网络内。
- R-CNN 和 SPP-Net 的训练开销大,所以 Fast R-CNN 用了 image-centric 的训练方式来通过卷积的 共享 特性来降低运算开销
- R-CNN 和 SPP-Net 需要占用大量本地存储空间用来存储提取到的特征,而 Fast R-CNN 通过将 SVM 这一步去掉,从而将所有的特征都暂存在缓存中,这样就不需要额外的存储空间了。
- R-CNN 测试时间开销大,这一点在 SPP-Net 中已经得到了一定的改善,在 Fast R-CNN 中,进一步通过single scale(一种简化的 spp layer)testing 和 对全连接进行 SVD 降维分解来进一步提速。
2.整体框架
首先给出几张图:
a. 论文中的原图:
b. cs231n 中的2张“立体图”:
大致的框架如上所示
具体来说可以分为下面这几个步骤,这里以前面的网络使用 AlexNet 为例
对于训练来说:
- 使用 selective search 方法在一张图片中得到大约 2000 个 region proposals;
- 缩放图片的scale得到图像金字塔,FC 得到conv5 的特征金字塔;
- 对于每个scale的每个 ROI,求取映射关系,在conv5 中crop 处对应的 patch,并用一个单层的 SPP Layer(文中成为 ROI pooling layer)来统一到一样的尺度;
- 继续经过两个全连接层得到特征,这些特征分别共享到两个新的全连接层,并且分别连接上两个优化目标,第一个优化目标是分类,且是用的是softmax,第二个优化目标是 bbox regression,使用了一个 smooth 的 L1-loss。
我们在上面的第二张图中可以看到整个网络的训练过程,可以看到,Fast R-CNN 可以看做是一个 joint traing 过程的 SPP-Net。
在网络的前半部分,大致和 SPP-Net 网络相同,都是使用 SS 方法提出一张图片中的大约 2000 个 region proposals ,然后将这张标记了每个 ROI 位置信息的图像 经过 CNN 进行特征提取,一直传到 conv5,得到这张图像的完整 feature map。
在 conv5 结束阶段,输入P个候选区域,对于每个候选区域,都经过一次 ROI pooling Layer,这一层的具体原理下文会进行具体的讲述,在经过 ROI pooling Layer 后,可以看到,所有的 ROI 特征都被统一到相同的长度。
最后将相同长度的 ROI 特征送到两层全连接层,最后再分别连接到两个全连接层,后面分别是softmax 分类层和 b-box regression 层,最后用一个联合损失函数表示网络的整体损失。
注意,我们可以看到,在 R-CNN 网络中,在training 阶段,网络是可以在 ROI pooling Layer 中反向传播的,这是因为 Fast R-CNN 中的这个池化层不同于 SPP-Net 中的空间金字塔池化,它只有一层,也就是说,它只被放在了一个尺度内,因此反向传播可以通过。
3. 具体细节
下面分别具体介绍 Fast R-CNN 中的各个模块。
3.1 ROI pooling Layer
首先放上原文中的话:
The RoI pooling layer uses max pooling to convert the features inside any valid region of interest into a small feature map with a fixed spatial extent of H x W (e.g., 7 x 7), where H and W are layer hyper-parameters that are independent of any particular RoI.
从这段话中我们可以看出,Fast R-CNN 中所谓的 ROI pooling layer 就是将从 conv5(最后一个卷积层)中得到的 feature map 找到每个 ROI 对应的区域后对其进行分块,块的数量为 H*W,之后再连接上全连接层,这样对于不同大小的 ROI feature map,这一层都能够生成相同大小的特征向量并送入到后面的全连接层中。
Pooling is applied independently to each feature map channel, as in standard max pooling. The RoI layer is simply the special-case of the spatial pyramid pooling layer used in SPPnets in which there is only one pyramid level.
从上面这段话中我们可以知道,ROI pooling layer 这一层对于每一个 ROI 对应的 feature map 上的相应区域是相互独立操作的。而且,这一层其实就是在SPP-Net中的 SPP 层的简化版本,因为它只有一个尺度,也就是说,它是一层的 SPP-layer。
ROI pooling layer 的测试(forward过程)
ROI pooling layer将每个候选区域的特征均匀的分成 MxN块,然后对每块特征区域进行 max pooling。将特征图上大小不一的候选区域准便成为大小统一的数据,送入到下面的全连接层中。如下图所示:
ROI pooling layer 的训练(backward过程)
首先我们来考虑普通的 max-pooling 层的情况。这里我们设 xi 为输入层的节点, yi 为输出层的节点。则有:
- xi 不在 yj 范围内
- xi 不是最大值
对于 ROI pooling layer 来说,一个输入节点可能和多个输出节点相连。设
xi
为输入层的节点,
yrj
为第
r
个候选区域的第
则有下面公式成立:
也就是说,因为很多的 region proposal 的感受野可能是相同的或者是重叠的。因此在一个 batchsize 内,我们需要对于这些重叠的神经元偏导数进行求和,然后反向传播回去即可。
3.2 网络初始化
和之前的网络一样, Fast R-CNN 同样是使用已经训练好的网络进行初始化的。
- 要更改网络的结构,将最后一层池化层替换为 ROI pooling Layer;
- 设置 ROI pooling Layer 的具体超参数,也就是设置相应的 H 和 W 来匹配全连接层的输入要求;
- 将网络的输出改为两个子网络,一个用来分类(使用的是 softmax)另一个是 b-box 用来回归,最后的损失是二者的多任务损失。
- 将网络的输入进行更改,网络的输入是图片集合以及 ROI 的集合
3.3 微调(fine tunning)
之前有提到过,对于 SPP-Net 来说,网络无法微调 SPP 层之前的网络,因此在 SPP-Net 中只能对 SPP 层之后的全连接层进行微调。
而这主要的原因,文中也已经提到,原文是:
The root cause is that back-propagation through the SPP layer is highly inefficient when each training sample (i.e. RoI) comes from a different image, which is exactly how R-CNN and SPPnet networks are trained.
文中大致的意思是说这其中最根本的原因是当每个训练样本( ROI )都来自不同的图像的时候训练是相当没有效率的。
当在训练时每个批次(mini-batch)的样本来自于不同的图样,而 SPP pooling 的感受野有特别的大,一般是整幅的图片,因此无论是前向传播还是反向传播误差都要经过一整幅图像,效率特别慢,也无法进行权重更新。
而在本文中使用的方法是对于同一批次(mini-batch)的图片,尽量选用来自同一幅图片的不同区域。这样做的好处是相比于 SPP-Net 来说,我们的训练速度大约能够提高 64 倍。
之前的网络没有这样做是因为,在深度学习的调参过程中,如果一个批次里的图片都来自于同一个类,网络的收敛速度会非常慢,但是作者发现,在这个网络中,使用这种操作会使得收敛速度也很快。
在 目标检测(4)-Fast R-CNN 分析可能是有 2 个原因
- 因为 batchsize 比较大,本文将 batchsize 设置为 128,相当于我们将 batchsize 设置为2。
- 因为在同一幅图片中的不同区域很可能来自不同的类别。比如在论文中网络示意图中的图片,包含了马、人、帽子等等。
3.4 多任务损失(multi-task loss)
在 Fast R-CNN 中,因为在网络的全连接层后将分类与回归都放在了一个网络里面,因此损失函数一定是多任务的,最后总的损失表达式如下所示:
而对于回归损失来说, tu 的定义方式和 RCNN 中的一致,都是中心区域的坐标,以及区域宽度以及高度。也就是 tu=(tux,tuy,tuw,tuh) ,其中 u 表示所属的类别。
但是所使用的回归函数和 RCNN 中有所不同, RCNN 中是用的是 L2 损失函数,而在这里我们使用的是一种名为“软 L1”(smooth-L1)的损失函数。具体表达式如下:
3.5 尺度不变性(scale invariance)
首先回顾一下在之前的 SPP-Net 中的尺度不变行的方法:
- brute force(single scale),直接将 image 设置为某种 scale,直接输入网络进行训练,期望网络自己适应这个 scale;
- image pyramid(multi scale),也就是说,对于确定的 ROI,先生成一个图像金字塔,在 multi-scale 训练时,对于要用的 ROI,在金字塔上找到一个最接近 227*227 的尺寸,然后用这个尺寸训练网络
SPP-Net 中使用的是第二种方法,然而这篇论文中说,虽然第二种方法看起来的确比较好,但是非常耗时,最主要的是性能提升也不高,大约只有 1%,所以在这篇论文中还是使用了第一种方案。
3.6 SVD 加速检测
在进行 test 的时候,每一个 ROI 都需要在全连接层进行计算,如果 ROI 特别多,就会导致计算效率的下降。所以,可以对全连接层进行 SVD 分解,具体公式如下:
原文中有如下描述:
In this technique, a layer parameterized by the u×v weight matrix W is approximately factorized as
using SVD. In this factorization, U is aW=UΣtVT u×t matrix comprising the first t left-singular vectors ofW , Σt is a t×t diagonal matrix containing the top t singular values of W , andV is v×t matrix comprising the first t right-singular
vectors ofW . Truncated SVD reduces the parameter count from uv to t(u+v) , which can be significant if t is much smaller thanmin(u;v) .To compress a network, the single fully connected layer corresponding to W is replaced by two fully connected layers, without a non-linearity between them. The first of these layers uses the weight matrix ΣtVT (and no biases) and the second uses U (with the original biases associated withW ). This simple compression method gives good speedups when the number of RoIs is large.
简单来说,假设我们的网络中某一层的权重可以用矩阵
W
来表示,且形式为
这种 SVD 结构将减数数量从
uv
减少到了
t(u+v)
,当
t
比
为了压缩一个网络,单个全连接层可以使用两个没有非线性关系的全连接层进行代替。其中第一个使用的权重矩阵为
ΣtVT
(不包括偏置) 第二个是用的权重矩阵为
U
(包括
原文中给出了使用 SVD 的对比图:
最后说一下实现,在实现的时候,相当于把一个全谅阶层拆分为 2 个,中间用一个低维数据相连。如下图所示:
3.7 数据增强(data augment)
在训练期间,作者是用的数据增强的方式是将图片进行水平翻转。
此外,作者也尝试将 VOC2012 数据集中的图像加入到 fine tunning 中,结果 VOC2007 的 mAP 从 66.9 到了 70.0,说明对于网络来说,数据越多越好。
3.8 SVM 与 Softmax
先给出使用 SVM 与 Softmax 的对比图:
这里引用目标检测(4)-Fast R-CNN的一段话:
此前在RCNN中,我们了解到了不能够使用CNN中的样本定义方式去训练SVM,是因为两个分类器对于样本的需求是不同的。因此直接使用Fast RCNN的训练样本去训练SVM也是不公平的,因此作者通过RCNN中SVM的训练方式和参数设计对比SVM和SoftMax的结果,发现softMax结果优于SVM 0.1-0.8,也就是说将分类及回归放到一个网络中去做,并没有影响到网络的精度。
4. 实验与结论
- 网络末端同步训练的分类和位置调制,提升了准确率;
- 使用多尺度图像金字塔,对于整个网络来说性能几乎没有提高;
- 倍增训练数据,能够有 2%-3% 的准确度的提升;
- 网络直接输出各类的概率(也就是使用 softmax),比后面接 SVM 效果要好;
- 选择更多的候选框并不能提升性能。
5. 优缺点
优点:
- 提供了在 caffe 框架下如何定义自己的层/参数/结构范例
- 实现了 training 和 test 都是end-to-end,正式因为引入了 ROI pooling Layer
- 速度上的提升
缺点:
- 依旧使用 SS 方法来提取 region proposal(耗时2~3s, 作为对比,特征提取耗时0.32s);
- 无法满足实施应用,整个系统没有实现真正的 end-to-end;
- 利用了 GPU,但是 region proposal 仍然是在 CPU 上实现的。