Fast R-CNN论文:Fast R-CNN
Fast R-CNN,是Ross Girshirck提出的、基于R-CNN(和SPP)做出改进的目标检测网络。
R-CNN的缺点
R-CNN的缺点:
1.需要分步训练。原因:被R-CNN的网络结构(Region Proposal→Feature Extraction→SVM Classification→Bounding Box Regression)所限,R-CNN需要分步训练用于特征提取的卷积神经网络、用于分类的SVM和Bounding Box的回归变换参数。
2.训练的时间和空间成本太大。原因:对每个(共2000个)Region Proposal而言,都需要分别通过特征提取网络(前向传播),在训练中这些网络隐藏层中的变量都要被存储在内存。
3.目标检测速度慢。原因:这也是因为每个Region Proposal中的内容都要通过一遍特征提取网络。
Fast R-CNN的主要改进思路
1.在每个Region Proposal之间共享特征提取网络的输出。
2.采用multi-task loss(Classification 和 Bounding Box Regression)评估模型输出,从而实现端到端的训练过程。
Fast R-CNN的结构
1.输入:网络输入为(任意尺寸的图像,[若干Region Proposal])。Region Proposal通过Selective Search方法预先生成。
2.特征提取:先不考虑Region Proposal,只考虑原始图像,通过卷积神经网络提取特征。根据选取的预训练模型不同,卷积层会有5~13层,最大池化层有4层。
3.ROI Pooling:在特征图像上,对于每个Region Proposal而言,保留其里面的特征图内容,舍弃其它的(原始图像经过池化和带stride的卷积,导致特征图像被下采样,则Region Proposal等比变小)。将保留的内容通过最大池化下采样成H×W的输出,输出被展平成(H×W)*1的一维列向量,H、W为预先决定的网络超参数。ROI Pooling层的位置替代了预训练模型的第5个池化层。
4.若干个全连接层,用一般的神经网络做逻辑运算。
5.最后分别经过两个全连接层,一个用于多分类(K个对象类别+1个背景类别);一个用于Bounding Box Regression。
训练
训练集采样
R-CNN的训练集采样策略是,对于每个mini-batch而言,从尽可能多(128张)的图片中,每张图片取少量(2个)ROI作为训练集,这样会导致很多图片在内存中占用很大空间,数据读取速度也会很慢。
fast R-CNN的改进是,对于每个mini-batch而言,从少量(2张)的图片中,每张图片取较多(128个)ROI作为训练集。实验证明这会令训练过程大幅提速(64倍速)。作者提到了一个担忧,因为一个mini-batch中的ROI大多来自同一张图,训练数据之间互相相关,可能会令模型更难以收敛,但是在实验中并没有这种情况发生。
据作者说,除了能够共享存储空间,这种策略还有“共享计算”的效果,没看懂体现在哪里。
在采样时,25%的样本取ROI和Ground Truth有至少50%的重叠面积者,这些ROI作为具有类别()的正样本;另外的样本取重叠面积在10%~50%之间的,这些ROI作为负样本(背景,)。至于重叠面积在10%以下的,则不采用(原文的表达很奇怪,我并没有理解,他说这些数据被当作hard example mining的启发?什么意思嘛?)。
训练时应用了数据增强:每个ROI有50%的概率被水平翻转并作为新数据输入。
Multi-task LOSS
fast R-CNN网络有两个输出。一个是长度为K+1的向量,表示该ROI对于K个类别的置信度(在softmax函数下的);另一个是边界框位置参数,对于每个类别K(不包括背景),分别预测。其定义为:
其中G代表Bounding Box的Ground Truth,P代表当前ROI。
对于训练数据中的每个ROI而言,它都带有Ground Truth:类别和边框回归变换。Multi-task Loss定义为:
。其中,为正确的分类对应的的交叉熵损失函数;而为边框回归预测的损失函数,其定义如下:
这里的函数也是计算损失时常用的函数了(能够有效应对梯度爆炸问题),定义为:
这里的边框损失函数是只对正确的类别而言的,忽略对其他类别预测的边框。另外,在类别为背景时,忽略边框损失函数。超参数用于调节两个损失之间的权重分配,不过在论文作者的训练中,边框回归中的数据都经过了normalization,而一直取1。
在ROI Pooling层的反向传播
BP沿着ROI Pooling层传递微分的算法。原文中这段有些晦涩,但实际上就是:ROI Pooling层执行的是最大池化,在每个池化窗格中,选择了哪个(上一层输出的特征图上的)像素,池化层输出到该像素的微分就是1,否则是0。
不过比较牛(?)的一点是,这里的反向传播不是按照逐个训练数据累加的,而是同一张图片一起累加的,因为有很多ROI都是在一张图像的Feature Map上的,这张特征图上的某个像素有可能在不同的ROI池化中被选择多次,那么,它被选择了多少次(假设是次),它的微分就是。也许这个操作对应的就是前面说的“共享计算”?
超参数选择
分类和边框回归全连接层的权重初始值分别被设置为标准差0.01和0.001的零均值高斯分布。Bias都初始化为0。每层的参数的学习率是1,bias的学习率是2,全局的学习率为0.001(在VOC07或VOC12上训练时,在30K个mini-batch之后,将学习率减至0.0001,再训练10K个mini-batch)。Momentum参数(按上次下降的梯度修改这次下降的梯度)为0.9,weight decay(权重和bias的正则化参数)为0.0005。
尺寸无关性
目的是使网络能够处理任意尺寸比例的ROI。作者试了两种方法。一种是直接将输入ROI池化为固定尺寸,这时网络需要主动学习尺寸无关的特征权重;另一种是以空间金字塔池化将ROI池化为若干固定尺寸,不过在训练过程中,空间金字塔池化的输出只取了随机的某个尺寸的输出。
检测
对于输入(一张图,2000个ROI)中的每个ROI,输出每个类别的softmax置信度,和对于每个类别的Bounding Box Regression。每个ROI保留置信度最大的类别和对应的Bounding Box。然后,对于每个类别而言,进行非最大值抑制,以移除重叠过多的ROI。
Truncated SVD
采用了truncated SVD方法(看上去和主成分提取很像?)压缩每个网络参数,据作者称,在前向传播中全连接层上的运算占用的时间几乎是整个前向传播时间的一半,而应用了truncated SVD方法后,能够大幅减少全连接层上的运算占用的时间。
其操作如下:对于一个全连接层的原始权重矩阵,用奇异值分解(svd)方法得到其奇异值和变换矩阵:
保留其前个奇异值。在还原时:
和取前列,取前个奇异值组成的对角阵。
在实际网络结构中,每个全连接层被分为了两个中间不插入非线性变换的全连接层,第一层权重为,第二层权重为。
其它
Fintune 从哪层开始?
在以往较小的特征提取网络支持下,Finetune只对全连接层进行就好,但实验表明,对于更深的特征提取网络,只Finetune全连接层将不会得到较高的mAP。然而Finetune所有卷积层也是没必要的,因为靠前的一些卷积层对于任何任务基本上都是通用的,Finetune它们带来的模型上的提升远不值得花费的时间。所以从中间的某一层开始Finetune是个较好的选择(作者选择从VGG16的conv3_1开始)。
Multi-task Loss有没有帮助?
首先,采用Multi-task Loss能够让训练过程简化,这是采用它的一个理由。此外,Multi-task Loss也有潜力能够提升模型效果(因为分类和边框回归共用相同的特征)。实验证明,在应用Muti-task Loss下,模型mAP有所提高。
用不用金字塔池化?
实验证明还是直接缩放特征图片在时间和准确率的取舍上表现得更好。所以,深度卷积网络有着学习尺寸无关的特征的能力。
更多训练数据有用吗?
有用,mAP能够提高。相应地,需要更多的训练迭代次数。
one-vs-all SVM和one-hot softmax哪个好?
基本一样,非要说的话softmax的表现好了那么一点点。
更多区域建议更好吗?
并非,区域建议过多可能还会导致mAP下降。这应该是因为新增的区域建议的selective search评分都比原来的更低(内容更不是个东西)?