Faster R-CNN学习笔记

论文大部分转载自:https://blog.csdn.net/WZZ18191171661/article/details/79439212


论文题目Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks 

论文链接论文链接

论文代码:Matlab版本点击此处,Python版本点击此处


作为一个目标检测领域的baseline算法,Faster-rcnn值得去仔细理解里面的细节

按照总分总的顺序剖析。

                                                                   图1 Faster-rcnn架构图(理解版)


图2 Faster-rcnn架构图(精简版)


图3 Faster-rcnn架构图(细节版)

一、目标检测的总体框架


图4 目标检测框架图

观察图4,你可以发现目标检测的框架中包含4个关键模块,包括region proposal(生成ROI)、feature extraction(特征提取网络)、classification(ROI分类)、regression(ROI回归)。而faster-rcnn利用一个神经网络将这4个模块结合起来,训练了一个端到端的网络。通过观察图1、图2、图3,我们可以得到如下的结论:Faster-rcnn主要包括4个关键模块,特征提取网络、生成ROI、ROI分类、ROI回归

1. 特征提取网络:它用来从大量的图片中提取出一些不同目标的重要特征,通常由conv+relu+pool层构成,常用一些预训练好的网络(VGG、Inception、Resnet等),获得的结果叫做特征图feature map;

2. 生成ROI(RPN):在获得的特征图的每一个点上(一共的点数时feature map的大小)做多个候选ROI(这里是9),然后利用分类器将这些ROI区分为背景和前景,同时利用回归器对这些ROI的位置进行初步的调整;

3. ROI分类:在RPN阶段,用来区分前景(于真实目标重叠并且其重叠区域大于0.5)和背景(不与任何目标重叠或者其重叠区域小于0.1);在Fast-rcnn阶段,用于区分不同种类的目标(猫、狗、人等);

4. ROI回归:在RPN阶段,进行初步调整;在Fast-rcnn阶段进行精确调整;

总之,其整体流程如下所示

  • 首先对输入的图片进行裁剪操作,并将裁剪后的图片送入预训练好的分类网络中获取该图像对应的特征图;
  • 然后在特征图上的每一个锚点上取9个候选的ROI(3个不同尺度,3个不同长宽比),并根据相应的比例将其映射到原始图像中(因为特征提取网络一般有conv和pool组成,但是只有pool会改变特征图的大小,因此最终的特征图大小和pool的个数相关);
  • 接着将这些候选的ROI输入到RPN网络中,RPN网络对这些ROI进行分类(即确定这些ROI是前景还是背景)同时对其进行初步回归(即计算这些前景ROI与真实目标之间的BB的偏差值,包括Δx、Δy、Δw、Δh),然后做NMS(非极大值抑制,即根据分类的得分对这些ROI进行排序,然后选择其中的前N个ROI);
  • 接着对这些不同大小的ROI进行ROI Pooling操作(即将其映射为特定大小的feature_map,文中是7x7),输出固定大小的feature_map
  • 最后将其输入简单的检测网络中,然后利用1x1的卷积进行分类(区分不同的类别,N+1类,多余的一类是背景,用于删除不准确的ROI),同时进行BB回归(精确的调整预测的ROI和GT的ROI之间的偏差值),从而输出一个BB集合。 

二、Faster-rcnn中的核心问题

1. 提出了“RPN”网络,在提高精度的同时提高了速度;

2. RPN网络和Fast-rcnn网络的特征共享与训练;

3. 使用了ROI Pooling技术 ;

4. 使用了NMS技术;


三、细节详解

0.Conv layers


缩进Conv layers包含了conv,pooling,relu三种层。以python版本中的VGG16模型中的faster_rcnn_test.pt的网络结构为例,如图2,Conv layers部分共有13个conv层,13个relu层,4个pooling层。这里有一个非常容易被忽略但是又无比重要的信息,在Conv layers中:

  1. 所有的conv层都是:kernel_size=3,pad=1
  2. 所有的pooling层都是:kernel_size=2,stride=2
为何重要?在Faster RCNN Conv layers中对所有的卷积都做了扩边处理(pad=1,即填充一圈0),导致原图变为(M+2)x(N+2)大小,再做3x3卷积后输出MxN。正是这种设置,导致Conv layers中的conv层不改变输入和输出矩阵大小。如图3:


图3

类似的是,Conv layers中的pooling层kernel_size=2,stride=2。这样每个经过pooling层的MxN矩阵,都会变为(M/2)*(N/2)大小。综上所述,在整个Conv layers中,conv和relu层不改变输入输出大小,只有pooling层使输出长宽都变为输入的1/2。

