Fast RCNN 笔记

在这里插入图片描述
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 倍,并且更加准确。

目标检测比分类要复杂,是因为检测有两个挑战:

  1. 需要处理大量的候选物体的位置(proposal)
  2. 这些候选位置只提供了一个粗略的定位,需要对其进行 refine 来使之更加准确。

本文精简了训练的流程,我们提出了一个单阶段的训练流程来同时进行分类和 bbox 的 refine

RCNN 和 SPPNet

Region-base CNN 通过使用 deep CNN 来对物体 proposal 进行分类,得到了很高的精度,但是有很明显的缺点:

  1. 训练是多阶段的流程,RCNN 首先用 log loss 来在 object proposal 上微调卷积神经网络,然后再喂给 SVM 进行分类
  2. 训练需要很多时间和空间,训练 SVM 以及 bbox regressor 时,需要把每个 proposal 中的特征提取出来然后写到硬盘里,耗费大量时间空间
  3. 检测速度慢,测试时用 VGG-16 在一张图上需要 47s

RCNN 速度慢的主要原因在于没有共享特征的计算。SPPNet(Spatial pyramid pooling networks)通过共享计算来为 RCNN 提速。SPPnet 对整个输入图像计算卷积特征图,然后把每个 proposal 用一个提出来特征向量后进行分类。每个 proposal 是通过把 proposal 中的特征图经过 max pooling 得到一个固定长度的输出(比如 6×66\times 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 ,其好处有:

  1. 比 RCNN, SPPNet 的 mAP 更高
  2. 单阶段训练,使用 multi-task loss
  3. 训练时可以更新所有网络的参数
  4. 不需要磁盘去存储特征

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×WH\times W (比如 7×77\times7),其中 H,WH,W 时超参数,和 RoI 无关。RoI 时卷积特征图上的一个矩形框,每个 RoI 定义为 (r,c,h,w)(r,c,h,w) ,表示左上角的坐标以及高和宽。

RoI max pooling 通过将 h×wh\times w 大小的 RoI 区域分成 H×WH\times W 大小的格子,每个子窗口的大小约为 hH×wW\dfrac{h}{H}\times\dfrac{w}{W} ,然后对每个子窗口进行 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 进行初始化时,需要进行以下三个变换:

  1. 将最后的 max pooling 层换成 RoI pooling ,然后将 H,W 设置成符合网络第一个全连接层的数(比如对于 VGG16 来说 H=W=7)
  2. 网络的最后一个全连接层和 softmax 用两个分支来替换(一个进行分类,一个进行坐标回归)
  3. 网络调整为接收两个输入:图片输入以及 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+1K+1 个类别上的离散的概率分布(对于每个 RoI):p=(p0,...,pk)p=(p_0,...,p_k) 其中 pp 是用一个全连接层用 softmax 输出 K+1K+1 个结果。第二个分支输出 bbox regression 的偏移 tk=(txk,tyk,twk,thk)t^k=(t_x^k,t_y^k,t_w^k,t_h^k) ,对于每个类别。我们使用 RCNN 文章中给出的参数化 tkt^k 的做法。其中 tkt^k 表示一个尺度不变的平移以及 log 空间内宽/高相对于 proposal 的偏移。

每个训练的 RoI 都用一个 ground truth 类别 uu 和 ground truth bbox regression target vv 来标记。我们在每个标记了的 RoI 上使用 multi-task loss LL 来联合训练分类和 bbox regression:

在这里插入图片描述
其中 Lcls(p,u)=logpuL_{cls}(p,u)=\log p_u 是对于类别 uu 的对数损失

第二个损失 LlocL_{loc}uuv=(vx,vy,vw,vy)v=(v_x,v_y,v_w,v_y) 以及预测结果 tu=(txu,tyu,twu,thu)t^u=(t_x^u,t_y^u,t_w^u,t_h^u) 上进行定义。Iverson bracket indicator function [u1][u\ge 1] 表示 u1u\ge 1 时取值为 1 ,否则取值为 0。对于背景 RoI 是没有 bbox 的,因此对应的 LlocL_{loc} 是忽略掉的,对于 bbox regression,使用的 loss 为:

在这里插入图片描述
smooth L1 loss 是一个鲁棒的 L1 loss,它对异常值不敏感(不像 RCNN 和 SPPnet 中使用的 L2 loss 那样 )。当回归的目标没有界时,用 L2 进行训练时需要对学习率仔细调整以避免梯度爆炸。而 smooth l1 loss 降低了这种敏感性。

式子 1 中的超参 λ\lambda 控制两个 loss 之间的平衡。我们对 ground truth 目标 viv_i 进行了归一化,使之具有零均值和单位方差,所有的实验中使用的 λ=1\lambda=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=128R=128 ,也就是说在每张图片中采样 64 个 RoI。和 RCNN 中一样,我们从 proposal 中取出 25% 的 RoI ,他们和 ground truth 的 IoU 至少为 0.5。这些 RoI 包含被分为前景的类别的样本,即 u1u\ge 1 。剩下的 RoI 从 IoU 为 [0.1,0.5)[0.1,0.5) 中采样获得,这些 RoI 标记为负样本,u=0u=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=1N=1),扩展到多张图片是很简单的,因为前向传播独立地处理每张图像。

