【论文】Ross Girshick. Fast R-CNN. (pdf)
Why is Fast RCNN
RCNN 存在的问题:
- 训练分多阶段进行
(1)fine-tune ConvNet;(2)fit SVMs to CovNet features;(3)learn bbox regression - 训练耗时、占内存
从磁盘读出图片然后再对 object proposal 提取特征 - 测试时检测速度慢
测试时对每张图片的每个 object proposal 提取特征,每张图片提取 2k 个 object proposal
SPPnets 在 RCNN 的基础上添加了一些共享计算的方法(sharing compution)提高了 RCNN 的速度:
- SPPnets 对整张图像计算特征向量,然后根据这个特征向量为每个 object proposal 做分类
- 对特征图上对应 proposal 的位置使用最大池化降维得到的一个固定维度的小特征图
- 对不同大小的输出做空间金字塔在一起形成 proposal 对应的特征
但是,SPPnets 还是存在一些和 RCNN 一样的问题——分阶段寻训练、特征写回磁盘等等
相比较之下,Fast RCNN 有如下的有点:
- 检测率高
- 一步训练,多任务损失
- 训练更新整个网络
- 不使用磁盘存储特征
Fast RCNN architecture
其工作流程为:
- 对整张图片做卷积提取特征
- 每个 object proposal 经过 RoI 池化得到一个固定大小的特征向量
- 特征向量经过 softmax 预测 top-K 的得分,外加一个背景分类
- 对每一类做 bbox regression 产生 4 个精确定位值
RoI pooling layer
RoI pooling 将 RoI 在特征图上的有效的部分通过最大池化压缩为一个固定大小的小特征图(H×WH\times WH×W,e.g. 7×77\times77×7),H,WH,WH,W 作为超参数通过学习得到
每一个 RoI 对应特征图上一个矩形窗口,(r,c,h,w)(r,c,h,w)(r,c,h,w) 给出具体的位置,(r,c)(r,c)(r,c) 表示左上角的位置,(h,w)(h, w)(h,w) 表示宽高。RoI 降维的时候,根据大小为 (h/H,w/W)(h/H,w/W)(h/H,w/W) 的子窗口做最大池化
Fine-tuning for detection
Multi-task loss
softmax 分支输出 K+1K+1K+1 类的预测得分 p=(p0,?,pK)p=(p_0,\cdots,p_K)p=(p0?,?,pK?)(including background class)
bbbox regression 分支输出 tk=(txk,tyk,twk,thk)t^k=(t^k_x,t^k_y,t^k_w,t^k_h)tk=(txk?,tyk?,twk?,thk?),位置回归只对 KKK 个物体分类进行,background class 不计算位置回归
于是,多任务损失就可以写做 L(p,u,tu,v)=Lcls(p,u)+λ[u?1]Lloc(tu,v)L(p, u, t^u, v)=L_{cls}(p, u)+\lambda[u\geqslant1]L_loc(t^u,v)L(p,u,tu,v)=Lcls?(p,u)+λ[u?1]Ll?oc(tu,v) 其中,uuu 是 ground-truth class,tut^utu 是 bbox regression predictive tuple tu=(txu,tyu,twu,thu)t^u=(t^u_x,t^u_y,t^u_w,t^u_h)tu=(txu?,tyu?,twu?,thu?) ,vvv 是 ground-truth bbox regression target (vx,vy,vw,vh)(v_x,v_y,v_w,v_h)(vx?,vy?,vw?,vh?),[u?1][u\geqslant1][u?1] 为示性函数,u=0u=0u=0 表示背景分类不纳入回归计算,λ\lambdaλ 作为比例系数平衡分类和回归的贡献
Lloca(tu,v)L_{loca}(t^u,v)Lloca?(tu,v) 定义为 Lloca(tu,v)=∑i∈{x,y,w,h}smoothL1(tiu?v)L_{loca}(t^u,v)=\sum_{i\in\left\{x,y,w,h \right\}}smooth_{L_1}(t_i^u-v)Lloca?(tu,v)=i∈{ x,y,w,h}∑?smoothL1??(tiu??v) 其中 smoothL1(x)={0.5x2if∣x∣<1∣x∣?0.5otherwisesmooth_{L_1}(x)=\left\{\begin{matrix} 0.5x^2& if\ |x|<1 \\ |x|-0.5& otherwise \end{matrix}\right.smoothL1??(x)={ 0.5x2∣x∣?0.5?if ∣x∣<1otherwise?
Mini-batch
Fast RCNN 训练时随机梯度采用分层抽样的方法,即抽取 NNN 张图片,每张图片有 R/NR/NR/N 个 RoI,于是,一个 mini-batch 总共有 RRR 个样本
其中,75% 的 RoI 与 ground-truth box 的 IoU 大于 0.5,75% 的 IoU 在 [0.1,0.5)[0.1, 0.5)[0.1,0.5) 之间,属于背景分类
Back propagation through RoI pooling layers
记 xi∈Rx_i\in\mathbb Rxi?∈R 表示第 iii 个激活到 RoI poolig 的输入,yrjy_{rj}yrj? 表示第 rrr 个 RoI 在 第 jjj 层上的输出。RoI pooling 计算最大池化,yrj=xi?(r,j)y_{rj}=x_{i^*(r, j)}yrj?=xi?(r,j)?,i?(r,j)=argmaxi′∈R(r,j)xi′i^*(r, j)=\underset{i'\in\mathcal R(r,j)}{argmax}\ x_{i'}i?(r,j)=i′∈R(r,j)argmax? xi′?,R(r,j)\mathcal R(r,j)R(r,j) 表示 yrjy_{rj}yrj? max pooling 对应的子窗口
于是, RoI pooling layer 的反向传播就可以定义为下面的形式 ?L?xi=∑r∑j[i=i?(r,j)]?L?yrj\frac{\partial L}{\partial x_i}=\sum_r\sum_j[i=i^*(r, j)]\frac{\partial L}{\partial y_{rj}}?xi??L?=r∑?j∑?[i=i?(r,j)]?yrj??L?
这个公式很好理解,还记得 max pooling 的反向传播吗?max pooling 的反向传播可以简单理解为将梯度只沿最大的数回传,其实 RoI pooling 也是这样
通过上面图也很好理解,一个 xix_ixi? 可能对应几个不同的 yrjy_{rj}yrj?,因为 RoI 之间存在重叠情况
truncated SVD for faster detection
如果是一个普通的分类网络,那么全连接层的计算应该远不及卷积层的计算。但是,针对物体检测任务,Fast RCNN 在 ROoI pooling 后得到的每个region proposal 都要经过几个全连接层,这使得全连接层的计算占网络的计算将近一半,如下图,所以作者采用 SVD 分解来简化全连接层的计算
一层的权重矩阵 WWW 的大小为 u×vu\times vu×v,可以通过下面公式近似计算 W≈U∑tVTW\approx U\sum_tV^TW≈Ut∑?VT 其中,UUU 是一个 u×tu\times tu×t 的矩阵包含 WWW 的 first ttt left-singular vectors,∑t\sum_t∑t? 是一个 t×tt\times tt×t 的对对角矩阵,包含 WWW 的 top signular value, VVV 是一个 v×tv\times tv×t 的矩阵包含 WWW 的 first ttt right-singular vectors
于是,通过 SVD 分解,参数量从 uvuvuv 降到了 t(u+v)t(u+v)t(u+v),如果 t?min(u,v)t \ll min(u,v)t?min(u,v) 这样做是非常有意义的
Why Fast RCNN works
为什么 Fast RCNN 的检测率更高?
Fast RCNN 对整张图像做卷积提取特征,然后再是在特征图上框出 RoI,这样前向传播有一个更大的感受野,也能更加有效地更新整个网络的参数,这也就是作者说的 feature sharing during training
之前的 RCNN 和 SPPnets 并不是这样做的,它们从不同的图像中取得 RoI 放入网络进行训练。但是,事实上每一个 RoI 都有可能有一个很大的感受野,这个感受野可能覆盖整张图片。于是,这就导致了模型在反向传播时更新效率很低
为什么 Fast RCNN 的检测速度更快?
每个 RoI 是从已经卷积好的特征图上抽取得到,然后经过 RoI polling 和一些全连接就可以进行分类和回归,同时卷积层使用 SVD 分解也在一定程度上加快了全连接层的计算
下面是 Fast RCNN 的训练过程和测试过程