缩进那么,一个MxN大小的矩阵经过Conv layers固定变为(M/16)x(N/16)!这样Conv layers生成的featuure map中都可以和原图对应起来。

1. 锚点

即特征图上的最小单位点,比如原始图像的大小是256x256,特征提取网络中含有4个pool层,然后最终获得的特征图的大小为 256/16 x 256/16,即获得一个16x16的特征图,该图中的最小单位即是锚点,由于特征图和原始图像之间存在比例关系,在特征图上面密集的点对应到原始图像上面是有16个像素的间隔,如下图所示:


图5 原始图像中对应的锚点

2. 候选的ROI

针对每一个锚点,然后根据不同的尺度(128、256、512pixel)和不同的长宽比(1:1、0.5:1、1:0.5)产生9个BB,如下图所示,对于16x16的特征图,最终产生16x16x9个候选的ROI。


图6 左侧:锚点、中心:特征图空间单一锚点在原图中的表达,右侧:所有锚点在原图中的表达


3. RPN网络 -- 用来对特征图上面产生的多个ROI进行区分和初步定位


图7 RPN映射过程

RPN(如图3所示) 是用完全卷积的方式高效实现的,用基础网络返回的卷积特征图作为输入。首先,我们使用一个有 512个通道和 3x3 卷积核大小的卷积层,然后我们有两个使用 1x1 卷积核的并行卷积层,其通道数量取决于每个点的锚点数量。

对于分类层,我们对每个锚点输出两个预测值:它是背景(不是目标)的分数,和它是前景(实际的目标)的分数。

对于回归或边框调整层,我们输出四个预测值:Δx、Δy、Δw、Δh我们将会把这些值用到锚点中来得到最终的建议。

具体RPN详解看我博客的另一篇文章。

https://blog.csdn.net/qq_36269513/article/details/80421990

4.  ROI Pooling 

ROI Pooling的作用是通过最大池化操作将特征图上面的ROI固定为特定大小的特征图(7x7),以便进行后续的分类和包围框回归操作。

缩进RoI Pooling layer forward过程:在之前有明确提到:proposal=[x1, y1, x2, y2]是对应MxN尺度的,所以首先使用spatial_scale参数将其映射回MxN大小的feature maps尺度(这里来回多次映射,是有点绕);之后将每个proposal水平和竖直都分为7份,对每一份都进行max pooling处理。这样处理后,即使大小不同的proposal,输出结果都是7x7大小,实现了fixed-length output。

proposal示意图


存在的问题

由于预选ROI的位置通常是有模型回归得到的,一般来说是浮点数,而赤化后的特征图要求尺度固定,因此ROI Pooling这个操作存在两次数据量化的过程。1)将候选框边界量化为整数点坐标值;2)将量化后的边界区域平均分割成kxk个单元,对每个单元的边界进行量化。事实上,经过上面的两次量化操作,此时的ROI已经和最开始的ROI之间存在一定的偏差,这个偏差会影响检测的精确度。


图8 ROI Pooling解释

下面我们用直观的例子具体分析一下区域不匹配问题,如图所示,这是一个Faster-rcnn检测框架。输入一张800x800的图片,图片中有一个665x665的BB中框这一只狗。图片经过特征提取网络之后,整个图片的特征图变为800/32 * 800/32,即25x25,但是665/32=20.87,带有小数,ROI Pooling直接将它量化为20。在这里引入了一次偏差。由于最终的特征映射的大小为7x7,即需要将20x20的区域映射成7x7,矩形区域的边长为2.86,又一次将其量化为2。这里再次引入了一次量化误差。经过这两次的量化,候选ROI已经出现了严重的偏差(如图中绿色部分所示)。更重要的是,在特征图上差0.1个像素,对应到原图上就是3.2个像素。

5. ROI Pooling后的检测网络


图9 检测网络

如上图所示,在获得7x7x512的特征映射之后,通过Flatten操作将其展开为一维向量,然后经过两个全连接层对其进行分类和回归。一个有 N+1 个单元的全连接层,其中 N 是类的总数,另外一个是背景类。一个有 4N 个单元的全连接层。我们希望有一个回归预测,因此对 N 个类别中的每一个可能的类别,我们都需要 Δx、Δy、Δw、Δh。

