下面的介绍都是基于VGG16 的Faster RCNN网络,各网络的差异在于Conv layers层提取特征时有细微差异,至于后续的RPN层、Pooling层及全连接的分类和目标定位基本相同.

一)、整体框架

我们先整体的介绍下上图中各层主要的功能

1)、Conv layers提取特征图:

作为一种CNN网络目标检测方法,Faster RCNN首先使用一组基础的conv+relu+pooling层提取input image的feature maps,该feature maps会用于后续的RPN层和全连接层

2)、RPN(Region Proposal Networks):

RPN网络主要用于生成region proposals,首先生成一堆Anchor box,对其进行裁剪过滤后通过softmax判断anchors属于前景(foreground)或者后景(background),即是物体or不是物体,所以这是一个二分类;同时,另一分支bounding box regression修正anchor box,形成较精确的proposal(注:这里的较精确是相对于后面全连接层的再一次box regression而言)

3)、Roi Pooling:

该层利用RPN生成的proposals和VGG16最后一层得到的feature map,得到固定大小的proposal feature map,进入到后面可利用全连接操作来进行目标识别和定位

4)、Classifier:

会将Roi Pooling层形成固定大小的feature map进行全连接操作,利用Softmax进行具体类别的分类,同时,利用L1 Loss完成bounding box regression回归操作获得物体的精确位置.

)、网络结构

现在,通过上图开始逐层分析

1)Conv layers

Faster RCNN首先是支持输入任意大小的图片的,比如上图中输入的P*Q,进入网络之前对图片进行了规整化尺度的设定,如可设定图像短边不超过600,图像长边不超过1000,我们可以假定M*N=1000*600(如果图片少于该尺寸,可以边缘补0,即图像会有黑色边缘)

①   13个conv层:kernel_size=3,pad=1,stride=1;

卷积公式:

outputsize=intputsize-kernel_size+2*padstride+1

所以,conv层不会改变图片大小(即:输入的图片大小=输出的图片大小)

②   13个relu层:激活函数,不改变图片大小

③   4个pooling层:kernel_size=2,stride=2;pooling层会让输出图片是输入图片的1/2

经过Conv layers,图片大小变成(M/16)*(N/16),即:60*40(1000/16≈60,600/16≈40);则,Feature Map就是60*40*512-d(注:VGG16是512-d,ZF是256-d),表示特征图的大小为60*40,数量为512

2)RPN(Region Proposal Networks):

Feature Map进入RPN后,先经过一次3*3的卷积,同样,特征图大小依然是60*40,数量512,这样做的目的应该是进一步集中特征信息,接着看到两个全卷积,即kernel_size=1*1,p=0,stride=1;

如上图中标识:

①   rpn_cls:60*40*512-d ⊕  1*1*512*18 ==> 60*40*9*2

逐像素对其9个Anchor box进行二分类

②   rpn_bbox:60*40*512-d ⊕  1*1*512*36==>60*40*9*4

逐像素得到其9个Anchor box四个坐标信息(其实是偏移量,后面介绍)

如下图所示:

(2.1)、Anchors的生成规则

前面提到经过Conv layers后,图片大小变成了原来的1/16,令feat_stride=16,在生成Anchors时,我们先定义一个base_anchor,大小为16*16的box(因为特征图(60*40)上的一个点,可以对应到原图(1000*600)上一个16*16大小的区域),源码中转化为[0,0,15,15]的数组,参数ratios=[0.5, 1, 2]scales=[8, 16, 32]

先看[0,0,15,15],面积保持不变,长、宽比分别为[0.5, 1, 2]是产生的Anchors box

如果经过scales变化,即长、宽分别均为 (16*8=128)、(16*16=256)、(16*32=512),对应anchor box如图

综合以上两种变换,最后生成9个Anchor box

所以,最终base_anchor=[0,0,15,15]生成的9个Anchor box坐标如下:

 [[ -.  -.   .   .]
[-. -. . .]
[-. -. . .]
[ -. -. . .]
[-. -. . .]
[-. -. . .]
[ -. -. . .]
[ -. -. . .]
[-. -. . .]]

特征图大小为60*40,所以会一共生成60*40*9=21600个Anchor box

源码中,通过width:(0~60)*16,height(0~40)*16建立shift偏移量数组,再和base_ancho基准坐标数组累加,得到特征图上所有像素对应的Anchors的坐标值,是一个[216000,4]的数组

