FasterRcnn 算法原理讲解笔记 下面的介绍都是基于VGG16 的Faster RCNN网络,各网络的差异在于Conv layers层提取特征时有细微差异,至于后续的RPN层、Pooling层及全连接的分类和目标定位基本相同.
文章目录
- FasterRcnn 算法原理讲解笔记
-
- 一、整体框架
-
- 1.1、Conv layers提取特征图:
- 1.2、RPN(Region Proposal Networks):
- 1.3、Roi Pooling:
- 1.4、Classifier:
- 二、网络结构
-
- 2.1、Conv layers
-
- 2.1.1 faster_rcnn读入图片尺寸问题
- 2.1.2 Conv layers结构
- 2.2、RPN(Region Proposal Networks):
-
- 2.2.1 Anchors box的生成
- 2.2.2 RPN工作原理解析
-
- 2.2.2.1 rpn-data
- 2.2.2.2 rpn_loss_cls、rpn_loss_bbox、rpn_cls_prob
- 2.2.2.3 proposal
- 2.2.2.4 roi_data
- 2.2.2.5ROI Pooling:
- 2.2.2.5 全连接层
- 三、faster-rcnn + FPN网络,提升小目标检测 一些理解
一、整体框架
文章图片
如上图所示,整体主要分为4个阶段:
1.1、Conv layers提取特征图:
作为一种CNN网络目标检测方法,Faster RCNN首先使用一组基础的conv+relu+pooling层提取input image的feature maps,该feature maps会用于后续的RPN层和全连接层,具体为VGG的网络层,13个conv+13个relu+4个pooling层。
1.2、RPN(Region Proposal Networks):
RPN网络主要用于生成region proposals,首先生成一堆Anchor box,对其进行裁剪过滤后通过softmax判断anchors属于前景(foreground)或者后景(background),即是物体or不是物体,所以这是一个二分类;同时,另一分支bounding box regression修正anchor box,形成较精确的proposal(注:这里的较精确是相对于后面全连接层的再一次box regression而言)。
1.3、Roi Pooling:
该层利用RPN生成的proposals和VGG16最后一层得到的feature map,得到固定大小的proposal feature map,进入到后面可利用全连接操作来进行目标识别和定位。
(感觉这个操作有点像金字塔池化)
1.4、Classifier:
会将Roi Pooling层形成固定大小的feature map进行全连接操作,利用Softmax进行具体类别的分类,同时,利用L1 Loss完成bounding box regression回归操作获得物体的精确位置。
二、网络结构
文章图片
整体网络结构如上图所示。
2.1、Conv layers
2.1.1 faster_rcnn读入图片尺寸问题 Faster-Rcnn本身对于采集的原图像没有要求,但是作为输入放入网络训练的话就必须限制图片的大小,一般Faster-Rcnn对于输入图像的大小限制规则是:限制最小边为600,最大边为1000,对于输入图像优先考虑最大边的限制。
例如:
输入图像的大小是:375x500x3,则resize后的图像大小为:600x800x3
输入图像的大小是:375x800x3,则resize后的图像大小为:469x1000x3
此时假定输入的图片大小M*N = 600 * 1000
2.1.2 Conv layers结构 13个conv层:kernel_size=3,pad=1,stride=1; (经过卷积层,图片大小不变)
+
13个relu层:激活函数,不改变图片大小
+
4个pooling层:kernel_size=2,stride=2; pooling层会让输出图片是输入图片的1/2
经过Conv layers,图片大小变成(M/16)*(N/16),即:60x40(1000/16≈60,600/16≈40);则,Feature Map就是60x40x512-d(注:VGG16是512-d,ZF是256-d),表示特征图的大小为60x40,数量为512
2.2、RPN(Region Proposal Networks):
RPN主要分为两路:
rpn_cls 和 rpn_bbox
Feature Map进入RPN后,先经过一次3x3的卷积,同样,特征图大小依然是60x40,数量512,这样做的目的应该是进一步集中特征信息,接着看到两个1x1卷积,分成两路进行卷积,即kernel_size=1*1,p=0,stride=1,一路生成18维,一路生成36维。
文章图片
1) rpn_cls:
60x40x512-d * 1x1x512x18 -> 60x40x18
这一路主要是对 Anchor box 内图像信息做二分类工作
2)rpn_bbox: 60x40x512-d * 1x1x512x36 -> 60x40x36
得到其Anchor box四个坐标信息(其实是偏移量,后面介绍)
2.2.1 Anchors box的生成 前面提到经过Conv layers后,图片大小变成了原来的1/16,令feat_stride=16,在生成Anchors时,我们先定义一个base_anchor,大小为16x16的box(因为特征图(60*40)上的一个点,可以对应到原图(1000x600)上一个16x16大小的区域),源码中转化为[0,0,15,15]的数组,参数ratios=[0.5, 1, 2]scales=[8, 16, 32].
先看[0,0,15,15],面积保持不变,长、宽比分别为[0.5, 1, 2]时产生的Anchors box。
文章图片
如果经过scales变化,即长、宽分别均为 (16x8=128)、(16x16=256)、(16x32=512),对应anchor box如图:
文章图片
综合以上两种变换,最后生成9个Anchor box
文章图片
所以,最终base_anchor=[0,0,15,15]生成的9个Anchor box坐标如下:
[[ -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.]]
特征图大小为60x40,所以会一共生成60x40x9=21600个Anchor box。
源码中,通过width:(0—60)*16,height(0—40)*16建立shift偏移量数组,再和base_ancho基准坐标数组累加,得到特征图上所有像素对应的Anchors的坐标值,是一个[216000,4]的数组。
eg:
width: [0,1,2,3,…,59]
heith: [0,1,2,3,…39] 共有 60x40=2400种组合
if: width=1,heith=0,则对应在原图坐标点为:(1x16, 0x16)
base_ancho[0] = [ -84, -40, 99, 55]
相加结果为: [-84+16, -40+0, 99+16,55+0] = [-68, -40, 115, 55]。
比较通俗的讲就是,人为制定了 9 个不同大小的矩形框,又在 600x1000的图像中,均匀的选取了 60x40 个位置,去放这9个矩形框,让矩形框在原图中游走。。。
所以,相当于在一个 6001000的图片中,选取了 4060*9=21600个矩形框,这个数字大不大,当然还是挺大的,所以不能全都用,要进一步做筛选。
2.2.2 RPN工作原理解析 为了进一步更清楚的看懂RPN的工作原理,将Caffe版本下的网络图贴出来,对照网络图进行讲解会更清楚
文章图片
部分的网络图,其中‘rpn_conv/33’是33的卷积,上面有提到过,接着是两个1*1的全卷积,分别是图中的‘rpn_cls_score’和‘rpn_bbox_pred’,在上面同样有提到过。接下来,分析网络图中其他各部分的含义:
2.2.2.1 rpn-data
1.layer {
2.name: 'rpn-data'
3.type: 'Python'
4.bottom: 'rpn_cls_score'#仅提供特征图的height和width的参数大小
5.bottom: 'gt_boxes'#ground truth box
6.bottom: 'im_info'#包含图片大小和缩放比例,可供过滤anchor box
7.bottom: 'data'
8.top: 'rpn_labels'
9.top: 'rpn_bbox_targets'
10.top: 'rpn_bbox_inside_weights'
11.top: 'rpn_bbox_outside_weights'
12.python_param {
13.module: 'rpn.anchor_target_layer'
14.layer: 'AnchorTargetLayer'
15.param_str: "'feat_stride': 16 \n'scales': !!python/tuple [8, 16, 32]"
16.}
17.}
这一层主要是为特征图60*40上的每个像素生成9个Anchor box,并且对生成的Anchor box进行过滤和标记,参照源码,过滤和标记规则如下:
①去除掉超过1000*600这原图的边界的anchor box②如果anchor box与ground truth的IoU值最大,标记为正样本,label=1③如果anchor box与ground truth的IoU>0.7,标记为正样本,label=1④如果anchor box与ground truth的IoU<0.3,标记为负样本,label=0剩下的既不是正样本也不是负样本,不用于最终训练,label=-1
除了对anchor box进行标记外,另一件事情就是计算anchor box与ground truth之间的偏移量。
令:ground truth:标定的框也对应一个中心点位置坐标x*,y*和宽高w*,h*anchor box: 中心点位置坐标x_a,y_a和宽高w_a,h_a所以,偏移量:△x=(x*-x_a)/w_a△y=(y*-y_a)/h_a △w=log(w*/w_a)△h=log(h*/h_a)
通过ground truth box与预测的anchor box之间的差异来进行学习,从而是RPN网络中的权重能够学习到预测box的能力。
2.2.2.2 rpn_loss_cls、rpn_loss_bbox、rpn_cls_prob 经过上述操作后,就得到了 n个矩形框anchor box,而且每个anchor box,都具有自己的标签和label=(0,1)。
rpn_loss_cls:对应 softmax损失函数,对anchor box进行分类操作
rpn_loss_bbox: 对应smooth L1损失函数,对anchor box坐标点进行操作,训练便宜坐标的数值△x, △y, △w, △h。
rpn_cls_prob:计算概率值(可用于下一层的nms非最大值抑制操作)。这个操作又进一步减少了anchor box。
在’rpn-data’中已经为预测框anchor box进行了标记,并且计算出与gt_boxes之间的偏移量,利用RPN网络进行训练。
得到了上述中的anchor box,就要开始训练了。
在训练RPN时,一个Mini-batch是由一幅图像中任意选取的256个proposal组成的,其中正负样本的比例为1:1。如果正样本不足128,则多用一些负样本以满足有256个Proposal可以用于训练,反之亦然
2.2.2.3 proposal
1.layer {
2.name: 'proposal'
3.type: 'Python'
4.bottom: 'rpn_cls_prob_reshape' #[1,18,40,60]==> [batch_size, channel,height,width]Caffe的数据格式,anchor box分类的概率
5.bottom: 'rpn_bbox_pred'# 记录训练好的四个回归值△x, △y, △w, △h
6.bottom: 'im_info'
7.top: 'rpn_rois'
8.python_param {
9.module: 'rpn.proposal_layer'
10.layer: 'ProposalLayer'
11.param_str: "'feat_stride': 16 \n'scales': !!python/tuple [4, 8, 16, 32]"
12.}
13.}
在输入中我们看到’rpn_bbox_pred’,记录着训练好的四个回归值△x, △y, △w, △h。
源码中,会重新生成60x40x9个anchor box,然后累加上训练好的△x, △y, △w, △h,从而得到了相较于之前更加准确的预测框region proposal,进一步对预测框进行越界剔除和使用nms非最大值抑制,剔除掉重叠的框;比如,设定IoU为0.7的阈值,即仅保留覆盖率不超过0.7的局部最大分数的box(粗筛)。最后留下大约2000个anchor,然后再取前N个box(比如300个);这样,进入到下一层ROI Pooling时region proposal大约只有300个。
自此,RPN网络结束,经过此网络筛选,anchor box 由原来的21600变为300个。
2.2.2.4 roi_data
1.layer {
2.name: 'roi-data'
3.type: 'Python'
4.bottom: 'rpn_rois'
5.bottom: 'gt_boxes'
6.top: 'rois'
7.top: 'labels'
8.top: 'bbox_targets'
9.top: 'bbox_inside_weights'
10.top: 'bbox_outside_weights'
11.python_param {
12.module: 'rpn.proposal_target_layer'
13.layer: 'ProposalTargetLayer'
14.param_str: "'num_classes': 81"
15.}
16.}
为了避免定义上的误解,我们将经过‘proposal’后的预测框称为region proposal(其实,RPN层的任务其实已经完成,roi_data属于为下一层准备数据)
主要作用:
① RPN层只是来确定region proposal是否是物体(是/否),这里根据region proposal和ground truth box的最大重叠指定具体的标签(就不再是二分类问题了,参数中指定的是81类)
② 计算region proposal与ground truth boxes的偏移量,计算方法和之前的偏移量计算公式相同
经过这一步后的数据输入到ROI Pooling层进行进一步的分类和定位。
2.2.2.5ROI Pooling:
1.layer {
2.name: "roi_pool5"
3.type: "ROIPooling"
4.bottom: "conv5_3"#输入特征图大小
5.bottom: "rois"#输入region proposal
6.top: "pool5"#输出固定大小的feature map
7.roi_pooling_param {
8.pooled_w: 7
9.pooled_h: 7
10.spatial_scale: 0.0625 # 1/16
11.}
12.}
【深度学习-目标检测|FasterRcnn 算法原理讲解笔记(非常详细)】ROI Pooling:作用是将不同大小的特征图,全部pooling为 n*n同等大小的特征图。
从上述的Caffe代码中可以看到,输入的是RPN层产生的region proposal(假定有300个region proposal box)和VGG16最后一层产生的特征图(60x40 512-d),遍历每个region proposal,将其坐标值缩小16倍,这样就可以将在原图(1000x600)基础上产生的region proposal映射到60x40的特征图上,从而将在feature map上确定一个区域(定义为RB*)。
在feature map上确定的区域RB*,根据参数pooled_w:7,pooled_h:7,将这个RB区域划分为7x7,即49个相同大小的小区域,对于每个小区域,使用max pooling方式从中选取最大的像素点作为输出,这样,就形成了一个7x7的feature map.
以此,参照上述方法,300个region proposal遍历完后,会产生很多个77大小的feature map,故而输出的数组是:[300,512,7,7],作为下一层的全连接的输入.
再通俗点讲,就是输入是一个 40x60的特征图,共512维;然后在特征图中画300个矩形框(也就是region proposal),对每一个矩形框通过roi_pooling(这个不懂的自己再去看),变为7x7的特张图,也就是 7x7x512x300.
2.2.2.5 全连接层 经过roi pooling层之后,batch_size=300, proposal feature map的大小是7*7,512-d,对特征图进行全连接,参照下图,最后同样利用Softmax Loss和L1 Loss完成分类和定位。
文章图片
通过full connect层与softmax计算每个region proposal具体属于哪个类别,输出cls_prob概率向量;同时再次利用bounding box regression获得每个region proposal的位置偏移量bbox_pred,用于回归获得更加精确的目标检测框。
即从PoI Pooling获取到7x7大小的proposal feature maps后,通过全连接主要做了:
1)通过全连接和softmax对region proposals进行具体类别的分类
2)再次对region proposals进行bounding box regression,获取更高精度的rectangle box。
最后再付一张完整的网络图:
文章图片
三、faster-rcnn + FPN网络,提升小目标检测 一些理解
文章图片
参考:
https://www.cnblogs.com/wangyong/p/8513563.html
https://blog.csdn.net/Lin_xiaoyi/article/details/78214874
https://blog.csdn.net/dudu815110/article/details/79088258 —fasterrcnn训练步骤