Classification部分利用已经获得的proposal feature maps,通过full connect层与softmax计算每个proposal具体属于那个类别(如人,车,电视等),输出cls_prob概率向量;同时再次利用bounding box regression获得每个proposal的位置偏移量bbox_pred,用于回归更加精确的目标检测框。Classification部分网络结构如图15。

图15 Classification部分网络结构图

从PoI Pooling获取到7x7=49大小的proposal feature maps后,送入后续网络,可以看到做了如下2件事:

  1. 通过全连接和softmax对proposals进行分类,这实际上已经是识别的范畴了
  2. 再次对proposals进行bounding box regression,获取更高精度的rect box
这里来看看全连接层InnerProduct layers,简单的示意图如图16,

图16 全连接层示意图

其计算公式如下:

其中W和bias B都是预先训练好的,即大小是固定的,当然输入X和输出Y也就是固定大小。所以,这也就印证了之前Roi Pooling的必要性。到这里,我想其他内容已经很容易理解,不在赘述了。


6. 损失函数计算

对于每个锚点,首先在后面接上一个二分类softmax,有2个score 输出用来表示这是一个前景还是一个背景的概率 (p_i),然后再接上一个bounding box的regressor 输出代表这个锚点的4个坐标位置(t_i),因此RPN的总体Loss函数可以定义为 :


其中Lcls表示分类loss,这里使用两类别(前景还是背景)的log loss;Lreg表示回归loss,这里使用的是Smooth-L1;


i表示第i个锚点,当锚点是正beiji样本时 p_i^* =1 ,是负样本则为0 。 t_i^* 表示 一个与正样本锚点相关的ground true box坐标 (每个正样本锚点 只可能对应一个ground true box: 一个正样本锚点 与某个grand true BB对应,那么该锚点与ground true box 的IOU要么是所有anchor中最大,要么大于0.7) 。

x,y,w,h分别表示box的中心坐标、宽和高;x,x_a,x^* 分别表示 predicted box, anchor box, and ground truth box ,如下图所示;t_i 表示predict box相对于anchor box的偏移量;t_i^* 表示ground true box相对于anchor box的偏移量,学习的目标就是让前者接近后者的值。


图13 predicted box, anchor box, and ground truth box


7. 正负样本的划分

  • 对每个标定的ground true box区域,与其重叠比例最大的anchor记为 正样本 (保证每个ground true 至少对应一个正样本anchor);
  • 对1)剩余的anchor,如果其与某个标定区域重叠比例大于0.7,记为正样本(每个ground true box可能会对应多个正样本anchor。但每个正样本anchor 只可能对应一个grand true box);如果其与任意一个标定的重叠比例都小于0.3,记为负样本。
  • 对上面两步剩余的anchor,弃去不用;
  • 跨越图像边界的anchor弃去不用。

8. Faster-rcnn训练策略


图14 Faster-rcnn训练策略

  • 用ImageNet模型初始化,独立训练一个RPN网络;
  • 仍然用ImageNet模型初始化,但是使用上一步RPN网络产生的proposal作为输入,训练一个Fast-RCNN网络,至此,两个网络每一层的参数完全不共享;
  • 使用第二步的Fast-RCNN网络参数初始化一个新的RPN网络,但是把RPN、Fast-RCNN共享的那些卷积层的learning rate设置为0,也就是不更新,仅仅更新RPN特有的那些网络层,重新训练,此时,两个网络已经共享了所有公共的卷积层;
  • 仍然固定共享的那些网络层,把Fast-RCNN特有的网络层也加入进来,形成一个unified network,继续训练,fine tune Fast-RCNN特有的网络层,此时,该网络已经实现我们设想的目标,即网络内部预测proposal并实现检测的功能。

即进行交替训练,迭代2次的原因是作者发现多次的迭代并没有显著的改善性能。 


四、总结

最后,给大家介绍一个很好用的网络可视化工具,专门用来可视化.prototxt文件,你可以将.prototxt文件中的内容复制到该链接点击打开链接,然后按下Shift+Enter,就可以看到漂亮的网络结构啦。如下所示:


图14 caffe可视化工具




参考文献:

[1] Faster R-CNN: Down the rabbit hole of modern object detection,链接地址

[2] CNN目标检测(一):Faster RCNN详解,链接地址

[3] Faster R-CNN,链接地址

[4] 详解 ROI Align 的基本原理和实现细节,链接地址

[5] NMS——非极大值抑制,链接地址

[6]Faster RCNN算法详解 链接地址

[7]http://www.360doc.com/content/17/0809/10/10408243_677742029.shtml

展开阅读全文

没有更多推荐了,返回首页