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 倍,并且更加准确。
目标检测比分类要复杂,是因为检测有两个挑战:
- 需要处理大量的候选物体的位置(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 得到一个固定长度的输出(比如 )在。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 (比如 ),其中 时超参数,和 RoI 无关。RoI 时卷积特征图上的一个矩形框,每个 RoI 定义为 ,表示左上角的坐标以及高和宽。
RoI max pooling 通过将 大小的 RoI 区域分成 大小的格子,每个子窗口的大小约为 ,然后对每个子窗口进行 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 的网络有两个输出层,第一个输出在 个类别上的离散的概率分布(对于每个 RoI): 其中 是用一个全连接层用 softmax 输出 个结果。第二个分支输出 bbox regression 的偏移 ,对于每个类别。我们使用 RCNN 文章中给出的参数化 的做法。其中 表示一个尺度不变的平移以及 log 空间内宽/高相对于 proposal 的偏移。
每个训练的 RoI 都用一个 ground truth 类别 和 ground truth bbox regression target 来标记。我们在每个标记了的 RoI 上使用 multi-task loss 来联合训练分类和 bbox regression:
其中 是对于类别 的对数损失
第二个损失 在 和 以及预测结果 上进行定义。Iverson bracket indicator function 表示 时取值为 1 ,否则取值为 0。对于背景 RoI 是没有 bbox 的,因此对应的 是忽略掉的,对于 bbox regression,使用的 loss 为:
smooth L1 loss 是一个鲁棒的 L1 loss,它对异常值不敏感(不像 RCNN 和 SPPnet 中使用的 L2 loss 那样 )。当回归的目标没有界时,用 L2 进行训练时需要对学习率仔细调整以避免梯度爆炸。而 smooth l1 loss 降低了这种敏感性。
式子 1 中的超参 控制两个 loss 之间的平衡。我们对 ground truth 目标 进行了归一化,使之具有零均值和单位方差,所有的实验中使用的
我们注意到 [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 大小为 ,也就是说在每张图片中采样 64 个 RoI。和 RCNN 中一样,我们从 proposal 中取出 25% 的 RoI ,他们和 ground truth 的 IoU 至少为 0.5。这些 RoI 包含被分为前景的类别的样本,即 。剩下的 RoI 从 IoU 为 中采样获得,这些 RoI 标记为负样本,。其中的下界 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 只有一张图片(),扩展到多张图片是很简单的,因为前向传播独立地处理每张图像。
令 为第 个进入 RoI pooling 的激活层输入。令 为第 个 RoI 的第 个输出。RoI pooling layer 计算 其中 , 为 max pool 的子窗口内的下标值的集合。一个单独的 可以赋值给多个不同的输出 。
RoI pooling layer 的 反向传播方程计算损失函数相对于每个输入变量 的偏导:
也就是说,对于每一个 mini-batch RoI 和每一个 pooling 的输出单元 ,假如 是被 max pooling 选中的下标,那么其对应的偏导 要进行累加。在反向传播时,偏导 已经被 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
网络接受一张图片(或一个图像金字塔)以及 个 proposal 来进行训练。在测试时, 通常在 左右,即使我们还会考虑更多 proposal 的情况(45k),当使用一个图像金字塔时,每个 RoI 都被赋予了一个尺度,使得尺度变换后的 RoI 的面积大概是 (依据仍然是 SPPnet)
对于每个测试的 RoI ,前向传播输出类别的后验概率分布 以及一系列的预测出的相对于 的 bbox 的偏置(每个 K
类别中的得到它自己的 refine 之后的 bbox prediction)我们用估计的概率 ,然后我们对每个类别单独进行了 NMS ,使用的算法的设置来源于 RCNN
Truncated SVD for faster detection
对于整张图的分类,花在计算全连接层上的时间很少。但是,对于检测来说,需要处理的 RoI 很多,前向传播的大约一半时间都花在了全连接层上。大的全连接层可以用 truncated SVD 进行很轻易地加速[5,23]
在这种技术中,一个层地参数为 的权重矩阵 ,它可以用 SVD 近似分解为:
在这种分解中, 是一个 的矩阵,包含 的前 个左奇异向量(left-singular vector), 是一个 的对角矩阵,包含 最大的 个奇异值, 是一个 的矩阵,包含前 个 的右奇异值向量(right-singular vector)。Truncated SVD 可以将参数量从 减少至 。假如 ,则这样的加速是很可观的。为了对网络进行压缩, 对应的一个单一的全连接层被两个全连接层进行了替换,并且过程中不需要在他们中间引入非线性因素。第一层用的是权重矩阵 (没有偏置),第二个用的是 (使用原来 对应的偏置)。当 RoI 的数量很多时,这样简单的压缩可以进行很好的加速。
主要结果
实验设置
使用了三个预训练好的网络: 对应 RCNN 中的 CaffeNet(本质是 AlexNet)。 对应 VGG_CNN_M_1024。 对应 VGG16 。
训练和测试的时间
Truncated SVD 带来的加速