【目标检测】Faster R-CNN论文详解(Faster R-
论文原文:https://arxiv.org/pdf/1506.01497.pdf
R-CNN论文详解:https://www.jianshu.com/p/c1696c27abf8
fast R-CNN论文详解:https://www.jianshu.com/p/fbbb21e1e390
一、简介
faster R-CNN发表于NIPS2015,从命名不难看出,它和R-CNN、fast R-CNN一脉相承。首先简单比较一下三个算法:
- R-CNN采用Selective Search算法来提取(propose)可能的RoIs(regions of interest)区域。然后对每个RoI采用CNN进行目标分类。
- fast R-CNN则是采用兴趣区域池化(region of interest pooling,RoI pooling):首先用CNN提取图片feature maps,再从feature maps上提取RoIs,再进行classification。避免同时调用多个CNN网络,达到了共享计算量,大幅提高模型效率的效果。
- faster R-CNN则是将影响检测效率的传统方法selective search,也用CNN网络代替了,真正实现了基于深度学习的端到端的目标检测算法。在达到了与fast R-CNN相近的mAP基础上,使检测速度从fast的0.5fps上升至7fps。
二、网络结构
faster R-CNN结构faster R-CNN的网络可以分为四个大的模块:
- Conv layers:作为一种CNN网络目标检测方法,Faster R-CNN首先使用一组基础的conv+relu+pooling层提取image的feature maps。该feature maps被共享用于后续RPN层和全连接层。
- Region Proposal Networks:RPN网络用于生成region proposals。该层通过softmax判断anchors属于foreground或者background,再利用bounding box regression修正anchors获得精确的proposals。
- Roi Pooling:该层收集输入的feature maps和proposals,综合这些信息后提取proposal feature maps,送入后续全连接层判定目标类别。
- Classification:利用proposal feature maps计算proposal的类别,同时再次bounding box regression获得检测框最终的精确位置。
下图展示了python版本中的VGG16模型中的faster_rcnn_test.py的网络结构,可以清晰的看到该网络对于一副任意大小PxQ的图像,首先缩放至固定大小MxN,然后将MxN图像送入网络;而Conv layers中包含了13个conv层+13个relu层+4个pooling层;RPN网络首先经过3x3卷积,再分别生成foreground anchors与bounding box regression偏移量,然后计算出proposals;而Roi Pooling层则利用proposals从feature maps中提取proposal feature送入后续全连接和softmax网络作classification:
faster R-CNN测试结构图Conv layers、Roi Pooling、classification这三个模块其实和前作对应的模块并无大的差异,介绍R-CNN、fast R-CNN的文章见本文首的链接,这里我们不再反复赘述。而RPN则是我们这篇文章介绍的重点。
三、RPN(Region Proposal Networks)
RPN网络的输入是经过conv layers的feature maps,首先对feature maps进行3*3的conv+relu操作,得到新的特征图。
RPN
上图展示了RPN网络的结构。可以看到RPN网络实际分为2条线,左边一条通过softmax分类anchors获得foreground和background(检测目标是foreground)右边一条用于计算对于anchors的bounding box regression偏移量,以获得精确的proposal。
256-d表示特征图共有256张,k是每个基准点的anchor的个数,2k scores表示k个anchors的softmax的分数,每个anchor2个score(foreground/background),4k coordinates表示k个anchors坐标[x、y、w、h]的偏移量的regression结果。
3.1.Anchors
RPN网络的输入是经过conv+pool+relu操作的feature maps,针对feature maps上的每一点(特征点),映射回原图的感受野的中心点(基准点)。围绕这个基准点选取k=9个矩形框,这些矩形框就是所谓的anchors,他们共有3种形状,长宽比分别为1:1、1:2、2:1。具体形状见下图:
9个anchors的大小及形状关于anchors size,其实是根据检测图像设置的。在python demo中,会把任意大小的输入图像reshape成800x600(即图2中的M=800,N=600)。而对应这个尺寸的图像,anchors中长宽1:2中最大为352x704,长宽2:1中最大736x384,即9个不同大小的anchors里大概是可以从大到小覆盖800*600图像中各种尺寸和形状的目标。
为什么说是大概呢?因为很明显,这种固定尺寸与比例的anchors肯定无法精准的框出我们千奇百怪的目标,作者只是将anchors作为初始的检测框,在后续的流程中还有两次的bounding box regression可以修正检测框位置。
3.2.正负样本划分
在训练阶段需要人为的划分正负样本,让RPN网络去学习“判断anchor是正负样本的能力”。正样本为foreground(目标)、负样本为background(背景)。具体做法是将一张图像中产生的所有anchors与ground true box区域计算IoU(Intersection over Union,重叠比例),根据以下规则划分正负样本:
- 对每个标定的ground true box区域,与其IoU最大的anchor记为正样本(保证每个ground true至少对应一个正样本anchor)
- 剩余的anchor,如果其与某个标定区域重叠比例大于0.7,记为正样本。如果其与任意一个标定的重叠比例都小于0.3,记为负样本
- 上两步剩余的anchor弃去不用
- 跨越图像边界的anchor弃去不用
3.3.训练时的损失函数
RPN的损失函数是联合了正负样本分类与检测框回归的。目的是让我们的RPN网络具有鉴别正负样本与回归检测框至正确坐标的能力。公式如下:
RPN损失函数
第一项是分类损失,pi是anchor i作为目标的预测概率,pi*是标签,正样本为1,负样本为0,分类损失L(cls)是两个类别上(是目标或不是目标)的对数损失;
第二项是回归损失,pi* 代表回归损失仅对正样本,如果为负样本pi* =0,则不存在回归损失。ti是预测框与anchor i的坐标偏差,ti*是ground true box与anchor i的坐标偏差,优化这项回归损失可以让我们的模型学习到从anchor坐标到ground true box坐标的映射的能力,即是bounding box regression。L(reg)是smooth L1损失函数,公式如下:
smooth L1损失函数窗口一般使用四维向量(x, y, w, h)表示,分别表示窗口的中心点坐标和宽高。偏移量(tx,ty,tw,th)计算公式如下,带*表示是ground true box的参数,带a表示anchor的参数,不带任何标识的表示预测框的参数:
偏移量计算公式
训练RPN:文中提到如果每幅图的所有anchor都去参与优化loss function,那么最终会因为负样本过多(背景肯定多于目标)导致最终得到的模型对正样本预测准确率很低。因此,在每幅图像中随机采样256个anchors去参与计算一次mini-batch的损失。正负比例1:1(如果正样本少于128则补充采样负样本)。
3.4.Proposal层
测试阶段,在得到所有foreground anchors和其对应的偏移量[dx(A),dy(A),dw(A),dh(A)]后。Proposal Layer负责综合两者,计算出精准的proposal,流程如下:
-
生成anchors,利用[dx(A),dy(A),dw(A),dh(A)]对所有的anchors做bounding box regression回归(这里的anchors生成和训练时完全一致)
-
按照输入的foreground softmax scores由大到小排序anchors,提取前pre_nms_topN(e.g. 6000)个anchors,即提取修正位置后的foreground anchors。
-
将foreground anchors从MxN尺度映射回PxQ原图,判断fg anchors是否大范围超过边界,剔除严重超出边界fg anchors。
-
进行nms(nonmaximum suppression,非极大值抑制)
-
再次按照nms后的foreground softmax scores由大到小排序fg anchors,提取前post_nms_topN(e.g. 300)结果作为proposal输出。
四、RPN与fast R-CNN共享特征
我们知道,如果是分别训练两种不同任务的网络模型,即使它们的结构、参数完全一致,但各自的卷积层内的卷积核也会向着不同的方向改变,导致无法共享网络权重,论文作者提出了三种可能的方式:
-
交替训练。在这个解决方案中,首先训练RPN,并使用这些提议来训练Fast R-CNN。由Fast R-CNN微调的网络然后被用于初始化RPN,并且重复这个过程。这是原文中所有实验中使用的解决方案,交替循环训练了两次。
-
近似联合训练。在这个解决方案中,RPN和Fast R-CNN网络在训练期间合并成一个网络,在每次SGD迭代中,前向传递生成区域提议,在训练Fast R-CNN检测器将这看作是固定的、预计算的提议。反向传播像往常一样进行,其中对于共享层,组合来自RPN损失和Fast R-CNN损失的反向传播信号。这个解决方案很容易实现。但是这个解决方案忽略了关于提议边界框的坐标(也是网络响应)的导数,实验发现这个方法产生了与交替方法相近的结果,但训练时间减少了大约25−50%。
-
非近似的联合训练。如上所述,由RPN预测的边界框也是输入的函数。Fast R-CNN中的RoI池化层接受卷积特征以及预测的边界框作为输入,所以理论上有效的反向传播求解器也应该包括关于边界框坐标的梯度。在上述近似联合训练中,这些梯度被忽略。在一个非近似的联合训练解决方案中,需要一个关于边界框坐标可微分的RoI池化层。这是一个重要的问题,解决方法作者只是一笔带过:超纲了。
五、小结
不得不说,faster R-CNN这篇论文能量密度还是非常高的,值得拜读学习的地方非常多,而本文也只是着重介绍了一下RPN网络,非常值得复现的一篇文章。