论文地址:Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks
Github:https://github.com/rbgirshick/py-faster-rcnn
1、文章概述
Faster r-cnn是2016年提出的文章,有两个模型,一个是ZF模型,一个是VGG模型。在VOC07+12数据集中,ZF模型的mAP值达到59.9%,17fps; VGG模型的mAP值达到73.2%,5fps。
Faster r-cnn可以two-stage的代表,可以看做是RPN网络+Fast r-cnn的结合。Region proposal 阶段由RPN网络完成,创新性地提出了“Anchor”的思路用以解决多Scale、aspect ratio图像目标的输入问题。RPN网络提取ROI区域后,送入检测网络(比如Fast rcnn)再进行分类和回归。在训练阶段提出了“four -step”来交替训练RPN网络和detect网络,使两个网络共享卷积层(即基础网络的卷积层部分)。
具体的整个Faster R-CNN的结构图如下面两张图,都是描述Faster R-CNN结构的:
(图来自知乎:https://zhuanlan.zhihu.com/p/36184131)
(图来自博客:https://blog.csdn.net/gbyy42299/article/details/80352418)
2、RPN网络
2.1 RPN网络的提出原因
Rcnn系列是典型的“two-stage”,第一个stage就是region proposal。SPPnet和Fast r-cnn在region proposal阶段的时间太长,导致region proposal阶段的耗时成了two-stage方法的瓶颈。SPPnet和Fast r-cnn的region proposal阶段均没有利用卷积神经网络来完成region proposal,因此效果差耗时长成了必然。 Faster r-cnn的RPN网络(卷积神经网络)用来完成region proposal提取合适的ROI区域,且RPN网络能和整个检测网络共享卷积层,使得region proposal阶段在GPU上完成,且几乎不花费时间。
2.2 RPN网络的结构
下图是RPN网络的结构:
其中RPN和后面的检测网络(比如RCNN)将要共享的卷积层就是基础网络(ZF/VGG)中的卷积层,这个所谓的“共享”在后面训练过程中体现。
2.3 PRN的流程
RPN网络在最后卷积得到的特征图上(即基础网络的最后一层)进行扫描,RPN每次与特征图上的3*3窗口连接,然后映射到一个低维向量(256d for ZF/512d for VGG),这个操作是在RPN网络的第一个3*3的卷积层上完成的。(具体如何映射的我没有看源码,具体过程我也不清楚,看了网上的讲解这一部分也没有详细说明,请知道的大佬赐教!)256和512是由ZF的最后一层卷积层的40*60的卷积特征图数目为256和VGG的最后一层卷积层的特征图数目决定的,这一点可以参考下图的RPN结构。
在RPN网络的每次3*3卷积滑窗的中心处产生9个anchor,用来生成RPN其网络的训练所需要的anchor样本。实际上anchor在40*60的卷积特征图上的每一个单元点上都生成。将低维向量送入两个1*1的卷积层(一个是bbox的回归层reg),一个是bbox的分类层(cls)。如果RPN网络作用的卷积层的特征图大小是40*60,则reg层最后得到40*60*(9*4)个坐标,cls层最后得到40*60*(9*2)个分类得分。这个数据不明白的可以参考博客中最后给出的参考博客。具体的RPN流程可以参考下图(来自博客:https://blog.csdn.net/qq_17448289/article/details/52871461):
需要注意的是,上面提到的cls层和reg层后面,还要连接RPN网络相对应的损失函数层(就是文中浓墨重彩介绍的损失函数),而RPN网络提取到region proposal再送入到后面的检测网络(代码里是R-CNN网络)训练时,损失函数是对应的检测网络的损失函数。也就是说,全程训练时,有两个不同的损失函数指导整个Faster R-CNN网络的训练。具体网络结构可阅读作者提供的Caffe代码里的train.prototxt:Caffe代码里的对应的train.prototxt
3、Anchors
anchors被翻译成了“锚点”,后面的SSD的default boxes的思想应该是借鉴了anchor的思想。区别在于:Faster R-CNN的anchors仅在60*40的那一层的feature maps上提取,特征图的尺度单一;而SSD的default boxes在多个卷积层的feature maps上提取,且default boxes的scale和aspect ratio随着卷积层层数的不同而不同,也可以看成是特征金字塔的一种形式。
3.1 Anchors的生成
Anchors是为了训练RPN网络提供样本的。说是在RPN网络的每个3*3的窗口中心生成一系列anchors,实际上60*40的卷积特征图上每个点都生成了一系列的anchors。文中anchors默认有9个不同的形态:三种面积{128*128,256*256,512*512} * 三种长宽比例{1:1, 1:2, 2:1}。注意这里的面积是对应到“短边resize到600的重新缩放的原始图像”。这一步在60*40的feature maps上会生成60*40*9=21600,大约2W个anchors。附一张每个博客都会提到的描述anchors的图:
上图的这些类似火龙果的籽的点就是生成anchors的中心,一种颜色的框对应一个生成anchor的中心,上图三种颜色的框对应的三个不同的生成anchors的中心。
3.2 anchors的正负类别标定
既然用Anchors训练RPN,生成了2W多个anchors肯定有正类、负类之分,具体的正、负类别标定方法是:
Positive Labels:
(1)Anchors与GT(Ground Truth)有最高IOU重叠的anchors标为正类(也许IOU不到0.7);
(2)与任意GT的IOU大于0.7的anchors均可标为正类;
Negative Labels:
(1)与所有GT的IOU均小于0.3的anchors标为负类;
注意:对于既不是正类也不是负类的anchors,以及跨越图像边界的anchors(cross - boundary anchors)均舍弃,对训练目标不起作用。经过去掉“跨越图像边界的anchors”这一操作后,anchors的数目由2W变为了6000(对于一副feature map)。
3.3 Anchors训练选择
得到上面6000个正负类别标签的anchors后,要将anchors再进行挑选用来训练RPN。为了减少计算量,从上面3.2中提到的6000个anchors中随机挑选256个anchors,作为一个mini-batch的计算量,且256个anchors中,正负样例的比例为1:1.如果一个mini-batch中正例太少,则由负例填充,凑足256个anchors作为更新一次RPN网络权重的mini-batch。
3.4 生成的ROI区域的过滤
RPN网络训练好后,由RPN网络生成的ROI送入后面的检测网络(Faster R-CNN代码中是RCNN网络)。但是生成的region proposals中有很多是与周围的ROI高度重叠的。解决方法是用NMS(非极大值抑制),根据cls的scores。NMS中的IOU的阈值设置为0.7,NMS后大约剩下2000个ROIs。之后,再在这2000个ROIs中选取前N个ROIS(根据得分取前N个)用于检测网络。
注意:刚读论文的时候要区分anchors和RPN生成的ROIs。anchors仅用来训练RPN网络,训练好的RPN网络根据原图生成对应的ROIs送入检测网络。
3.5 ROI pooling
RPN网络生成的ROI区域和之前的feature maps一起作用完成ROI pooling过程,说简单点,就是根据ROI将feature maps中的对应区域抠出来,再resize到相应的输出尺寸,以下面的例子为例:
为简洁起见,我们先将 8×8 特征图转换为预定义的 2×2 大小。
- 下图左上角:特征图。
- 右上角:将 ROI(蓝色区域)与特征图重叠。
- 左下角:将 ROI 拆分为目标维度。例如,对于 2×2 目标,我们将 ROI 分割为 4 个大小相似或相等的部分。
- 右下角:找到每个部分的最大值,得到变换后的特征图。
输入特征图(左上),输出特征图(右下),ROI (右上,蓝色框)。
按上述步骤得到一个 2×2 的特征图块,可以馈送至分类器和边界框回归器中。
图摘自知乎:https://zhuanlan.zhihu.com/p/36184131
注意:每个anchor经过回归后对应到原图,然后再对应到feature map经过roi pooling后输出7*7的大小的map;anchors要对应到feature map上。
3.6 三种尺度
(1)原图尺度:原始输入图像大小,不受限制,不影响性能。即制作好的VOC格式的数据集的训练图像大小;
(2)归一化尺度:就是文中提到的“短边resize到600”,在上面原图的基础上好像resize到了1000*600,。anchors就是根据这个尺度确定的最终大小三种面积{128*128,256*256,512*512},后面生成的ROIs也是映射到的这个尺度上;
(3)网络输入尺度:输入进基础网络的尺度,代码中是224*224。应该也是由原图尺度resize得到的。
注意:anchor映射的尺度是归一化尺度1000*600,而不是网络输入尺度224*224,可以参照文中Tabel 1中的数据。
4、Faster R-CNN的损失函数
损失函数部分见博客:https://blog.csdn.net/qq_17448289/article/details/52871461)
介绍了Fast rcnn的多任务损失函数和Fast rcnn的损失函数。
参数解释:
5、训练整个网络(RPN网络+检测网络)
参见figure2可知,RPN和检测网络结构上前面都共有一个基础网络,因此RPN和检测网络训练时应共享基础网络卷积参数层,用交替训练(alternating training),达到卷积层特征共享。文中作者提出了“四步”训练法,具体地:
(1)训练RPN,RPN网络由ImageNet预训练的模型初始化;
(2)利用RPN生成ROIs,训练检测网络。检测网络(R-CNN)同样也由ImageNet预训练的模型初始化,此时RPN和RCNN还没有共享卷积层;这一步是对检测网络层的参数微调;
(3)用RCNN初始化RPN,初始化RCNN和RPN共享的卷积层的参数,微调不共享的和其他层的参数(即微调RPN独有的层),到这一步RPN和RCNN共享参数了;
(4)训练R-CNN,保持其与RPN共享的卷积层参数不变,微调不共享层(即R-CNN层)的参数;
训练超参数设置和实验结果请参照原文。
参考文章:
这两篇是目标检测的综述,其中第一篇详细对比了R-CNN、Fast R-CNN、Faster R-CNN和R-FCN。
https://zhuanlan.zhihu.com/p/36184131
https://zhuanlan.zhihu.com/p/36088972
下面几篇是阅读文章时看的博客:
https://blog.csdn.net/qq_17448289/article/details/52871461
https://blog.csdn.net/hunterlew/article/details/71075925
https://blog.csdn.net/shenxiaolu1984/article/details/51152614
https://www.jianshu.com/p/656343761fd5
https://blog.csdn.net/sloanqin/article/details/51545125
https://blog.csdn.net/gbyy42299/article/details/80352418