Faster R-CNN细节详解

论文题目:Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks
论文地址:传送门

这学期刚开学的时候,重新读了遍R-CNN系列,但当时仍然是浅尝辄止,许多东西还不懂。这是当时写的R-CNN系列总结,基本就是照着论文翻译,但其实现细节也是很久之后才懂的。

最近在尝试旋转框的检测,需要将Faster R-CNN的Horizontal BBOX改为Oriented BBOX,这才发现自己对其细节理解的不够深刻,同时代码能力也不够。

经过半个月的摸索,虽然旋转框还没有跑起来,但代码能力似乎提高了不少,对检测流程、检测框架有了较多的了解。

重读Faster R-CNN,才发现作者的设计真的是非常的严谨。

Introduction

事实上,Fast R-CNN已经够快了,将R-CNN上通过crop对应Region的图像块,调整为crop对应Region的特征块,即从feature map上crop出对应特征,并剔除ROI Pooling,使得特征的输入更加平稳。

至此,只有Region Proposal的部分仍然使用传统的方法,如Selective Search,耗费了大量的时间,且不符合NN的自动提取特征。因此作者就思考,能不能在feature map上提取region proposal?

为此,Faster R-CNN最突出的贡献就是提出了RPN(Region Proposal Network),而RPN也成为了Det中奠基石的一部分。

而在Faster R-CNN的实现当中,如果实现了RPN,其实就实现了其80%。

Region Proposal Networks

RPN对于任意尺寸的输入图像,可以输出其矩形的Region Proposals,每个Proposal都有一个score。其示意图如图一所示。

RPN是一个全卷积网络,其输入是某一尺寸为$H \times W \times N$的特征图,输出是$H \times W \times 2k$的scores和$H \times W \times 4k$的坐标。

具体来说,我们将$H \times W \times N$的特征图,通过一次卷积得到$H \times W \times N_1$的特征图($N_1$可以是256、512等),然后再分别送入两个分支网络当中,其中的分类(cls)分支得到$H \times W \times 2k$的特征图,回归分支得到$H \times W \times 4k$的特征图。其中$k$是特征图上每个点的anchor数量,本文设置为$k=9$。

Translation-Invariant Anchors

那么anchor是什么东西呢?其中文意思是锚点,(个人理解)在Det中一般指的是在某个位置上设置的“锚”,也就是预设的目标。如上图中$k$个anchor具有不用的尺寸和长宽比。

这里是怎样实现Translation-Invariant呢?其实就是在每个点设置$k$个anchors,从而可以得到$k$个Region Proposals(RP),且这$k$个RP相对于anchors是参数化的,也就是其$(x,y,h,w)$是相对于anchor的$(x,y,h,w)$的。

具体来说,本文选取$k=9$,其中包括3个scale、3个ratio,$scales=128,256,512$,$ratios=2:1,1:1,1:2$。两者组合起来即有9种anchors。
这样的话,对于$H \times W$的特征图,将会有$H \times W \times 9$个anchors。

Loss Function for Learning Region Proposals

为了更清晰的说明,贴上具体实现过程中,Faster R-CNN的示意图,图片来自这里

由于RPN只需要判断objectness,而不需要判断类别,因此在训练RPN时,只需要gt_boxes,而不需要gt_labels。

首先我们根据特征图的大小$H \times W$,可以预设$H \times W \times k$个anchors,每个anchor都可以表示为$(x_a,y_a,w_a,h_a)$,其中$x_a,y_a$为其中心点坐标。那么这些anchors当中有许多都是没有gt_boxes与其对应的,这样的anchors在后面的box回归当中也很难收敛,因此我们需要从这些anchors当中选取一些与gt_boxes重叠较大的anchors。Positive anchors的选择原则:

  1. 和gt_boxes有最大重叠的anchors
  2. 和任一gt_boxes重叠超过0.7的anchors

因此一个gt_boxes可能有多个anchors与其对应,负责其box回归。那么negative anchors被定义为IOU小于0.3的anchors,其他的anchors则被忽略。

其Loss Function定义如下:

其中$i$是一个mini_batch中anchor的索引,$p_i$是anchor $i$的objectness预测值,$p_i^*$是对应的gt,$p_i^*=1$时为positive,$p_i^*=0$时为negative。其中$L_{cls}$为log loss。

$t_i$为预测的box的参数化表示,相应的$t_i^*$为gt。$L_{reg}(t_i,t_i^*)=R(t_i-t_i^*)$。其中$L_{reg}$为Smooth L1 Loss。

$p_i^*L_{reg}$表示只对positive anchor进行回归,忽略negative。

我们前面所说的参数化表示,如下式所定义:

其中$x,x_a,x^*$分别为预测值、anchor、gt_boxes。

到这里文章所要表达的内容似乎清晰多了。检测的主要任务是cls和reg,而reg需要预测物体的坐标,但直接让一个网络预测坐标是比较困难的。
因此作者设计了anchor这个东西,即在每个位置都预设一些“锚点”,我们不直接预测坐标,而是预测gt_boxes与anchors之间的偏移量。
同时由于物体的大小、长宽比各不相同,因此在每个位置设置多个不同scale,不同ratio的anchor,每种anchor负责相近尺寸目标的回归。

当网络学习到这种偏移量规则后,我们再将偏移量转为coordinates,从而实现box预测。

当然,由于每个位置有$k$个anchor,且是人为设计的,因此后面有许多工作对此进行改进,甚至是取消anchor这个机制,如FSAF、FCOS等。

Optimization

经过anchor的选取后,我们有许多positives和negatives,我们可以直接对其进行训练,然而由于negatives的数量远超过positives,从而会导致class imbalance的问题。因此在RPN中会有一个样本选择的过程,即我们共选取大约256个样本,其中正样本128个,负样本128个。如果正样本$s_{pos}<128$,则仅选取$s_{pos}$个正样本,那么负样本即选取$256-s_{pos}$个;若正样本$s_{pos}>128$,则随机选取128个样本,负样本也是同样的规则。

Sharing Convolutional Feaetures for Region Proposal and Object Detection

即RPN和Fast R-CNN共享同一个backbone的feature map,然后两者依次交叉训练,但后来实验表明,直接对两者联合训练的效果也非常好。

当RPN与Fast R-CNN结合时,其作用是为Fast R-CNN提供Region Proposals,也就是取代了Selective Search的作用。因此其输出有3个:cls_loss,reg_loss,region proposals。

由于这些region proposals有很大的重叠,会造成冗余,因此我们根据其cls_score进行NMS(threshold=0.7),选取大约2000k region proposals。然后我们再选出top-N个regions用于检测。

Experiments

Ignored

Conclusion

在CV如此快速发展的今天,Faster R-CNN从15年提出,到现在19年底依然是非常流行的检测框架,足以见其重要性,接下来我们重新实现下Faster R-CNN,同时形成自己的一套代码风格。