Fast R-CNN 是在R-CNN的基础上进行的改进,它在训练和测试速度及目标检测精度上均有提高。相 在VGG16
模型上,相对于R-CNN, Fast R-CNN在训练时间上提高了9倍,在测试时间上提高了213倍;相对于SPP-Net,Fast R-CNN在训练时间上提高了3倍,在测试时间上提高了10倍。
作者首先提出了目标检测中的R-CNN和SPPNet的缺点。
对于R-CNN,它的训练阶段是一个多阶段的过程,包括生成目标候选区域、提取特征、训练SVM、拟合边界框回归量(Bounding-box regressors);并且在空间和时间方面代价巨大;此外在测试阶段时检测一张图片需要47s。
对于SPPNet,同与R-CNN一样,该训练阶段也是是一个多阶段过程,涉及提取特征、使用log loss微调网络、训练SVM、最后拟合边界框回归。与R-CNN不同的是,SPP中提出的微调算法无法更新空间金字塔池池化层之前的卷积层,即固定卷积层限制了深度网络的准确性。
其次作者提出了对于R-CNN和SPPNet的缺点改进后的Fast R-CNN的优点:
接下来对网络架构进行详细的总结:
对于任何在有效候选区域中的特征,RoI池化层通过最大池化方法将该特征转换为固定大小的特征向量表示。每个RoI是一个包含卷积特征图的矩形窗口,通过4元组(r,c,h,w)
来定义,矩形左上角顶点为(r,c)
,矩形的高和宽为(h,w)
。
RoI池化层将RoI区域划分成h×w
个子网格,然后最大池化每一个子网格内的值,最后输出相应的h×w
的网格结果。同标准最大池化一样,RoI池化是对特征图的每个通道独立进行的。可以把RoI池化看作是特殊的单层SPP池化,其中h和w是超参数。
为将提前训练好的AlexNet、VGG16等网络调整为Fast R-CNN模型,作者对AlexNet、VGG16等网络进行了三方面的调整:
Q: 为什么SPPnet不能更新空间金字塔池化层之前的卷积层参数?
SPP层反向传播效率很低, 其根本原因是每一个训练样本(例如RoI)均来自不同的图片,而我们知道反向传播需要用到正向传播过程中的数据,则导致需要存储的数据量巨大!!!
SPP-Net中fine-tuning的训练样本是来自所有图像的所有RoI打散后均匀采样的,即RoI-centric sampling,这就导致SGD的每个batch的样本来自不同的图像,需要同时计算和存储这些图像的Feature Map,过程变得expensive;Fast R-CNN采用分层采样思想,先采样出N张图像(image-centric sampling),在这N张图像中再平均采样出R个RoI,即每张图片采样出R/N个RoI,同一图像的RoI共享计算和内存。
论文中举了一个例子说到:设N = 2, R = 128,也就是说只用计算和存储2张图像卷积正向传播过程中的数据,那么需要存储的数据量相比R-CNN和SPP小了64倍!
Fast R-CNN 通过 单阶段微调同时优化softmax分类器和边界框回归器来简化训练过程,该单阶段微调的组成(损失、小批量采样策略、RoI池化层的方向传播、SGD超参数)如下所示。
u
和真实边界框v
的训练RoI,同时训练分类和边界框回归的多任务损失函数定义为:softmax
输出的预测概率p
对于真实类型u
的交叉熵损失函数Lcls(p,u) = -ulogp - (1-u)log(1-p); 之前提到softmax输出u+1
个类型,其中加1表示背景类,而在这里若RoI中没有真实标注的边界框而仅存在背景类时,[u≥1]
返回0,即此时Lloc项为0。
对于边界框回归:
Q2:注意这里使用L1范数而非L2范数的原因是:
L1范数的鲁棒性较强,它不像R-CNN
和SPPnet
中使用的L2范数对异常值那么敏感。当回归目标无边界时,使用L2范数训练时需要仔细调整learning rate
以避免梯度爆炸,而使用L1范数消除了对于学习率的敏感性。
将真实的回归目标 vi 标准化为均值为0,方差为1,λ=1
。
小批量抽样(Mini-batch sampling)
对于每个小批量样本,RoI与真实边界框的IoU大于0.5的标记为u≥1;取IoU为区间[0.1, 0.5)中最大值为背景,标记为u=1;数据增广方法采用概率为0.5的图像水平翻转。
通过RoI池化层的反向传播
xi表示RoI池化前的特征图上的像素点,yrj表示第r个RoI池化后的第j个的像素点,RoI的前向传播为
其中i*(r, j)表示如果第r个RoI的第j个像素点的来源,是最大池化时选出的最大的那个点对应的坐标;
但是这里由于一个RoI池化前的像素点xi可能和多个不同的yrj有映射关系(因为存在多个候选框,候选框之间可能有重叠),因此反向传播过程的公式为:
奇异值分解(Singular Value Decomposition,SVD)
是一种矩阵分解(Matrix Decomposition)
的方法。假设有 m×n
的矩阵A
,那么 SVD
就是要找到如下式的这么一个分解,将 A 分解为 3 个矩阵的乘积:
Am×n=Um×mΣm×nVTn×n
其中对于分解后的三个矩阵计算方法 参考这里。
在Python 中可以使用 numpy
包的linalg.svd()
函数来求解 SVD。
论文中提到,在目标检测过程中,需要处理的RoIs区域数量非常大,几乎一半的前向传播时间都花在全连接层的计算当中,对全连接层的权重W采用奇异值分解(SVD)可以加快计算速度。原因是SVD可以减少参数数量。
而采用SVD后对于网络模型的改动为:和权重W相关的单一全连接层改为两个全连接层,第一个全连接层的权重为Σm×nVTn×n(偏差为0),第二个全连接层的权重为Um×m(偏差和改动之前的全连接层偏差相同)
Fast R-CNN 是在R-CNN基础上进行的改进,实验大多实在VGG-16模型上进行的。其改进共可分为三个方面,以上都有详细提到, 这里做一个最后的总结:
提出了RoIPooling,避免了R-CNN中对提取的region proposals进行先缩放再逐一卷积获取特征的步骤,加速了整个网络的学习处理过程,这是巨大的改进;并且RoIPooling是可导的,因此使得整个网络可以实现end-to-end learning,这点可以认为是Fast R-CNN相对于R-CNN最大的改进之处;
采用了Multi-task loss进行边框回归,在R-CNN中也有这方面的实验;
利用了截断的奇异值分解(Truncated SVD for faster detection)加速了网络计算;
参考博客1
欢迎关注【OAOA】