(2.2)、RPN工作原理解析

为了进一步更清楚的看懂RPN的工作原理,将Caffe版本下的网络图贴出来,对照网络图进行讲解会更清楚

主要看上图中框住的‘RPN’部分的网络图,其中‘rpn_conv/3*3’是3*3的卷积,上面有提到过,接着是两个1*1的全卷积,分别是图中的‘rpn_cls_score’和‘rpn_bbox_pred’,在上面同样有提到过。接下来,分析网络图中其他各部分的含义

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

什么是IoU:

除了对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) 、rpn_loss_cls、rpn_loss_bbox、rpn_cls_prob

下面集体看下这三个,其中‘rpn_loss_cls’、‘rpn_loss_bbox’是分别对应softmax,smooth L1计算损失函数,‘rpn_cls_prob’计算概率值(可用于下一层的nms非最大值抑制操作)

补充:

①   Softmax公式,计算各分类的概率值

② Softmax Loss公式,RPN进行分类时,即寻找最小Loss值

在’rpn-data’中已经为预测框anchor box进行了标记,并且计算出与gt_boxes之间的偏移量,利用RPN网络进行训练。

RPN训练设置:在训练RPN时,一个Mini-batch是由一幅图像中任意选取的256个proposal组成的,其中正负样本的比例为1:1。如果正样本不足128,则多用一些负样本以满足有256个Proposal可以用于训练,反之亦然

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。

源码中,会重新生成60*40*9个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个

用下图一个案例来对NMS算法进行简单介绍

如上图所示,一共有6个识别为人的框,每一个框有一个置信率。 
现在需要消除多余的:

·    
按置信率排序: 0.95, 0.9, 0.9, 0.8, 0.7, 0.7

·    
取最大0.95的框为一个物体框

·    
剩余5个框中,去掉与0.95框重叠率IoU大于0.6(可以另行设置),则保留0.9, 0.8, 0.7三个框

·    
重复上面的步骤,直到没有框了,0.9为一个框

·    
选出来的为: 0.95, 0.9

所以,整个过程,可以用下图形象的表示出来

其中,红色的A框是生成的anchor
box,而蓝色的G’框就是经过RPN网络训练后得到的较精确的预测框,绿色的G是ground truth box

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层进行进一步的分类和定位.

3)ROI 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. }

从上述的Caffe代码中可以看到,输入的是RPN层产生的region proposal(假定有300个region proposal box)和VGG16最后一层产生的特征图(60*40 512-d),遍历每个region proposal,将其坐标值缩小16倍,这样就可以将在原图(1000*600)基础上产生的region proposal映射到60*40的特征图上,从而将在feature map上确定一个区域(定义为RB*)。

在feature map上确定的区域RB*,根据参数pooled_w:7,pooled_h:7,将这个RB*区域划分为7*7,即49个相同大小的小区域,对于每个小区域,使用max pooling方式从中选取最大的像素点作为输出,这样,就形成了一个7*7的feature map

细节可查看:https://www.cnblogs.com/wangyong/p/8523814.html

以此,参照上述方法,300个region proposal遍历完后,会产生很多个7*7大小的feature map,故而输出的数组是:[300,512,7,7],作为下一层的全连接的输入

4)、全连接层:

经过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后,通过全连接主要做了:

4.1)通过全连接和softmax对region proposals进行具体类别的分类

4.2)再次对region proposals进行bounding box regression,获取更高精度的rectangle box

作为一枚技术小白,写这篇笔记的时候参考了很多博客论文,在这里表示感谢,同时,未经同意,请勿转载....

