论文原文地址为: Fast R-CNN
1. RoI Pooling详解
RoI Pooling其实是SPP pooling的一种特殊情况。SPP pooling可以采用多个金字塔层,RoI只采用一种。具体做法为: 对于映射到feature map上的RoI(Region Proposal通过变换得来),假设该RoI大小为 h×w h × w ,RoI Pooling的输出为 H×W H × W ( H,W H , W 为超参数)。将 h×w h × w 的 RoI R o I 分解成 H×W H × W 的子网格,每个格子大小近似为 hH×wW h H × w W 。然后再对 H×W H × W 个格子,每个格子取 maxpooling m a x p o o l i n g 。这样最后对于每个RoI,不论其大小如何,都能得到一个大小为 H×W H × W 的feature map。
如下:
1. 输入feture map
2. region proposal投影(左上角,右下角坐标):(0,3),(7,8)。
3. 将其划分为(2*2)个sections(因为输出大小为2*2),我们可以得到:
4. 对每个section做max pooling,可以得到:
2. Fast RCNN的的主要贡献
RCNN的缺点非常明显。SPP在此基础上进行了一些改进,但SPP也存在很大问题。SPP仍然是分阶段训练而不是一个端到端的过程,分为:提取特征,使用log损失对网络进行微调,训练SVM分类器,最后拟合检测框回归。特征也写入磁盘。并且SPP提出的fine tuning方法不能跟新SPP之前的卷积层。因为SPP并不是一个端到端的过程。这种固定的卷积层限制也限制了深层网络的精度。RCNN主要贡献有:
- 比RCNN和SPPNet有更高的目标检测精度(mAP)
- 训练采用的是多任务损失(multi-task loss),并且是单阶段,端到端的(end-to-end)
- 训练可以更新所有网络层参数
- 不需要磁盘空间缓存特征
3. Fast RCNN的网络结构
Fast RCNN的输入有两个: 一整张图像和一些列的object proposals。网络首先对整张图像进行conv和pooling的处理,得到一个feature map。然后对于每个Region proposal, 使用RoI Pooling层提取一个固定长度的特征向量(feature vector)。特征向量送入一系列全连接层,其最终分支产生两个同级输出层:一个用来产生softmax概率(K个object再加1个background)。另外一个用来产生4个实数值,每个实数值对应1个object class的bounding box。每组4个值表示K个类别的一个类别的检测框位置的修正后的值。
4. 预训练
将ImageNet上面训练好的网络进行调整。
1. 将最后的一个Max Pooling层由RoI Pooling层代替。
2. 网络的最后一个全连接层和Softmax被替换为前面描述的两个同级层(一个全连接层和K+1的softmax分类层以及bounding box回归层)。
3. 网络的输入该为接受两个输入:list of images and list of RoIs in those images。
4. 训练过程
用反向传播更新所有网络层的权重是Fast RCNN的重要能力。SPPNet无法更新低于金字塔池化层的权重的原因是当每个RoI来自不同的图像时(SPPNet的做法),每个RoI可能会有一个非常大的感受野,通常是贯穿整个图像的。由于前向传播要处理整张图像,训练的输入太大。
文中提出了一个分层次抽样的方法。分为两步:
- 抽样出 N N 张图片
- 每张图片抽样出个RoI
来自同一张图片的RoI在前向传播和反向传播中是共享计算和内存的。减小N就减小了小批量的计算。例如 N=2,R=128 N = 2 , R = 128 比从128张图片中,每张图片取1个RoI要快64倍(RCNN和SPPNet的做法)。
这个策略的一个令人担心的问题是它可能导致训练收敛变慢,因为来自相同图像的RoI是相关的。但实验证明这个问题不存在。
5. 多任务损失
除了分层采样,Fast R-CNN使用了一个精细的训练过程,在微调阶段联合优化Softmax分类器和检测框回归,而不是分别在三个独立的阶段训练softmax分类器,SVM和回归器。
Fast RCNN的输出有2部分。一个是分类损失,一个是bounding box回归损失:
其中 Lcls(p,u L c l s ( p , u 是对数分类损失。而第二项是bounding box回归损失。前面乘以一个indicator function: [u≥1] [ u ≥ 1 ] 表示当 u=0 u = 0 时是背景,此时是没有bounding box的。其中: tu=(tux,tuy,tuw,tuh) t u = ( t x u , t y u , t w u , t h u ) 。 v=(vux,vuy,vuw,vuh) v = ( v x u , v y u , v w u , v h u ) 是ground truth。bounding box回归使用的损失函数为:
其中:
使用 smoothL1 s m o o t h L 1 损失的原因是,当预测值与目标值相差太大的时候,并且这种差别其实是没有界限的。这样在计算损失的时候,如果采用 L2 L 2 损失,则: L2=|f(x)−Y|2 L 2 = | f ( x ) − Y | 2 。导数为: 2(f(x)−Y)f′(x) 2 ( f ( x ) − Y ) f ′ ( x ) 。因为其中包含了 f(x)−Y f ( x ) − Y 这一项,可能会产生梯度爆炸现象。而采用 smoothL1 s m o o t h L 1 损失之后,当预测值与目标值差距太大时,导数为 ±f′(x) ± f ′ ( x ) 。这样,原来 L2 L 2 损失里面的 f(x)−Y f ( x ) − Y 被替换成 ±1 ± 1 。能够避免梯度爆炸。
另一方面,预测值与目标值差距大一般是因为噪声数据造成的。因此该方法也能增强鲁棒性,对抗噪声数据。
最后为了2个loss之间的平衡,将回归的bounding的数值都进行归一化,变成0均值和单位方差。实验中 λ λ 取 1 1 <script type="math/tex" id="MathJax-Element-66">1</script>。
6. 使用截断SVD来加快检测
文中对全连接层的矩阵乘法应用了SVD矩阵分解的方法来加快计算过程。
7. 需要fine tuning的卷积层
首先,并不是所有的卷积层都需要微调。在较小的网络(S和M)中,conv1(第一个卷积层)是通用的和任务独立的(一个众所周知的事实1)。允许conv1学习或不学习,对mAP没有很有意义的影响。对于VGG16,我们发现只需要更新conv3_1及以上(13个卷积层中的9个)的层。这种观察是实用的:
(1)从conv2_1更新使训练变慢1.3倍(12.5小时对比9.5小时)
(2)从conv1_1更新GPU内存不够用。当从conv2_1学习时mAP仅为增加0.3个点。
因此所有Fast R-CNN在本文中结果都使用VGG16微调层conv3_1及以上的层,所有实验用模型S和M微调层conv2及以上的层。
8. 检测框数量对精度的影响
随着Region Proposal数量的增加,发现mAP上升,然后随着候选区域计数增加而略微下降。实验表明,用更多的候选区域没有帮助,甚至稍微有点伤害准确性。