xiRx_i\in\mathbb{R} 为第 ii 个进入 RoI pooling 的激活层输入。令 yrjy_{rj} 为第 rr 个 RoI 的第 jj 个输出。RoI pooling layer 计算 yrj=xi(r,j)y_{rj}=x_{i^*}(r,j) 其中 i(r,j)=arg maxiR(r,j)xii^*(r,j)=\argmax_{i'\in\mathcal{R}(r,j)}x_{i'}R(r,j)\mathcal{R}(r,j)yrjy_{rj} max pool 的子窗口内的下标值的集合。一个单独的 xix_i 可以赋值给多个不同的输出 yrjy_{rj}

RoI pooling layer 的 反向传播方程计算损失函数相对于每个输入变量 xix_i 的偏导:

Lxi=rj[i=i(r,j)]Lyrj \frac{\partial L}{\partial x_i}=\sum_r\sum_j[i=i^*(r,j)]\frac{\partial L}{\partial y_{rj}}

也就是说,对于每一个 mini-batch RoI rr 和每一个 pooling 的输出单元 yrjy_{rj} ,假如 ii 是被 yrjy_{rj} max pooling 选中的下标,那么其对应的偏导 L/yrj\partial L/\partial y_{rj} 要进行累加。在反向传播时,偏导 L/yrj\partial L/\partial y_{rj} 已经被 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

尺度的不变性:

我们探索了两种方法来达到目标检测中的尺度不变性:

  1. 暴力学习 brute force learning
  2. 图像金字塔 image pyramids

这两个策略和 SPPnet 中的一样。在 brute-force 策略中,每张图片在一个预先定义好的尺度上进行,训练和测试时都是如此。网络必须直接从训练数据中学习尺度不变性

多尺度的方法则是通过使用 image pyramid 来给网络提供近似的尺度不变性。在测试时,image pyramid 被用来近似去对每一个 object proposal 进行尺度归一化。在多尺度训练时,每个图像采样后。我们随机采样一个 pyramid 的尺度,用来做数据增强(这一点来自 SPPnet)。由于 GPU 内存的限制,我们只在小网络上进行了实验。

Fast RCNN

网络接受一张图片(或一个图像金字塔)以及 RR 个 proposal 来进行训练。在测试时,RR 通常在 20002000 左右,即使我们还会考虑更多 proposal 的情况(45k),当使用一个图像金字塔时,每个 RoI 都被赋予了一个尺度,使得尺度变换后的 RoI 的面积大概是 2242224^2(依据仍然是 SPPnet)

对于每个测试的 RoI rr ,前向传播输出类别的后验概率分布 pp 以及一系列的预测出的相对于 rr 的 bbox 的偏置(每个 K
类别中的得到它自己的 refine 之后的 bbox prediction)我们用估计的概率 Pr(class=kr)pk\mathrm{Pr}(\mathrm{class}=k|r)\triangleq p_k ,然后我们对每个类别单独进行了 NMS ,使用的算法的设置来源于 RCNN

Truncated SVD for faster detection

对于整张图的分类,花在计算全连接层上的时间很少。但是,对于检测来说,需要处理的 RoI 很多,前向传播的大约一半时间都花在了全连接层上。大的全连接层可以用 truncated SVD 进行很轻易地加速[5,23]

在这里插入图片描述
在这里插入图片描述
在这种技术中,一个层地参数为 u×vu\times v 的权重矩阵 WW ,它可以用 SVD 近似分解为:

WUΣtVT W\approx U\Sigma_tV^T

在这种分解中,UU 是一个 u×tu\times t 的矩阵,包含 WW 的前 tt 个左奇异向量(left-singular vector),Σt\Sigma_t 是一个 t×tt\times t 的对角矩阵,包含 WW 最大的 tt 个奇异值,VV 是一个 v×tv\times t 的矩阵,包含前 ttWW 的右奇异值向量(right-singular vector)。Truncated SVD 可以将参数量从 uvuv 减少至 t(u+v)t(u+v) 。假如 tmin(u,v)t\ll \min(u,v) ,则这样的加速是很可观的。为了对网络进行压缩,WW 对应的一个单一的全连接层被两个全连接层进行了替换,并且过程中不需要在他们中间引入非线性因素。第一层用的是权重矩阵 ΣtVT\Sigma_tV^T (没有偏置),第二个用的是 UU (使用原来 WW 对应的偏置)。当 RoI 的数量很多时,这样简单的压缩可以进行很好的加速。

主要结果

实验设置

使用了三个预训练好的网络:SS 对应 RCNN 中的 CaffeNet(本质是 AlexNet)。MM 对应 VGG_CNN_M_1024。LL 对应 VGG16 。

训练和测试的时间

在这里插入图片描述
Truncated SVD 带来的加速

在这里插入图片描述

posted @ 2020-04-21 09:23  winechord  阅读(79)  评论(0编辑  收藏  举报