赞
踩
注:可以先看文末总结
1.Faster RCNN 整体思路概述
如图1.1所示,Faster RCNN 的整体框架按照功能区分,大致分为4个模块,分别是特征提取网络backbone模块、RPN模块、RoI and RoI pooling模块和RCNN模块。
图 1.1 Faster RCNN 整体框架
Backbone模块:主要负责接收输入数据,并进行数据预处理和特征提取得到输入图像对应的feature maps,并传递给下一层。这部分论文中用的VGG16和ZF框架,后来又有人用Resnet。
RPN network模块:这一模块主要有两个功能,一方面要生成一组proposals(图像中可能是前景的区域坐标),并将其传递给RoI模块;另一方面要计算RPN网络的损失,用于更新网络的参数。
RoI模块:对proposals进行降采样,并按proposals的坐标提取出feature maps中的特征,并将其传入下一层。
RCNN network模块:这一模块主要有两个功能,一方面用多层全连接网络对RoI传入的特征进行分类和回归,以得到预测目标的位置和标签;另一方面计算RCNN的损失,用于更新网络的参数。
如图1.1所示绿色框中的部分仅在训练时存在,整个结构的核心部分主要集中在后面三个部分,下面将对其进行详细的梳理。
2.Backbone模块
这一模块主要是利用效果比较好的卷积网络结构进行特征提取,这里就不详细介绍了。以VGG16为例,如图2.1所示,选取VGG16的前五层,取第五层pooling之前的数据作为feature maps。这里假设输入数据预处理后的尺度是则feature maps的尺度是
图 2.1 Backbone 的结构图
3. RPN network模块
如图3.1所示为RPN network的总体框架。
图 3.1 RPN network 整体框架及数据流关系(绿色部分表示仅在训练时存在)
3.1 RPN网络的输入输出和任务
输入:feature maps
输出:proposals(bounding box 的位置坐标)
任务:训练RPN网络;根据feature maps计算proposals
这里思考几个问题,如果按照常规的有监督学习思路对RPN网络进行组织训练,即以ground true bounding box(ground true bbox)的坐标进行回归,以其类别标签进行分类。对于分类问题问题不大,但是因为ground true bbox 的标签在原图上的随机性比较大,数据分布比较广,很难找到合适的网络使回归损失收敛。
因此作者想到了另一个方法,不直接输出box的真值,而是通过一定的映射关系(后面会讲)输出固定基box坐标下的偏移值。这样训练起来网络要容易收敛许多。
上面说的基box就是下面要讲的anchor。
3.2 Anchor 与 anchor的生成
Anchor简单来说就是在原图上的一些矩型框,但是这一系列矩形框与feature maps相关联。如图3.2所示,对于feature maps上的某一个点都会生成一定数量的anchor,论文中采用三种尺寸(128, 256, 512),以及三种长宽比(1:1, 1:2 , 2:1),组合起来一共有九种情况,即特征图上的每个点都会生成九个anchor。在代码中用每个anchor的左上角和右下角坐标来表示其位置。以一个特征点的九个anchor为例,就是生成如下形式的box坐标矩阵,维度为[9, 4]。
-
- [[ -84. -40. 99. 55.]
-
- [-176. -88. 191. 103.]
-
- [-360. -184. 375. 199.]
-
- [ -56. -56. 71. 71.]
-
- [-120. -120. 135. 135.]
-
- [-248. -248. 263. 263.]
-
- [ -36. -80. 51. 95.]
-
- [ -80. -168. 95. 183.]
-
- [-168. -344. 183. 359.]]
图 3.2 feature maps中某一点的anchors
但是刚才得到的坐标点是以这九个anchor的几何中心作为坐标原点得到的box坐标,因此还需要求anchors在原图坐标系下的box坐标。
首先要将feature maps映射到原图上,因为在backbone网络中对原图进行降采样得到feature maps,采样步长 stride = 16,因此将feature maps的坐标点乘以16,便可以映射回原图尺度。然后分别以这[37, 50]个点为原点,生成所有的anchors坐标。Anchor generate模块便是完成这部分功能,如图3.3所示。
图 3.3 Anchor generate 功能示意图
生成的总anchors数为
3.3 RPN网络的预测值
这部分功能主要由图3. 1.a中的Head模块完成,这里需要注意的是RPN网络的预测值和输出不同。此模块共有两个输出结果:
Objectness:预测anchors是前景还是背景的可能性大小
Pre bbox delta:预测anchors与ground true bounding box 的偏移量。
Head模块接收feature maps ,首先利用 [3\times3] 的卷积进行更深层的特征提取,然后利用两个 [1\times1] 卷积分别实现分类网络和回归网络。
在物体检测中通常将有物体的位置称为前景,没有物体的位置称为背景。在RPN的分类网络中,只需要区分出前景背景信息即可,因此这是一个二分类问题,考虑到每个特征点有9个anchor,所以分类网络中的卷积网络有 [9\times2]=18 个通道。同理回归网络要输出对anchor的修正,所以卷积层对应有 [9\times4]=36 个通道。
图 3.1.a Head 和Box decode模块
3.4 修正值与anchors关系
考虑某一特定的anchor,其中心点的坐标是 (x, y) ,宽是 w ,高是 h ,假设它对应的ground true bounding box坐标为 (x_0, y_0) ,宽是 w_0 ,高是 h_0 ,则对应的偏移值计算公式为:
3.3中Head模块输出的便是所有anchors的偏差值,利用式(1),可以实现RPN网络的偏差值与原值的相互转换。
3.5 解码与编码
通过3.4和3.3知道head模块输出的并不是预测bounding box的位置坐标,要求位置坐标还需要利用anchors的坐标进行转换。这里约定两个过程:
解码:已知偏差坐标(t_x, t_y, t_w, t_h)和基(在RPN中可以认为是anchor)坐标 (x_1, y_1, x_2, y_2) ,求预测bounding box坐标 (x_1^, ,y_1^,, x_2^, ,y_2^,) 的过程。
编码:已知ground true bbox坐标 (x_1^, ,y_1^,, x_2^, ,y_2^,) 和基(在RPN中可以认为是anchor)坐标 (x_1, y_1, x_2, y_2) ,求偏差坐标 (t_x, t_y, t_w, t_h) 的过程。
图3.1.a中的Box decode 模块完成解码过程,对Head模块传来的的pre bbox delta解码之后生成在原图坐标系下的pre bounding box 的位置坐标。
图3.1.c中Box code 完成编码过程。
具体实现还要考虑到原始图像的大小,进而对解码结果进行修整。
3.6 NMS 与生成proposals
现在假设RPN模型已经训练成功,网络处于inference阶段,Head模块可以输出较理想的objectness 和 pre bbox delta 值。在经过box decode之后会输出所有anchors的objectness得分和pre bounding box坐标。最后利用filter proposals模块完成NMS和生成proposals的任务。如图3.1.b所示,具体描述如下:
根据objectness的前景得分进行排序,按一定比例选出前12000个pre bbox 得到最初的建议区域。
考虑到一个物体可能会有多个bounding box重叠对应,所以在应用非极大值抑制(NMS)将重叠框去掉。
最后在剩余的bbox中,根据objectness前景得分随机抽取2000个box,作为最终的proposals。
图3.1.b Filter proposalss模块
3.7 RPN network的训练
为了让RPN网络能够提出良好的proposals,需要对网络进行训练。就像传统的有监督网络一样,在训练前我们需要明确,模型的预测值、真值和损失函数这三个要素。预测值在3.3中已经介绍,这里介绍真值和损失函数。图3.1.c 为训练部分结构图。
图 3.1.c RPN 训练部分结构图
3.7.1 RPN network的真值
RPN网络的预测值是对anchors的分类和回归修正,其真值也有两个——对应anchors的类别标签和真实偏差值。这一部分主要由Assign targets to anchors模块完成。
注意这两者的求取都是建立在anchors的基础之上。
为了便于理解,先介绍以下ground true的形式:
Ground true label:假设需要区分的类别有C种,则label的值属于整数[0, C],label的个数为输入图片中目标的个数。假如C=3, 有2个目标,则label = [1, 0]或[0, 2]……
Ground true bounding box:形式为box的左上角和右下角坐标如 (x_1, y_1, x_2, y_2) ,box个数为输入图片中目标的个数。假如C=3, 有2个目标,则box{[1, 2, 3, 4], [5, 6, 7, 8]}。
注:与box中对应位置的label值即为该位置的目标类别。
(1)真值标签(target labels)的求取
在这一部分标签主要要区分出前景和背景,不需要具体的分类,因此标签值有两个:
0:背景
1:前景
前景背景的区分是通过计算ground true bounding box与anchors的IoU值来区分的,这里需要计算每个ground true bbox和anchors的IoU,也就是说会形成一个IoU矩阵。假设ground true bbox有N个,则IoU大小为[N, 166500]具体的判断标准如下:
对于任何一个anchor与所有的gt box最大IoU小于阈值0.3(可以调整的参数),则视为负样本。
对于任何一个gt box,与其有最大IoU的anchor视为正样本。
对于任何一个anchor,与所有gt box的IoU大于阈值0.7(可以调整的参数),则视为正样本。
-1标签:在编程时,可以将IoU值在0.3-0.7之间的anchor标签置位-1,作为无效anchor的标记。这部分anchor不参与分类和回归损失的计算。
(2)真实坐标(target regression)的求取
这部分的主要思路是,利用IoU矩阵,对于某一anchor找到与其IoU值最大的gt box坐标,作为其真实坐标,依次找到所有的anchors真值。
注:
1)这里有一个问题:对某些不符合前景标准的anchor也进行了真值赋值,但是在后续计算中,会根据target label进行抽样,不符合前景背景标准的target regression不会被计算到。
2)这里求得的所有anchor的真值坐标是 (x_1, y_1, x_2, y_2) 形式的,还需要对其进行编码操作(box code)才能得到RPN网络的回归真值target regression。
3.7.2 RPN network损失函数的计算
经过3.7.1和3.2,RPN获得了网络的预测值和真值,现在可以计算损失函数了。
(1)抽取正负样本
由于网络预测的bounding box综数接近两万,并且大部分box标签都是背景,如果都计算损失的话则正负样本失去平衡,不利于网络收敛。因此,RPN默认选择256(可调整)个bounding box进行损失计算,其中最多不超过128(可调整)个正样本。如果超过则进行随机抽取。
(2)损失函数的计算
RPN损失函数主要有两部分组成,即分类损失和回归损失,如下所示:
L({p_i, t_i}) = \frac{1}{N_{cls}}\sum_iL_{cls}(p_i, p_i^*)+\lambda\frac{1}{N_{reg}}\sum_ip_i^*L_{reg}(t_i, t_i^*)\tag{2}
L_{cls}(p_i, p_i^*) 代表了晒算出来的256个box的分类损失,这里是一个二分类问题,使用的是交叉熵函数。其中 p_i 为真值, p_i^* 为预测值。
L_{reg}(t_i, t_i^*) 代表了回归损失,回归损失使用的是 smooth_{L1} 函数,如下所示。其中 t_i 为真值, t_i^* 为预测值。
L_{reg}(t_i, t_i^*) = \sum_{i\in{x, y, w, h}}smooth_{L1}(t_i, t_i^*)\\ smooth_{L1}(t_i, t_i^*) =
注:在训练阶段RPN的损失函数会传递到RCNN部分一起计算总的损失函数,进而进行反馈,改善网络效果。
至此RPN部分的所有内容梳理完毕。
4. RoI and RoI pooling模块
4.1 RoIs的获得
训练时由RPN网络传输过来的proposals的数量为2000个,其中仍然有很多背景框,真正的存在目标的前景占比很少。因此在进行特征提取之前要对proposals进行再次筛选。筛选的流程如图4.1所示。
计算IoU矩阵和分配标签的过程和RPN网络中Assign targets to anchors模块一致,这里只是将anchors替换成了proposals。这里就不重复介绍了。
在分配完标签之后,在所有正负样本中选出256(参数可调节)个样本,正样本数按照一定比例提取,同样比例可以调整。
最后选出的256个proposals即为RoIs。
图 4.1 RoI 和 RoI pooling 结构图
4.2 RoI pooling
在4.1中得到的RoIs区域,实际是对应原图中可能是前景和背景的bbox坐标,我们需要将这个坐标映射到feature maps上,进而提取出RoI区域对应特征图。然后再传递给后面的全连接层进行分类和回归。
这里有一个问题是,特征最后要输入到全连接层进行计算,所以要求输入的特征图大小是一样的。而由于RoI 的bbox大小不同,其提取的特征大小也不同,因此特征传递给FC层之前需要进行一定的处理,这就是RoI pooling的主要作用。
论文中统一将特征图pooling到 [7\times7] 大小。
具体的方法这里就不详细介绍了。
注:由于RoI pooling在实现的时候会多次取整,导致精度不高。后来常用maskRCNN中的RoI Align代替。
5. RCNN network
5.1 RCNN的输入输出和任务
输入:RoI and RoI pooling 网络传递过来的 固定维度的pooling maps特征图
输出:目标类别和位置偏差的预测值,以及RCNN Loss。
任务:训练RCNN网络;对pooling maps进行学习,利用三层全连接网络进行标签分类及位置回归。
5.2 全连接模块
这里用三层全连接层对特征进行处理,如图所示。前两层是VGG16中的第六第七层,最后一层是两个全连接层,分别对256个RoIs区域进行类别预测和位置预测。
图 5.1 全连接网络结构图
图中C代表需要检测的类别,背景算作第0类,所以类别预测输出的维度是 [256\times(1+C)] 。位置预测需要对每一类都预测出位置所以输出维度是 [256\times(1+C)\times4] 。
5.3 RCNN网络的训练
在训练之前我们来梳理以下RCNN网络的预测值和真值。RCNN 的预测值在5.2中已经求出,就是RCNN网络的输出值。
(1)RCNN网络的真值
RCNN网络的真值是RoIs区域的类别标签和与对应的真实坐标的偏差。RoIs区域对应的真实坐标在RoI模块中的assign targets中实际已经得到,具体过程同3.7.1中RPN部分一致。
注:这里得到的RoIs target location 是编码前的表示,所以需要进行box code计算偏差,才是真正的RCNN网络的真值。
(2)损失函数
损失函数的计算和RPN部分相同,不在重复。
需要注意的是这里的分类损失是C+1类,而不是二分类;
回归损失只计算正样本部分对应类别的损失。
举例说明第二点。假设第3个区域为正样本且是第K类,则对应pre bbox delta中的[3,K, :]的delta值参与损失计算。
至此RCNN中关于训练和inference的思路全部梳理完毕。图5.2展示了RoI and RoI pooling和RCNN模块之间的关系和数据流。
图5.2 RoI and RoI pooling及RCNN模块之间的关系和数据流(绿色部分表示仅在训练时存在)
6. 总结
本文主要从编程实现的角度梳理了Faster RCNN的流程,重点介绍了RPN部分的实现。RoI and RoI pooling和RCNN部分的结构和RPN网络实际上十分类似,很多的思路都是想通的,因此介绍的并不详细。
比如:RPN的预测值是对anchors进行修正,得到proposals;RCNN网络其实是对RoI进行修正得到最终的预测结果。其修正的目的都是为了使被修正的bbox经过修正后能够更接近ground true bbox。
关于RoI pooling和RoI Align:其二者的具体方法本文没有介绍,这部分的内容并不影响读者对整个网络的理解,如果想要了解,建议阅读原文、源码或其他博客。
关于参数上细节:整个框架中有许多可调节的超参数,如anchor的大小 和 长宽比、生成proposals时的下采样数等等。而且有些参数在训练和inference时并不相同。如果读者想要了解请参考源码。
关于参考代码:本文的主要参考代码是torchvision包中自带的fasterrcnn_resnet50_fpn()实现。
关于配图:图3.3中的部分图直接截取自
Object Detection and Classification using R-CNNswww.telesens.co
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。