Faster RCNN 学习笔记的更多相关文章

  1. Faster RCNN学习笔记

    感谢知乎大神的分享 https://zhuanlan.zhihu.com/p/31426458 Ross B. Girshick在2016年提出了新的Faster RCNN,在结构上,Faster R ...

  2. R-CNN学习笔记

    R-CNN学习笔记 step1:总览 步骤: 输入图片 先挑选大约2000个感兴趣区域(ROI)使用select search方法:[在输入的图像中寻找blobby regions(可能相同纹理,颜色 ...

  3. Faster RCNN 学习与实现

    论文 论文翻译 Faster R-CNN 主要分为两个部分: RPN(Region Proposal Network)生成高质量的 region proposal: Fast R-CNN 利用 reg ...

  4. Mask RCNN 学习笔记

    下面会介绍基于ResNet50的Mask RCNN网络,其中会涉及到RPN.FPN.ROIAlign以及分类.回归使用的损失函数等 介绍时所采用的MaskRCNN源码(python版本)来源于GitH ...

  5. Faster RCNN代码理解(Python)

    转自http://www.infocool.net/kb/Python/201611/209696.html#原文地址 第一步,准备 从train_faster_rcnn_alt_opt.py入: 初 ...

  6. [目标检测] 从 R-CNN 到 Faster R-CNN

    R-CNN 创新点 经典的目标检测算法使用滑动窗法依次判断所有可能的区域,提取人工设定的特征(HOG,SIFT).本文则预先提取一系列较可能是物体的候选区域,之后仅在这些候选区域上用深度网络提取特征, ...

  7. Faster R-CNN代码例子

    主要参考文章:1,从编程实现角度学习Faster R-CNN(附极简实现) 经常是做到一半发现收敛情况不理想,然后又回去看看这篇文章的细节. 另外两篇: 2,Faster R-CNN学习总结      ...

  8. 深度学习笔记之目标检测算法系列(包括RCNN、Fast RCNN、Faster RCNN和SSD)

    不多说,直接上干货! 本文一系列目标检测算法:RCNN, Fast RCNN, Faster RCNN代表当下目标检测的前沿水平,在github都给出了基于Caffe的源码. •   RCNN RCN ...

  9. 论文笔记:目标检测算法(R-CNN,Fast R-CNN,Faster R-CNN,FPN,YOLOv1-v3)

    R-CNN(Region-based CNN) motivation:之前的视觉任务大多数考虑使用SIFT和HOG特征,而近年来CNN和ImageNet的出现使得图像分类问题取得重大突破,那么这方面的 ...

随机推荐

  1. Spring Security(三十一):9.6 Localization(本地化)

    Spring Security supports localization of exception messages that end users are likely to see. If you ...

  2. 问题记录2019-03-06(todo)

    RuntimeError: maximum recursion depth exceeded while calling a Python object

  3. 【Topcoder 10689】TheSoccerDivOne

    题意:给\(n\)个队伍的积分,它们要踢足球,每个队伍剩下4场没有踢. 问踢完后\(0\)队伍最高排名. 思路:首先想了贪心,可惜不对. 那么老实dp. 首先:每个队伍具体和哪个人踢了没有关系. 那么 ...

  4. UIGestureRecognizer - BNR

    继续上篇UITouch - BNR.该篇将实现线条选择.移动和删除操作. UIGestureRecognizer有一系列子类,每一个子类都用于识别特定的手势.当识别出一个手势时,手势识别器会拦截视图的 ...

  5. .Net Core应用框架Util介绍(一)

    距离上次发文,已经过去了三年半,这几年技术更新节奏异常迅猛,.Net进入了跨平台时代,前端也被革命性的颠覆. 回顾 2015年,正当我还沉迷于JQuery + EasyUi的封装时,突然意识到技术已经 ...

  6. Scratch不仅适合小朋友,程序员和大学老师都应该广泛使用!!!

    去年接触到了Scratch这个编程工具,它是一种简易图形化编程工具,这个软件的开发团队来自于麻省理工大学称为“终身幼儿园团队”(Lifelong Kindergarten Group). 网址http ...

  7. C++ 中 auto 与 decltype 的用法与区别

    最近在恶补 C++ 知识的时候,学习到了一些 C++11 标准的新特性,利用这些新特性,我们能够更快地提高编程效率,从而实现我们的目标,在此特意记下学习过程中所学习到的一些东西,方便日后的回顾和复习. ...

  8. Python--day03(变量、数据类型、运算符)

    day02主要内容回顾 1.语言的分类 -- 机器语言:直接编写0,1指令,直接能被硬件执行 -- 汇编语言:编写助记符(与指令的对应关系),找到对应的指令直接交给硬件执行 -- 高级语言:编写人能识 ...

  9. mpvue-Vant Weapp踩坑记

    微信开发者工具:开发.调试和模拟运行微信小程序的最核心的工具了,所以必须安装 # 全局安装 vue-cli $ npm install --global vue-cli # 创建一个基于 mpvue- ...

  10. Python——电子邮件、Internet协议相关模块

    一.电子邮件相关模块 email:用于处理电子邮件 smtpd:SMTP服务器 base64:Base-16.32.64数据编码 mhlib:处理MH文件格式解析的类 mailcap:mailcap文 ...