3. Faster R-CNN
Faster R-CNN 取代selective search,直接通过一个Region Proposal Network (RPN)生成待检测区域,这么做,在生成RoI区域的时候,时间也就从2s缩减到了10ms。下图是Faster R-CNN整体结构。

由上图可知,Faster R-CNN由共享卷积层、RPN、RoI pooling以及分类和回归四部分组成:
首先使用共享卷积层为全图提取特征feature maps
将得到的feature maps送入RPN,RPN生成待检测框(指定RoI的位置),并对RoI的包围框进行第一次修正
RoI Pooling Layer根据RPN的输出在feature map上面选取每个RoI对应的特征,并将维度置为定值
使用全连接层(FC Layer)对框进行分类,并且进行目标包围框的第二次修正。 尤其注意的是,Faster R-CNN真正实现了端到端的训练(end-to-end training)。Faster R-CNN最大特色是使用了RPN取代了SS算法来获取RoI,以下对RPN进行分析。
3.1 RPN
经典的检测方法生成检测框都非常耗时,如OpenCV adaboost使用滑动窗口+图像金字塔生成检测框;或如R-CNN使用SS(Selective Search)方法生成检测框。而Faster R-CNN则抛弃了传统的滑动窗口和SS方法,直接使用RPN生成检测框,这也是Faster R-CNN的巨大优势,能极大提升检测框的生成速度。 首先来看看RPN的工作原理:

上图展示了RPN网络的具体结构。可以看到RPN网络实际分为2条支线,上面一条支线通过softmax来分类anchors获得前景foreground和背景background(检测目标是foreground),下面一条支线用于计算anchors的边框偏移量,以获得精确的proposals。而最后的proposal层则负责综合foreground anchors和偏移量获取proposals,同时剔除太小和超出边界的proposals。其实整个网络到了Proposal Layer这里,就完成了相当于目标定位的功能。anchor:简单地说,RPN依靠一个在共享特征图上滑动的窗口,为每个位置生成9种预先设置好长宽比与面积的目标框(即anchor)。这9种初始anchor包含三种面积(128×128,256×256,512×512),每种面积又包含三种长宽比(1:1,1:2,2:1)。示意图如下所示:

由于共享特征图的大小约为40×60,所以RPN生成的初始anchor的总数约为20000个(40×60×9)。其实RPN最终就是在原图尺度上,设置了密密麻麻的候选anchor。进而去判断anchor到底是前景还是背景,意思就是判断这个anchor到底有没有覆盖目标,以及为属于前景的anchor进行第一次坐标修正。

判断前景或背景:对于所有的anchors,首先需要判断anchor是是否为前景。对于第一个问题,RPN的做法是使用SoftmaxLoss直接训练,在训练的时候排除掉了超越图像边界的anchor;边框修正:如图绿色表示的是飞机的实际框标签(ground truth),红色的表示的其中一个候选区域(foreground anchor),即被分类器识别为飞机的区域,但是由于红色区域定位不准确,这张图相当于没有正确检测出飞机,所以我们希望采用一种方法对红色的框进行微调,使得候选区域和实际框更加接近:

对于目标框一般使用四维向量来表示(x,y,w,h)(x,y,w,h) ,分别表示目标框的中心点坐标、宽、高,我们使用AA 表示原始的foreground anchor,使用GG 表示目标的ground truth,我们的目标是寻找一种关系,使得输入原始的Anchor AA 经过映射到一个和真实框GG 更接近的回归窗口G′G′ ,即:
给定:

寻找一种变换F,使得


那么如何去计算F 呢?这里我们可以通过平移和缩放实现

平移:

缩放:

上面公式中,我们需要学习四个参数,分别是

其中

表示的两个框中心距离的偏移量
当输入的anchor A与G相差较小时,可以认为这种变换是一种线性变换, 那么就可以用线性回归来建模对目标框进行微调(注意,只有当anchors A和G比较接近时,才能使用线性回归模型,否则就是复杂的非线性问题了)。 接下来就是如何通过线性回归获得

线性回归就是给定输入的特征向量X ,学习一组参数W,使得线性回归的输出WX和真实值Y 的差很小。对于该问题,输入X是特征图,我们使用ϕ 表示,同时训练时还需要A到G变换的真实参数值:

输出是

那么目标函数可以表示为:

其中ϕ(A) 是对应anchor的特征图组成的特征向量,ww 是需要学习的参数,d(A) 是得到预测值(表示x,y,w,h,也就是每一个变换对应一个上述目标函数),为了让预测值和真实值差距最小,代价函数如下:

函数优化目标为:

需要说明,只有在G和A比较接近时,才可近似认为上述线性变换成立,下面对于原文中,A与G之间的平移参数和尺度因子为:

在得到每一个候选区域anchor A的修正参数之后,我们就可以计算出精确的anchor,然后按照物体的区域得分从大到小对得到的anchor排序,然后提出一些宽或者高很小的anchor(获取其它过滤条件),再经过非极大值抑制抑制,取前Top-N的anchors,然后作为proposals(候选框)输出,送入到RoI Pooling层。 那么,RPN怎么实现呢?这个问题通过RPN的本质很好求解,RPN的本质是一个树状结构,树干是一个3×3的卷积层,树枝是两个1×1的卷积层,第一个1×1的卷积层解决了前后景的输出,第二个1×1的卷积层解决了边框修正的输出。来看看在代码中是怎么做的:

从如上代码中可以看到,对于RPN输出的特征图中的每一个点,一个1×1的卷积层输出了18个值,因为是每一个点对应9个anchor,每个anchor有一个前景分数和一个背景分数,所以9×2=18。另一个1×1的卷积层输出了36个值,因为是每一个点对应9个anchor,每个anchor对应了4个修正坐标的值,所以9×4=36。那么,要得到这些值,RPN网络需要训练。在训练的时候,就需要对应的标签。那么,如何判定一个anchor是前景还是背景呢?文中做出了如下定义:如果一个anchor与ground truth的IoU在0.7以上,那这个anchor就算前景(positive)。类似地,如果这个anchor与ground truth的IoU在0.3以下,那么这个anchor就算背景(negative)。在作者进行RPN网络训练的时候,只使用了上述两类anchor,与ground truth的IoU介于0.3和0.7的anchor没有使用。在训练anchor属于前景与背景的时候,是在一张图中,随机抽取了128个前景anchor与128个背景anchor。

