- 论文链接:https://arxiv.org/pdf/1504.08083.pdf
- 论文题目:Fast R-CNN
Fast R-CNN
1. Introduction
最近,深度卷积网络明显的提高了图像识别和目标检测的准确率。跟图像识别相比,目标检测是一个更具挑战性的任务,它需要更复杂的算法和方法来解决。考虑到复杂性,最近的多级管线的训练方法太缓慢而且并不简洁。
目标检测的困难和复杂性主要来自于需要精确的定位物体,这就带来两个主要的挑战。第一,需要处理大量的候选目标位置(被称作“proposals”)。第二,这些候选区域仅仅提供了比较粗略的定位,还需要进一步的进行精细调节。解决上述问题还需要同时考虑速度,准确性和简洁。
在本文中,我们简化了目前最好的基于卷积网络的目标检测器的训练过程,提出一种单级训练算法,这种算法对分类目标区域和精细调节预测框位置进行联合学习。
这种方法可以用于训练很深的网络(VGG-16),而且比R-CNN快了9倍,比SPPnet快了3倍。在运行时间上,检测网络只需0.3s来处理图片(排除候选目标区域的时间),同时还在PASCAL VOC 2012数据集上取得了66%的mAP(R-CNN只有62%)。
1.1 R-CNN and SPPnet
基于区域的卷积网络办法(R-CNN)通过使用深度卷积网络很好地完成了目标检测任务,取得了很好的准确率。然而R-CNN有明显的弱点:
- Training is a multi-stage pipeline. R-CNN首先用似然误差来精细调节目标框的卷积网络。然后,用卷积特征来拟合支撑向量机。这些支撑向量机是作为目标检测器的,代替了softmax分类器。第三步,学习边框回归器。
- Training is expensive in space and time. 对于支撑向量机和边框回归器的训练,特征都是从每个图像的每个目标区域提取出来然后再写进磁盘。对于非常深的网络,例如VGG16,这个过程需要2.5个GPU花费好几天的时间才能完成VOC07 trainval数据集5k张图片的特征提取。而且这些特征需要上百个GB的存储空间。
- Object detection is slow. 在测试的时候,特征需要从每张测试图片的每个目标候选区域中提出来。使用VGG16的检测,每张图片需要花费47s(使用GPU)。
R-CNN太慢了,因为它需要对每个目标候选区域使用卷积网络进行前向传递,并没有共享运算。空间金字塔池化网络(Spatial pyramid pooling networks,SPPnets)就是设计来通过共享计算来对R-CNN进行提速。SPPnet对整张输入图片计算卷积特征图,然后使用从共享特征图上提取的特征向量来对每个目标候选区域进行分类。对于一个目标候选框的特征提取是将位于该候选框内的特征图上的部分最大值池化到固定大小(如
6
×
6
6 \times 6
6×6)。在空间金字塔池化中多种输出大小得到池化然后连接起来。SPPnet大大提高了R-CNN的速度,测试时提高了10~100倍。训练时间同样也减少了3倍,因为更快的候选框特征提取。
SPPnet也有明显的缺点。就像R-CNN,训练也是一个多级管线的过程,包括了特征提取,似然函数训练网络,训练支撑向量机,最后拟合边框回归器。特征仍然需要被写进到磁盘中。但是不像R-CNN,SPPnet的精细调节算法不能更新位于空间金字塔前的卷积层。并不意外的是,这样的限制(固定卷积层)限制了非常深网络的准确性。
1.2 Contributions
我们提出了一种新的训练算法弥补了R-CNN和SPPnet的缺点,同时也提高了速度和准确率。我们将这种算法命名为Fast R-CNN,因为它在训练和测试上都更快了。Fast R-CNN有如下几个优点。
- 相比于R-CNN和SPPnet有更高的检测质量(mAP)。
- 训练是单级的,使用多任务loss。
- 训练可以更新所有的网络层。
- 并不需要磁盘来进行特征向量的缓存。
图1. Fast R-CNN结构。一个输入图像和多个感兴趣区域(RoIs)被送入到一个全卷积网络中。每个RoI都被池化到一个固定大小的特征图中,然后通过全连接层映射到一个特征向量上。每个RoI有两个输出向量:softmax概率和每个类边框回归的补偿值。这个结构可使用多任务loss进行端对端的学习。
2. Fast R-CNN architecture and training
图一展示了Fast R-CNN的结构。Fast R-CNN网络将整张图像和一系列目标区域作为输入。网络首先利用一系列卷积层和最大值池化层来处理整张图像得到卷积特征映射图。然后,对于每个目标候选区域,一个RoI池化层从特征图上提取出一个固定长度的特征向量。每个特征向量被送入到一系列全连接层中,最后分出两个子分支输出层:一个输出softmax概率值(K个目标分类再加上一个“背景”类),另一个对于每个目标分类输出4个实数。每组这4个值分别为一个类别编码一个更加精细的边框位置。
2.1. RoI 最大值池化层
RoI pooling层使用最大值池化将任意有效RoI范围内的特征图转换为固定大小的一张小特征图
H
×
W
H\times W
H×W(如
7
×
7
7\times7
7×7),这里H和W都是超参数,与任意RoI都是独立的。在本文中,RoI是卷积特征图上的一个矩形窗口。每一个RoI都被一个4维元祖
(
r
,
c
,
h
,
w
)
(r,c,h,w)
(r,c,h,w)所定义,其中左上角坐标为
(
r
,
c
)
(r,c)
(r,c),高和宽为
(
h
,
w
)
(h,w)
(h,w)。
RoI最大值池化是通过将
h
×
w
h\times w
h×w大小的RoI窗口划分为一个一个大小为
h
/
H
×
w
/
W
h/H\times w/W
h/H×w/W的子窗口所组成的
H
×
W
H\times W
H×W的网格,然后对每个子窗口分别进行最大值池化输出到对应网格单元中。池化是分别应用到每个特征图通道上的。RoI层是SPPnet中的空间金字塔池化层的一种特殊形式。
2.2. Initializing from pre-trained networks
我们使用了三种ImageNet预训练模型,每一都有5个最大池化层和5到13个卷积层(Section 4.1 会有网络具体结构)。当用一个预训练网络来初始化一个Fast R-CNN网络的时候,它需要经过三个转化。
首先,最后的最大池化层被RoI池化层代替,然后根据网络第一个全连接层来配置H和W(如VGG16就是
H
=
W
=
7
H=W=7
H=W=7)。
第二,网络最后的全连接层和softmax(ImageNet要分1000个类)被先前提到的两个同胞子网络替代(一个是全连接层接softmax完成K+1个类别的分类,一个输出特定类的边框回归)。
2.3. Fine-tuning for detection
利用反向传播算法训练所有的网络参数是Fast R-CNN的一个重要特点。首先,让我们阐明为什么SPPnet不能够更新空间金字塔层下面层的参数。
这根本原因是反向传播经过SPP层是非常低效的,当每个训练样本(RoI)都来自不同的图片,但恰好SPPnet和R-CNN就是这样训练的。这个低效率来自于每个RoI的可能有很大的感受野,经常是跨越整个输入图像的。因为前向传播必须处理整个感受野,所以训练的输入是很大的(通常是整张图片)。
我们提出一种更为有效的训练方法,在训练过程中充分利用特征共享。在Fast R-CNN训练中,SGD mini-batches 是层次化采样的,首先采样N张图片,然后对于每张图片采用R/N个RoIs。严格来说,来自同一张图片的RoIs是可以共享前向后向传播中的运算和存储的。这将使得mini-batch的计算大大减小,只跟N有关。比如
N
=
2
N=2
N=2,
R
=
128
R=128
R=128,那么这样的训练策略将比原来的从128张不同的图像中采样RoI要快64倍(R-CNN和SPPnet的策略)。
这个策略需要关注的一点是可能会导致较为缓慢的训练收敛,因为来自同一张图像的RoIs是互相关的。这个担心在实际测试中并没有出现,我们使用
N
=
2
N=2
N=2,
R
=
128
R=128
R=128也取得了很好的结果并且比R-CNN迭代次数更少。
除了层次化采样之外,Fast R-CNN还简化了训练过程,仅通过一个精细调节阶段来联合优化一个softmax分类器和边框回归器,而不是分三步分别训练一个softmax分类器,支撑向量机和回归器。这个过程的所有构成都会在接下来进行讲解(loss,mini-batch采样策略,RoI池化层的反向传播以及SGD超参数)。
Multi-task loss. Fast R-CNN网络有两个同胞输出层。第一个输出一个离散概率分布(对于每个RoI),
p
=
(
p
0
,
.
.
.
,
p
K
)
p=(p_0,...,p_K)
p=(p0,...,pK),一共
K
+
1
K+1
K+1个分类。通常p是通过一个
K
+
1
K+1
K+1输出的全连接层之上的一个softmax层来计算的。第二个层输出边框回归补偿值,对于每个目标分类
t
k
=
(
t
x
k
,
t
y
k
,
t
w
k
,
t
h
k
)
t^k=(t^k_x,t^k_y,t^k_w,t^k_h)
tk=(txk,tyk,twk,thk),k是类别下标。
t
k
t^k
tk这个参数指定了一个尺度不变的平移量以及一个相对于目标预测框似然空间上的一个高度/宽度的变换(也就是平移和伸缩)。
每个训练RoI样本都被一个gt 类别u和gt 边框回归目标v标定。我们使用多任务loss L对于每一个标定的RoI进行分类和边框回归的联合训练:
(1)
L
(
p
,
u
,
t
u
,
v
)
=
L
c
l
s
(
p
,
u
)
+
λ
[
u
>
1
]
L
l
o
c
(
t
u
,
v
)
L(p,u,t^u,v)=L_{cls}(p,u)+\lambda [u\gt 1]L_{loc}(t^u,v) \tag 1
L(p,u,tu,v)=Lcls(p,u)+λ[u>1]Lloc(tu,v)(1)
在这里
L
c
l
s
(
p
,
u
)
=
−
log
p
u
L_{cls}(p,u)=-\log p_u
Lcls(p,u)=−logpu是真实类u的似然误差。
第二个loss,
L
l
o
c
L_{loc}
Lloc,是定义在对于类u真实边框回归目标的元组
v
=
(
v
x
,
v
y
,
v
w
,
v
h
)
v=(v_x,v_y,v_w,v_h)
v=(vx,vy,vw,vh)和预测目标的元组
t
u
=
(
t
x
u
,
t
y
u
,
t
w
u
,
t
h
u
)
t^u=(t^u_x,t^u_y,t^u_w,t^u_h)
tu=(txu,tyu,twu,thu)上的。这个方括号方程
[
u
>
1
]
[u\gt1]
[u>1],当
u
>
1
u\gt1
u>1时等于1,否则等于0。通常背景类被标记为
u
=
0
u=0
u=0。对于背景RoIs,没有所谓gt 边框的概念,所以
L
l
o
c
L_{loc}
Lloc这项就忽略。对于边框回归,我们采用loss
(2)
L
l
o
c
(
t
u
,
v
)
=
∑
i
∈
{
x
,
y
,
w
,
h
}
s
m
o
o
t
h
L
1
(
t
i
u
−
v
i
)
L_{loc}(t^u,v)=\sum_{i\in \{x,y,w,h\}} smooth_{L_1}(t^u_i-v_i) \tag 2
Lloc(tu,v)=i∈{x,y,w,h}∑smoothL1(tiu−vi)(2)
在这里
(3)
s
m
o
o
t
h
L
1
(
x
)
=
{
0.5
x
2
if
∣
x
∣
<
1
∣
x
∣
−
0.5
otherwise,
smooth_{L_1}(x)= \begin{cases} 0.5x^2 & \text{if $|x|<1$} \\ |x|-0.5 & \text{otherwise,} \tag 3 \end{cases}
smoothL1(x)={0.5x2∣x∣−0.5if ∣x∣<1otherwise,(3)
是一种鲁棒
L
1
L_1
L1 loss ,它对于异常值不是那么敏感相对于R-CNN和SPPnet中使用到的
L
2
L_2
L2 loss。当回归目标是无限制的,那么使用
L
1
L_1
L1 loss 进行训练就需要对学习率进行仔细的调节为了防止梯度爆炸,而方程(3)就消除了这种敏感性。
方程(1)中的超参数
λ
\lambda
λ是用来控制两个任务loss的平衡的。我们对gt 回归目标
v
i
v_i
vi进行归一化使其拥有零均值和单位方差,所有的实验
λ
=
1
\lambda=1
λ=1。
Mini-batch sampling. 在精细调节过程中,每个SGD mini-batch都构建于 N = 2 N=2 N=2张图片,这两张图片随机均匀的进行选择(实际,我们一般对数据集进行permutations然后进行迭代)。我们使用mini-batch 大小为128,从每张图像上采用64个RoIs。我们从目标预测框与gt 框的IoU达至少0.5的RoIs中选取25%。这些RoIs组成带有前景目标分类的标定样本, u > 1 u\gt 1 u>1。剩下的RoIs从与gt框的最大IoU在 [ 0.1 , 0.5 ) [0.1,0.5) [0.1,0.5)范围内的RoI中进行采样。这些采样出来的是 u = 0 u=0 u=0 的背景样本。这个低阈值 0.1 是对于难例挖掘一个启发性参数。在训练时,图像有50%的概率进行水平翻转。除了这个以外,不使用其他的数据集扩展方法。
Back-propagation through RoI pooling layers. 反向传播算法经过RoI池化层,会推导导数。简明一点,我们假设每个mini-batch只有一张图片,拓展到
N
>
1
N>1
N>1是非常直接的,因为前向传播是独立的处理所有图片的。
用
x
i
∈
R
x_i \in \mathbb R
xi∈R表示RoI池化层的第i个输入,
y
r
j
y_{rj}
yrj表示第r个RoI的第j个输出。RoI池化层计算
y
r
j
=
x
i
∗
(
r
,
j
)
y_{rj}=x_{i^*(r,j)}
yrj=xi∗(r,j),在这里
i
∗
(
r
,
j
)
=
a
r
g
m
a
x
i
′
∈
R
(
i
,
j
)
x
i
′
i^*(r,j)=argmax_{i'\in \mathcal R(i,j)}x_i'
i∗(r,j)=argmaxi′∈R(i,j)xi′。
R
(
r
,
j
)
\mathcal R(r,j)
R(r,j)是对于输出是
y
r
j
y_{rj}
yrj 最大池化对应的子窗口的输入下标集。一个
x
i
x_i
xi可能被赋予多个不同的输出
y
r
j
y_{rj}
yrj。
RoI池化层的反向传播方程对于每个输入参数
x
i
x_i
xi通过下面的argmax切换来计算损失函数对于该参数的偏导数:
(4)
∂
L
∂
x
i
=
∑
r
∑
j
[
i
=
i
∗
(
r
,
j
)
]
∂
L
∂
y
r
j
\frac{\partial L}{\partial x_i}=\sum_r \sum_j [i=i^*(r,j)]\frac{\partial L}{\partial y_{rj}} \tag 4
∂xi∂L=r∑j∑[i=i∗(r,j)]∂yrj∂L(4)
简单来说,对于每个mini-batch RoI
r
r
r和每个池化输出元
y
r
j
y_{rj}
yrj,偏导数
∂
L
/
∂
y
r
j
\partial L/\partial y_{rj}
∂L/∂yrj 是累加的,如果
i
i
i 是对于
y
r
j
y_{rj}
yrj通过最大池化被argmax选择的。在反向传播中,偏导数
∂
L
/
∂
y
r
j
\partial L/\partial y_{rj}
∂L/∂yrj 是已经在RoI 池化层的top的backwards函数里计算好的。
SGD hyper-parameters. 用于softmax分类和边框回归的全连接层都是用零均值和0.01和0.001的标准差来分别初始化的。偏置项全部初始化为0。所有层使用1作为每层权重的学习率,2作为每层偏置项的学习率。当在VOC07和VOC12 trainval上进行训练时,我们使用SGD跑30k个mini-batch周期,然后降低学习率到0.0001再训练另一个10k周期。还用到0.9的momentum和0.0005的参数衰减。
2.4. Scale invariance
我们探索了两种方式来完成尺度不变性检测:(1)通过“暴力法”学习,(2)使用图像金字塔。在暴力法中,训练和测试时每张图片都被处理到一个预先确定的像素大小上。这个网络必须直接从训练数据中学习到尺度不变性。
相反,多尺度方法通过图像金字塔给网络大概的提供尺度不变性。在测试时,图像金字塔被用来对每个目标候选框进行尺度归一化。在多尺度训练中,每次当一张图像被采样我们都随机地采样一个金字塔尺度,作为一种数据集增广策略。我们只对较小的网络进行多尺度训练。
3. Fast R-CNN detection
一旦一个Fast R-CNN被精细调节了,检测和跑一个前向传递没什么差别(假设目标候选框已经提前计算好了)。网络将一张图片(或图像金字塔,被编码成一个图像列表)和R个目标候选框作为输入来进行打分。在测试时,R大约有2000个,尽管我们会考虑R很大的时候。当使用一个图像金字塔时,每个RoI都被赋予一个尺度,使得经过尺度变换的RoI面积接近于
22
4
2
224^2
2242。
对于每个测试RoI r,前向传播输出一个类别后验概率分布p和一系列相对于r的预测边框补偿(对于每个K类别都有自己的精细边框预估)。我们对每个目标类k赋予r一个检测置信概率,
P
r
(
c
l
a
s
s
=
k
∣
r
)
≜
p
k
Pr(class=k|r)\triangleq p_k
Pr(class=k∣r)≜pk。然后我们对于每个类别进行NMS,使用R-CNN的算法和设定。
3.1. Truncated SVD for faster detection
对于整张图片的分类,全连接层计算所耗时间相比于卷积层是要小的。相反,对于检测,需要处理的RoIs的数量是很大的,前向传播的将近一半的时间都花费在了全连接层上。大的全连接层能够很容易地通过使用截断SVD来压缩进而提高速度。
在这个技术上,一个通过
u
×
v
u\times v
u×v大小的权值矩阵
W
W
W来参数的一层是可以大约的被如下分解的
(5)
W
≈
U
Σ
t
V
T
W\approx U \Sigma_t V^T \tag 5
W≈UΣtVT(5)
使用SVD。在这个分解中,
U
U
U是一个
u
×
t
u\times t
u×t矩阵包含了
W
W
W 的前
t
t
t个左奇异向量,
Σ
t
\Sigma_t
Σt是一个
t
×
t
t\times t
t×t 的对角矩阵包含了
W
W
W的top
t
t
t 个奇异值,然后
V
V
V是一个
v
×
t
v\times t
v×t的矩阵包含了
W
W
W的前
t
t
t个右奇异向量。截断SVD会将参数数量从
u
v
uv
uv降到
t
(
u
+
v
)
t(u+v)
t(u+v),如果
t
t
t 远小于
m
i
n
(
u
,
v
)
min(u,v)
min(u,v)那么这个效果将会非常明显。为了压缩一个网络,对应于
W
W
W的一个单一的全连接层会被两个全连接层代替,并且不引入非线性。第一个层使用权值矩阵
Σ
t
V
T
\Sigma_tV^T
ΣtVT(没有偏置项)然后第二个使用
U
U
U(带上原有的偏置项)。当RoIs的数量很大的时候,这个简单的压缩方法提供了很好的速度提升。