ICCV 2015 的文章
文章提出了用于目标检测的 Fast Region-based Convolutional Network 的方法。Fast RCNN 主要基于之前的方法,提出了用深度卷积网络来高效分类 object proposal 的方法。Fast RCNN 训练 VGG-16 比 RCNN 快了 9 倍,比测试时快了 213 倍,在 PASCAL VOC 上得到了更高的 mAP,和 SPPnet 相比,Fast RCNN 训练 VGG16 比它快了 3 倍,测试快了 10 倍,并且更加准确。
目标检测比分类要复杂,是因为检测有两个挑战:
- 需要处理大量的候选物体的位置(proposal)
- 这些候选位置只提供了一个粗略的定位,需要对其进行 refine 来使之更加准确。
本文精简了训练的流程,我们提出了一个单阶段的训练流程来同时进行分类和 bbox 的 refine
RCNN 和 SPPNet
Region-base CNN 通过使用 deep CNN 来对物体 proposal 进行分类,得到了很高的精度,但是有很明显的缺点:
- 训练是多阶段的流程,RCNN 首先用 log loss 来在 object proposal 上微调卷积神经网络,然后再喂给 SVM 进行分类
- 训练需要很多时间和空间,训练 SVM 以及 bbox regressor 时,需要把每个 proposal 中的特征提取出来然后写到硬盘里,耗费大量时间空间
- 检测速度慢,测试时用 VGG-16 在一张图上需要 47s
RCNN 速度慢的主要原因在于没有共享特征的计算。SPPNet(Spatial pyramid pooling networks)通过共享计算来为 RCNN 提速。SPPnet 对整个输入图像计算卷积特征图,然后把每个 proposal 用一个提出来特征向量后进行分类。每个 proposal 是通过把 proposal 中的特征图经过 max pooling 得到一个固定长度的输出(比如 6 × 6 6\times 6 6×6)在。multiple output sizes are pooled and then concatenated as in spatial pyramid pooling ,SPPnet 在测试时比 RCNN 快了 10 到 100 倍,训练的时间也加快了 3 倍,因为 proposal feature extraction 更快了。
但是 SPPNet 也有很严重的问题,跟 RCNN 一样,SPPNet 也是一个多阶段的流程:提取特征、用 log loss 来对网络进行微调、训练 SVM、最后训练 bbox regressor。特征也写到了磁盘上。但是和 RCNN 不同的是,SPPnet 中提出的微调方法不能更新 spatial pyramid pooling 之前的卷积层。不出意料,这个限制(固定了卷积层的参数)限制了非常深的网络的精度。
贡献
我们提出了一个新的训练算法,可以解决 RCNN 和 SPPnet 中出现的问题,我们叫这种方法为 Fast RCNN ,其好处有:
- 比 RCNN, SPPNet 的 mAP 更高
- 单阶段训练,使用 multi-task loss
- 训练时可以更新所有网络的参数
- 不需要磁盘去存储特征
Fast RCNN 的框架以及训练
图 1 展示了整体的框架。Fast RCNN 的输入为整张图片以及一系列的 object proposal。网络首先用一些卷积网络以及 max pooling 层在整个网络上进行处理得到一个卷积特征图。然后对于每个 proposal ,从特征图中提取一个定长的特征向量。每个特征向量喂到之后的全连接层中,出来两个分支,一个分支得到类别,另外一个分支四个实数,表示物体编码后的坐标。
the RoI pooling layer
RoI pooling 层使用 max pooling 来 convert the features inside any valid region of interest into a small feature map with a fixed spatial extent of H × W H\times W H×W (比如 7 × 7 7\times7 7×7),其中 H , W H,W H,W 时超参数,和 RoI 无关。RoI 时卷积特征图上的一个矩形框,每个 RoI 定义为 ( r , c , h , w ) (r,c,h,w) (r,c,h,w) ,表示左上角的坐标以及高和宽。
RoI max pooling 通过将 h × w h\times w h×w 大小的 RoI 区域分成 H × W H\times W H×W 大小的格子,每个子窗口的大小约为 h H × w W \dfrac{h}{H}\times\dfrac{w}{W} Hh×Ww ,然后对每个子窗口进行 max pooling ,得到一个值。pooling 在每个 feature map channel 中都是独立进行的,和标准的 max pooling 一样。RoI layer 是 SPPnet 中使用的 spatial pyramid pooling layer 的特例,区别是这里只用了一个 pyramid level。我们使用的是 SPPnet 中给出的 sub-window pooling 的计算方法
initializing from pre-trained networks
我们用了 3 个在 ImageNet 上预训练的网络,当用这些网络来对 Fast RCNN 进行初始化时,需要进行以下三个变换:
- 将最后的 max pooling 层换成 RoI pooling ,然后将 H,W 设置成符合网络第一个全连接层的数(比如对于 VGG16 来说 H=W=7)
- 网络的最后一个全连接层和 softmax 用两个分支来替换(一个进行分类,一个进行坐标回归)
- 网络调整为接收两个输入:图片输入以及 RoI 输入
fine-tuning for detection
通过反向传播算法来训练整个网络的权重是 Fast RCNN 的重要的能力。首先我们来阐释一下为啥 SPPnet 不能更新 spatial pyramid pooling layer 之前的权重
根源在于在训练不同图像的样本时,SPP 的反向传播很低效。低效的原因是每个 RoI 可能有很大的感受野,通常会分布到整张图像上,因为前向传播必须处理整个感受野,训练的输入很大(经常是整张图片)
我们提出了一个更加高效的训练方法,可以在训练的时候共享特征。在 Fast RCNN 的训练中,每次采样 N 个图片,然后采样从每张图片中采样 R/N 个 RoI。严格上来讲,来自相同图片的 RoI 在前向传播和反向传播中共享相同的计算和存储。 making N small decreases mini-batch computation (???) 比如说,当使用 N=2, R=128 时,本文提出的训练方法要比从 128 张不同的图片中采样一个 RoI 要快 64 倍。
这种策略存在的一个问题是,训练收敛得可能会更慢,因为来自同一个图片中得 RoI 是相关的。但是在实践中并没有出现太大的问题,取 N=2, R=128,我们使用比 RCNN 要少的 SGD 迭代次数达到了更好的效果。
除了这种 hierarchical sampling,Fast RCNN 使用了一个精简的训练流程,其中只有一个微调的阶段,可以联合优化 softmax classifier 和 bbox regressor,而不是在三个分开的阶段分别优化 softmax classifier, SVMs, regressors。 这个阶段的各个模块的描述如下:
Multi-task loss
一个 Fast RCNN 的网络有两个输出层,第一个输出在 K + 1 K+1 K+1 个类别上的离散的概率分布(对于每个 RoI): p = ( p 0 , . . . , p k ) p=(p_0,...,p_k) p=(p0,...,pk) 其中 p p p 是用一个全连接层用 softmax 输出 K + 1 K+1 K+1 个结果。第二个分支输出 bbox regression 的偏移 t k = ( t x k , t y k , t w k , t h k ) t^k=(t_x^k,t_y^k,t_w^k,t_h^k) tk=(txk,tyk,twk,thk) ,对于每个类别。我们使用 RCNN 文章中给出的参数化 t k t^k tk 的做法。其中 t k t^k tk 表示一个尺度不变的平移以及 log 空间内宽/高相对于 proposal 的偏移。
每个训练的 RoI 都用一个 ground truth 类别 u u u 和 ground truth bbox regression target v v v 来标记。我们在每个标记了的 RoI 上使用 multi-task loss L L L 来联合训练分类和 bbox regression:
其中
L
c
l
s
(
p
,
u
)
=
log
p
u
L_{cls}(p,u)=\log p_u
Lcls(p,u)=logpu 是对于类别
u
u
u 的对数损失
第二个损失 L l o c L_{loc} Lloc 在 u u u 和 v = ( v x , v y , v w , v y ) v=(v_x,v_y,v_w,v_y) v=(vx,vy,vw,vy) 以及预测结果 t u = ( t x u , t y u , t w u , t h u ) t^u=(t_x^u,t_y^u,t_w^u,t_h^u) tu=(txu,tyu,twu,thu) 上进行定义。Iverson bracket indicator function [ u ≥ 1 ] [u\ge 1] [u≥1] 表示 u ≥ 1 u\ge 1 u≥1 时取值为 1 ,否则取值为 0。对于背景 RoI 是没有 bbox 的,因此对应的 L l o c L_{loc} Lloc 是忽略掉的,对于 bbox regression,使用的 loss 为:
smooth L1 loss 是一个鲁棒的 L1 loss,它对异常值不敏感(不像 RCNN 和 SPPnet 中使用的 L2 loss 那样 )。当回归的目标没有界时,用 L2 进行训练时需要对学习率仔细调整以避免梯度爆炸。而 smooth l1 loss 降低了这种敏感性。
式子 1 中的超参 λ \lambda λ 控制两个 loss 之间的平衡。我们对 ground truth 目标 v i v_i vi 进行了归一化,使之具有零均值和单位方差,所有的实验中使用的 λ = 1 \lambda=1 λ=1
我们注意到 [6] 中使用了 related loss 来训练类别无关的 object proposal network。和我们的网络不同,[6] 提出了两个网络的系统,分别来进行定位和分类。OverFeat, RCNN, SPPnet 也训练了 classifiers 和 bbox localizers,但是这些方法使用的是 stage-wise training,是不优于 Fast RCNN 的。
Mini-batch sampling
在微调的时候,每个 SGD mini-batch 从两张图片中得到。使用的 mini-batch 大小为
R
=
128
R=128
R=128 ,也就是说在每张图片中采样 64 个 RoI。和 RCNN 中一样,我们从 proposal 中取出 25% 的 RoI ,他们和 ground truth 的 IoU 至少为 0.5。这些 RoI 包含被分为前景的类别的样本,即
u
≥
1
u\ge 1
u≥1 。剩下的 RoI 从 IoU 为
[
0.1
,
0.5
)
[0.1,0.5)
[0.1,0.5) 中采样获得,这些 RoI 标记为负样本,
u
=
0
u=0
u=0。其中的下界 0.1 被看作是在进行 hard example mining 的操作[8]。在训练的时候,图像以 0.5 的概率进行了水平翻转,没有使用数据增强。
Back-propagation through RoI pooling layers (通过 RoI pooling 的反向传播)
Back-propagation routes derivatives through the RoI pooling layer. 为了简洁起见,我们假设每个 mini-batch 只有一张图片( N = 1 N=1 N=1),扩展到多张图片是很简单的,因为前向传播独立地处理每张图像。
令 x i ∈ R x_i\in\mathbb{R} xi∈R 为第 i i i 个进入 RoI pooling 的激活层输入。令 y r j y_{rj} yrj 为第 r r r 个 RoI 的第 j j j 个输出。RoI pooling layer 计算 y r j = x i ∗ ( r , j ) y_{rj}=x_{i^*}(r,j) yrj=xi∗(r,j) 其中 i ∗ ( r , j ) = arg max i ′ ∈ R ( r , j ) x i ′ i^*(r,j)=\argmax_{i'\in\mathcal{R}(r,j)}x_{i'} i∗(r,j)=i′∈R(r,j)argmaxxi′ , R ( r , j ) \mathcal{R}(r,j) R(r,j) 为 y r j y_{rj} yrj max pool 的子窗口内的下标值的集合。一个单独的 x i x_i xi 可以赋值给多个不同的输出 y r j y_{rj} yrj。
RoI pooling layer 的 反向传播方程计算损失函数相对于每个输入变量 x i x_i xi 的偏导:
∂ 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}} ∂xi∂L=r∑j∑[i=i∗(r,j)]∂yrj∂L
也就是说,对于每一个 mini-batch RoI r r r 和每一个 pooling 的输出单元 y r j y_{rj} yrj ,假如 i i i 是被 y r j y_{rj} yrj max pooling 选中的下标,那么其对应的偏导 ∂ L / ∂ y r j \partial L/\partial y_{rj} ∂L/∂yrj 要进行累加。在反向传播时,偏导 ∂ L / ∂ y r j \partial L/\partial y_{rj} ∂L/∂yrj 已经被 RoI pooling 层上面的 backwards 函数计算过了。
SGD hyper-parameters
softmax 分类器中使用的全连接层以及 bbox regression 的部分用零均值,标准差依次为 0.01,0.001 的高斯分布进行初始化。偏置初始化为 0。所有的层使用 per-layer learning rate of 1 for weights and 2 for biases (???) and a global learning rate of 0.001。 在 VOC07 或 VOC12 上进行训练时,SDG 先训练 30k mini-batch iterations,然后降低学习率至 0.0001 然后再训练 10k 个 iterations 。momentum=0.9, decay=0.0005
尺度的不变性:
我们探索了两种方法来达到目标检测中的尺度不变性:
- 暴力学习 brute force learning
- 图像金字塔 image pyramids
这两个策略和 SPPnet 中的一样。在 brute-force 策略中,每张图片在一个预先定义好的尺度上进行,训练和测试时都是如此。网络必须直接从训练数据中学习尺度不变性
多尺度的方法则是通过使用 image pyramid 来给网络提供近似的尺度不变性。在测试时,image pyramid 被用来近似去对每一个 object proposal 进行尺度归一化。在多尺度训练时,每个图像采样后。我们随机采样一个 pyramid 的尺度,用来做数据增强(这一点来自 SPPnet)。由于 GPU 内存的限制,我们只在小网络上进行了实验。
Fast RCNN
网络接受一张图片(或一个图像金字塔)以及 R R R 个 proposal 来进行训练。在测试时, R R R 通常在 2000 2000 2000 左右,即使我们还会考虑更多 proposal 的情况(45k),当使用一个图像金字塔时,每个 RoI 都被赋予了一个尺度,使得尺度变换后的 RoI 的面积大概是 22 4 2 224^2 2242(依据仍然是 SPPnet)
对于每个测试的 RoI
r
r
r ,前向传播输出类别的后验概率分布
p
p
p 以及一系列的预测出的相对于
r
r
r 的 bbox 的偏置(每个 K
类别中的得到它自己的 refine 之后的 bbox prediction)我们用估计的概率
P
r
(
c
l
a
s
s
=
k
∣
r
)
≜
p
k
\mathrm{Pr}(\mathrm{class}=k|r)\triangleq p_k
Pr(class=k∣r)≜pk ,然后我们对每个类别单独进行了 NMS ,使用的算法的设置来源于 RCNN
Truncated SVD for faster detection
对于整张图的分类,花在计算全连接层上的时间很少。但是,对于检测来说,需要处理的 RoI 很多,前向传播的大约一半时间都花在了全连接层上。大的全连接层可以用 truncated SVD 进行很轻易地加速[5,23]
在这种技术中,一个层地参数为
u
×
v
u\times v
u×v 的权重矩阵
W
W
W ,它可以用 SVD 近似分解为:
W ≈ U Σ t V T W\approx U\Sigma_tV^T W≈UΣtVT
在这种分解中, U U U 是一个 u × t u\times t u×t 的矩阵,包含 W W W 的前 t t t 个左奇异向量(left-singular vector), Σ t \Sigma_t Σt 是一个 t × t t\times t t×t 的对角矩阵,包含 W W W 最大的 t t t 个奇异值, V V V 是一个 v × t v\times t v×t 的矩阵,包含前 t t t 个 W W W 的右奇异值向量(right-singular vector)。Truncated SVD 可以将参数量从 u v uv uv 减少至 t ( u + v ) t(u+v) t(u+v) 。假如 t ≪ min ( u , v ) t\ll \min(u,v) t≪min(u,v) ,则这样的加速是很可观的。为了对网络进行压缩, W W W 对应的一个单一的全连接层被两个全连接层进行了替换,并且过程中不需要在他们中间引入非线性因素。第一层用的是权重矩阵 Σ t V T \Sigma_tV^T ΣtVT (没有偏置),第二个用的是 U U U (使用原来 W W W 对应的偏置)。当 RoI 的数量很多时,这样简单的压缩可以进行很好的加速。
主要结果
实验设置
使用了三个预训练好的网络: S S S 对应 RCNN 中的 CaffeNet(本质是 AlexNet)。 M M M 对应 VGG_CNN_M_1024。 L L L 对应 VGG16 。
训练和测试的时间
Truncated SVD 带来的加速