先回归一下: ​​R-CNN​​​, ​​SPP-net​

Fast R-CNN_损失函数

Fast R-CNN_损失函数_02

​R-CNN​​​和​​SPP-net​​​在训练时​​pipeline​​​是隔离的:提取​​proposal​​​,​​CNN​​​提取特征,​​SVM​​​分类,​​bbox regression​​。

​Fast R-CNN​​ 两大主要贡献点 :

  1. 实现大部分​​end-to-end​​训练(提​​proposal​​阶段除外): 所有的特征都暂存在显存中,就不需要额外的磁盘空间。
    ​joint training​​(​​SVM​​分类,​​bbox​​回归联合起来在​​CNN​​阶段训练)把最后一层的​​Softmax​​换成两个,一个是对区域的分类​​Softmax​​(包括背景),另一个是对​​bounding box​​的微调。这个网络有两个输入,一个是整张图片,另一个是候选​​proposals​​算法产生的可能​​proposals​​的坐标。(对于​​SVM​​和​​Softmax​​,论文在​​SVM​​和​​Softmax​​的对比实验中说明,​​SVM​​的优势并不明显,故直接用​​Softmax​​将整个网络整合训练更好。对于联合训练: 同时利用了分类的监督信息和回归的监督信息,使得网络训练的更加鲁棒,效果更好。这两种信息是可以有效联合的。)
  2. 提出了一个​​RoI​​层,算是​​SPP​​的变种,​​SPP​​是​​pooling​​成多个固定尺度,​​RoI​​只​​pooling​​到单个固定的尺度 (论文通过实验得到的结论是多尺度学习能提高一点点​​mAP​​,不过计算量成倍的增加,故单尺度训练的效果更好。)

Fast R-CNN_损失函数_03

其它贡献点:

  • 指出​​SPP-net​​​训练时的不足之处,并提出新的训练方式,就是把同张图片的​​prososals​​​作为一批进行学习,而​​proposals​​​的坐标直接映射到​​conv5​​​层上,这样相当于一个​​batch​​​一张图片的所以训练样本只卷积了一次。文章提出他们通过这样的训练方式或许存在不收敛的情况,不过实验发现,这种情况并没有发生。这样加快了训练速度。 (实际训练时,一个​​batch​​​训练两张图片,每张图片训练64个​​RoIs(Region of Interest​​))

注意点:

  • 论文在回归问题上并没有用很常见的2范数作为回归,而是使用所谓的鲁棒L1范数作为损失函数。
  • 论文将比较大的全链接层用​​SVD​​分解了一下使得检测的时候更加迅速。虽然是别人的工作,但是引过来恰到好处(矩阵相关的知识是不是可以在检测中发挥更大的作用呢?)。

ROI Pooling

与​​SPP​​​的目的相同:如何把不同尺寸的​​ROI​​​映射为固定大小的特征。​​ROI​​​就是特殊的​​SPP​​,只不过它没有考虑多个空间尺度,只用单个尺度(下图只是大致示意图)。

Fast R-CNN_损失函数_04

​ROI Pooling​​​的具体实现可以看做是针对​​ROI​​​区域的普通整个图像​​feature map​​​的​​Pooling​​​,只不过因为不是固定尺寸的输入,因此每次的​​pooling​​​网格大小得手动计算,比如某个​​ROI​​​区域坐标为 ( x 1 , y 1 , x 2 , y 2 ) (x_1,y_1,x_2,y_2) (x1​,y1​,x2​,y2​),那么输入​​size​​​为 ( y 2 − y 1 ) ⋅ ( x 2 − x 1 ) (y_2-y_1)\cdot(x_2-x_1) (y2​−y1​)⋅(x2​−x1​),如果​​pooling​​​的输出​​size​​​为 p o o l e d h e i g h t ⋅ p o o l e d w i d t h pooledheight\cdot pooledwidth pooledheight⋅pooledwidth那么每个网格的​​​size​​为 ( ( y 2 − y 1 ) / p o o l e d h e i g h t ⋅ ( x 2 − x 1 ) / p o o l e d w i d t h ) ((y_2-y_1)/pooledheight\cdot (x_2-x_1)/pooledwidth) ((y2​−y1​)/pooledheight⋅(x2​−x1​)/pooledwidth)。

Bounding-box Regression

有了​​ROI Pooling​​​层其实就可以完成最简单粗暴的深度对象检测了,也就是先用​​selective search​​​等​​proposal​​​提取算法得到一批​​box​​​坐标,然后输入网络对每个​​box​​包含一个对象进行预测,此时,神经网络依然仅仅是一个图片分类的工具而已,只不过不是整图分类,而是ROI区域的分类,显然大家不会就此满足,那么,能不能把输入的​​box​​​坐标也放到深度神经网络里然后进行一些优化呢?​​rbg​​​大神于是又说了"yes"。在​​Fast-RCNN​​​中,有两个输出层:第一个是针对每个​​ROI​​​区域的分类概率预测 p = ( p 0 , p 1 , ⋅ ⋅ ⋅ , p K ) p=(p_0,p_1,\cdot \cdot \cdot ,p_K ) p=(p0​,p1​,⋅⋅⋅,pK​),第二个则是针对每个​​ROI​​区域坐标的偏移优化 t k = ( t x k , t y k , t w k , t h k ) , 0 ≤ k ≤ K t^k=(t_x^k,t_y^k,t_w^k,t_h^k),0\leq k \leq K tk=(txk​,tyk​,twk​,thk​),0≤k≤K 是多类检测的类别序号。这里我们着重介绍第二部分,即坐标偏移优化。

假设对于类别 k ∗ k^* k∗,在图片中标注了一个​​groundtruth​​坐标: t ∗ = ( t x ∗ , t y ∗ , t w ∗ , t h ∗ ) t^*=(t_x^*,t_y^*,t_w^*,t_h^*) t∗=(tx∗​,ty∗​,tw∗​,th∗​),而预测值为 t = ( t x , t y , t w , t h ) t=(t_x,t_y,t_w,t_h) t=(tx​,ty​,tw​,th​)

,二者理论上越接近越好,这里定义损失函数:

Fast R-CNN_数据_05

这里, s m o o t h L 1 ( x ) smooth_{L_1}(x) smoothL1(x) 中的x即为 t i − t i ∗ t_i - t_i^* ti−ti∗

t i − t i ∗ t_i - t_i^* ti​−ti∗​ 即对应坐标的差距。该函数在 (−1,1) 之间为二次函数,而其他区域为线性函数,作者表示这种形式可以增强模型对异常数据的鲁棒性,整个函数在​​matplotlib​​中画出来是这样的

Fast R-CNN_直接映射_06

对应的代码在​​smooth_L1_loss_layer.cu​​中。

参考: