题外话:近期好好学习一下Fast RCNN这篇经典的文章,如有说的不对的地方,欢迎大家讨论。
1. 概述:
Fast RCNN训练VGG16网络时的速度比RCNN提高了9倍,测试时比RCNN快了213倍,并且获得了更高的精度。与SPPnet算法相比,训练速度提高了3倍,测试提高了10倍,并获得了并SPPnet更高的精度。
2. Fast RCNN的结构和训练过程
Fast RCNN的结构如图所示。
图1. Fast RCNN的结构
1) 网络的输入是整幅图像以及一系列的目标预测框(object proposal)。
2) 首先,网络使用多个卷积层(conv)和最大池化层(max pooling)对整张图像进行特征提取,生成一个卷积特征图(conv feature map)。
3) 然后,对于每个目标预测框(object proposal),使用ROI pooling(Region of Interest,即感兴趣区域的池化操作)提取了一段定长的特征向量。
4) 每个特征向量都输入到一系列的全连接层(fc)中,然后分别输出到2个分支:一个使用softmax预测当前检测框(proposal)作为K种类别的概率;另一个层输出4个真值,即为改善检测框的位置坐标。
2.1 RoI pooling层
RoI pooling层使用max pooling(最大池化)将任意感兴趣的有效区域(有可能是前景的区域块)中的特征转换为具有一个固定尺寸大小的特征矩阵(feature map),写作H×W(如,7×7),其中H和W是独立于RoI的高阶参数。
本文中所用到的RoI pooling即一个矩形窗口中的图像内容转换为一个卷积特征矩阵(conv feature map)。每个RoI定义为一个四元对(r, c, h, w),分别表示该矩形框的左上角坐标(r, c)和它的高和宽(h, w)。
RoI max pooling通过将尺寸为h×w的RoI窗口划分为一个H×W的网格状的子窗口,如12×16的RoI尺寸划分为4×3的网格子窗口。那么,近似于每个子窗口的大小为 h/H × w/W,即 12/4 × 16/3。然后在每个子窗口里进行max pooling,输出的特征窗口为H×W,即4×3。
文中提到RoI pooling其实等同于SPPnets中用到的空间金字塔pooling的特殊版本,相当于只有一层的金字塔。SPPnets的方法还没有学习,之后可以看看。
2.2 基于预训练网络的初始化
作者提到实验使用了三个预训练的ImageNet网络,每个包含5个最大池化层(max pooling)以及5至13层卷积层(conv layer)。Fast RCNN使用预训练网络进行初始化,主要分为以下三个部门:
1)最后一个max pooling层由一个RoI pooling层替代,参数H和W与网络的第一个全连接层相容,如VGG16中H = W = 7。
2)网络的最后一个全连接层和softmax(ImageNet里包含1000种分类)替换为两个分支层,如上文中提到的那样(一个全连接的softmax输出分类概率和一个检测框回归器)。
3) 网络修改为接收两个数据输入:一系列的图像和一系列RoI从图中提取的特征矩阵。
2.3 算法的调优(Fine-tune)
作者提到Fast RCNN的优势之一是可以使用bp对网络中的所有参数进行更新。(当然,近期对bp调优是否正确的说法越来越多,期待dnn的变革吧^0^)
Fast RCNN中提出了一个启发式的随机梯度下降(SGD)的策略,通过对N张图像和R/N个RoI区域进行采样进行实现。具体说来,同一张图中的RoI具有相同的计算代价,例如,当N=2时,即有2张输入图像时,R = 128,那么提出的优化策略可以只计算一次同一张图中的RoI,这样就比从128张不同的图中提取不同的RoI快了R/N倍,也就是128/2 = 64倍。此外,Fast RCNN还使用了一个流水线的训练模式,即一个调优过程,级联优化了一个softmax分类器和一个检测框的回归器。下面具体介绍一下这些优化的组成部分。
1. 多任务的损失函数(Multi-task loss)
如上所述,Fast RCNN有两个输出,第一个是K+1个种类的类别概率向量,另一个是检测框回归器(bounding box regressor)的位移输出,t^k = (t_x^k, t_y^k, t_w^k, t_h^k),对于每个类别k∈K(即总共预测类别)。
每个训练样本RoI都标记了ground truth类别u,以及ground truth检测框v。多任务的损失函数L定义如下:
其中L_{cls}是对真实类别u的log loss。L_{loc}是基于每个u的四元子v = (vx, vy, vw, vh)定义的,对应预测的四元子t^u = (t_x^u, t_y^u, t_w^u, t_h^u)。λ平衡两个loss的权值,其中[u ≥ 1]的函数作用是,当u ≥ 1取值为1,否则为0(即当预测为背景时不用计算loss)。对于检测框回归器L_{loc}定义如下:
loss函数中的smooth平滑函数使用的是“鲁棒”L1 loss,对于边界的敏感度比L2更为鲁棒。
2. 随机梯度下降的Mini-batch sampling
调优过程中,每个SGD mini-batch由N = 2张图像组成(图像随机选出)。mini-batch的尺寸设置为R = 128,则在每张图中提取64个RoI。
3. RoI池化层的Bp过程
Fast RCNN使用Bp将导数传过RoI池化层。假设每个mini-batch只输入一张图(N = 1)。
设是RoI池化层的第i个输入,令
表示第r个RoI池化层的第j个输出。RoI池化层计算下式:
其中,,其中
是输入子窗口到输出单元
的索引。
RoI池化层的反向(backwards)传递函数根据每个xi计算偏导如下:
可以理解为,对于每个mini-batch中的RoI r和每个池化输出,若i是由最大池化选出的
偏导
就累加。在bp中,偏导由反向传递函数计算得到。
4. 随机梯度下降的高阶参数(SGD hyper-parameters)
连接两个输出的全连接层根据高斯分布(mean = 0,标准差 = 0.01和0.001)进行初始化。其余参数可以查看论文。
3. 实验结果
在VOC2007数据集上的实验结果如下表所示:
在VOC2010数据集上的实验结果:
在VOC2012数据集上的实验结果:
Fast RCNN虽然提出的时间不久,但是获得了广泛的认可和应用,算是深度学习中的代表框架之一。个人认为是由其精度和效率的折中效果都很好,再加上GitHub上的源码公开,都让Fast RCNN的地位不可动摇。接下来会对代码的运行和学习过程进行总结。
题外话:最近开始求职,一切才刚开始,感觉看不到终点,不过慢慢找到了方向,尽管步履维艰,脚踏实地的加油吧!距离R-Day还有22天^_________________^!