Paper:Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks

1.整体网络结构


faster rcnn是继RCNN,fast RCNN之后又一新作,是何凯明等大神在2015年提出目标检测算法,该算法在2015年的ILSVRV和COCO竞赛中获得多项第一,该算法是目标检测领域的经典算法,值得反复研读;
Faster Rcnn相关链接:
目标检测之正负样本详解
困难样本挖掘
目标检测 — Anchor的生成
Faster_Rcnn误检解决方案—强制负样本策略

2.几大核心部件

Faster R-CNN的结构主要分为四大部分,
第一部分是特征提取部分,包括backbone和neck,用于提取特征。
第二部分是候选区域生成网络-RPN
第三部分是对RPN选取的候选框进行映射的RoI Pooling
第四部分是对候选区域进行分类回归的网络头

2.1 特征提取

  • 特征提取和常规的检测算法类似,BackBone可以选择VGG、Resnet以及一些轻量级的网络,如Mobilenet、ShulffeNet、Xception等,具体选择参考实际部署的算力和精度需求;Neck部分可以选择输出单层,也可以考虑引入FPN输出多层;

2.2 RPN(Region Proposal Networks)

概述:

  • RPN的作用:给定一张输入image找出objects可能存在的所有位置。这一阶段的输出应该是一系列object可能位置的bounding
    box。这些通常称之为region proposals或者 regions of interest(ROI);故,RPN
    网络是解决region proposal的问题,输入是一副图像的特征图,输出是region proposal。
  • RPN 是Faster Rcnn的一大创新,主要用于改进是候选框的生成方式,不再依赖于外部区域建议算法;
  • 可以理解为RPN是一个卷积层**(3x3x256维)+ relu + 左右两个1x1卷积层的(cls layer 和 reg layer)**的小网络, 应用在特征图上【滑动窗口区域上】。
  • 在特征图的每一个位置【像素】,我们设置k(9)个不同长宽比例、不同面积的anchor【锚定框】,通过这些anchor逆向推导出它所对应的原始图片中的一个区域,这个区域的尺寸以及坐标都是已知的,而这个区域,就是我们想要的proposal。
  • 对于每个anchor,RPN预测两件事情:第一个是一个锚定框是某个目标的概率(不考虑目标属于哪个类别,只有前景和背景),对应于cls layer,其输出的维度2k;第二个是用于调整锚定框以更好地适合目标的边界框回归器(使得这个anchor box 修正后与 groud truth 的位置尽可能重叠度越高),对应于reg layer其输出的维度4k,表示每个 anchor box对应的4个值,分别表征anchor对 groud truth 的长宽与x、y坐标的预测(偏移量)。

RPN输出region proposal的过程

  • RPN设置的目的是用于为后续的RCNN提供region proposal,其流程大致如下:

1.假设经过3x3卷积层后得到特征图大小40×60,共2400个点,每个点对应到输入分辨率上设置9个anchor,所以一共可以得到40×60×9大约20000个候选区域,通过1-1的cls layer计算得到所有候选区域预测的scores;
2.根据预测得到的scores对候选区域进行排序,选取score最大的前12000个候选区域;
3.通过非极大值抑制【nms】,设置IOU阈值为0.7,对步骤2筛选的候选区域进一步处理;再在剩余的候选区域中选出score最大的前2000个候选区域
【以上是候选区域选取的大致流程,实际网络结构的不同,如fpn的引入,可能会有一些额外的操作】
【最终输出到rcnn阶段的候选区域数量最多为2000【有可能少】,输出的结果为各候选区域在输入分辨率上的坐标】

以上超参数的设置可以进行调整

    rpn_proposal=dict(nms_across_levels=False,nms_pre=12000, #nms前根据score选取的候选区域数量nms_post=2000,  #nms之后选取的候选区域数量max_num=2000,   #最终选取的最大候选区域数量nms_thr=0.7,   #nms操作的阈值min_bbox_size=0),

基于python实现候选区域的生成过程,其代码如下:

    def get_bboxes_(self,cls_scores,bbox_preds,mlvl_anchors,img_shape,scale_factor,cfg,rescale=False):mlvl_proposals = []for idx in range(len(cls_scores)):#遍历特征图的各层[主要考虑fpn等多层输出的结构]rpn_cls_score = cls_scores[idx]#cls layer预测的scoresrpn_bbox_pred = bbox_preds[idx]#reg layer预测的bboxassert rpn_cls_score.size()[-2:] == rpn_bbox_pred.size()[-2:]rpn_cls_score = rpn_cls_score.permute(1, 2, 0)if self.use_sigmoid_cls:rpn_cls_score = rpn_cls_score.reshape(-1)scores = rpn_cls_score.sigmoid()else:rpn_cls_score = rpn_cls_score.reshape(-1, 2)scores = rpn_cls_score.softmax(dim=1)[:, 1]rpn_bbox_pred = rpn_bbox_pred.permute(1, 2, 0).reshape(-1, 4)anchors = mlvl_anchors[idx]#预先设置的anchor坐标if cfg.nms_pre > 0 and scores.shape[0] > cfg.nms_pre:_, topk_inds = scores.topk(cfg.nms_pre)  #12000rpn_bbox_pred = rpn_bbox_pred[topk_inds, :]anchors = anchors[topk_inds, :]scores = scores[topk_inds]proposals = delta2bbox(anchors, rpn_bbox_pred, self.target_means,self.target_stds, img_shape) #映射到训练分辨率的大小上if cfg.min_bbox_size > 0:#对小于特定尺寸的框进行过滤{默认设置为0}w = proposals[:, 2] - proposals[:, 0] + 1h = proposals[:, 3] - proposals[:, 1] + 1valid_inds = torch.nonzero((w >= cfg.min_bbox_size) &(h >= cfg.min_bbox_size)).squeeze()proposals = proposals[valid_inds, :]scores = scores[valid_inds]proposals = torch.cat([proposals, scores.unsqueeze(-1)], dim=-1)proposals, _ = nms(proposals, cfg.nms_thr) #nms操作proposals = proposals[:cfg.nms_post, :] # 2000mlvl_proposals.append(proposals)proposals = torch.cat(mlvl_proposals, 0)if cfg.nms_across_levels:#对于fpn结构,是否将多层的框放到一起进行nms操作proposals, _ = nms(proposals, cfg.nms_thr)# proposals = proposals[:cfg.max_num, :]scores = proposals[:, 4]num = min(cfg.max_num, proposals.shape[0])_, topk_inds = scores.topk(num)proposals = proposals[topk_inds, :]else:scores = proposals[:, 4]num = min(cfg.max_num, proposals.shape[0])#cfg.max_num=2000_, topk_inds = scores.topk(num)proposals = proposals[topk_inds, :]return proposals #返回得到的bbox坐标也是相对于输入[训练]分辨率

RPN的训练过程:

1.假设经过3*3卷积层后得到特征图大小40×60,共2400个点,每个点对应到输入分辨率上设置9个anchor,所以一共可以得到40×60×9大约20000个候选区域;
2.对生成的候选区域进行初步过滤:丢掉部分超出图像边缘过多的候选区域
3.对筛选完的候选区域进一步处理:如果候选区域与某个标定区城【ground truth】重叠比例大于0.7,记为正样本,如果与任意一个标定区城重叠比例都小于0.3,记为负样本。其余区城不作为样本。
4.我们会随机地抽取256个区城来训练(正、负样本中各抽128),正负候选区城比例为1:1,如采正样本数小于128,用负样本填充。正样本的数量一般不够,往往需要负样本来进行填充,负样本的数量往往很多远远超过128,此时负样本的选取可以采取一些策略,如在线困难样例挖掘,使得网络更加关注于困难负样本的学习;
【关于正负样本的定义和筛选参考:目标检测之正负样本详解】
5.计算正样本和标定区城【ground truth】的偏差【相对值】,生成正样本的位置标签【负样本只有类别标签没有位置标签】;根据网络的预测值和标签进行模型参数的迭代

以上训练过程的超参数都可以进行调整

rpn=dict(assigner=dict(type='MaxIoUAssigner',pos_iou_thr=0.7, #正样本阈值neg_iou_thr=0.3, #负样本阈值min_pos_iou=0.2, #最小正样本阈值ignore_iof_thr=0.3),sampler=dict(type='RandomSampler',num=256, #用于训练的正负样本总数pos_fraction=0.5,  #用于训练的正样本比例neg_pos_ub=-1,add_gt_as_proposals=False),),allowed_border=128,#允许超过的最大边界像素

2.3 RoI Pooling/RoI Align


RoI Pooling
作用:
主要完成两件事:
第一件是为每个RoI选取对应的特征(从输入分辨率区域映射到ROI特征层区域)
第二件事是为了满足全连接层的输入需求,将每个RoI对应的特征的维度转化成某个定值(输出固定大小的特征图,如7-7-512)

RoI Pooling的输入输出
-输入:RPN输出的候选区域【RoI】以及对应的RoI Feature Map

RoI Feature Map可以和RPN共享同一个特征图也可以是在RPN基础进一步处理得到的特征图

  • 输出:各候选区域对应的且大小固定的特征图

ROI pooling具体操作

1.根据输入image,将ROI映射到RoI Feature Map对应位置;
2.将映射后的区域划分为相同大小的sections(sections数量与输出的维度相同,如7);
3.对每个sections进行max pooling操作;

这样我们就可以从不同大小的方框得到固定大小的相应 的feature maps。需要注意的是,输出的feature maps的大小不取决于ROI和feature maps大小;Roi Pooling并没有改变通道数量,因此输出的通道数仍然等于输入的通道数
Roi Pooling操作示例:假设有一个88大小的feature map和一个ROI,要求输出大小为22的特征图,其流程如下:.

RoI Align
在Faster-RCNN中,ROI Pooling的作用是根据预选框的位置坐标在特征图中将相应区域池化为固定尺寸的特征图,以便进行后续的分类和候选框回归操作;但是由于候选框的位置通常是由模型回归得到的,一般来讲是浮点数(小数),而像素都为整数且池化后的特征图要求尺寸固定。故ROI Pooling这一操作存在两次量化的过程:

1.将候选框边界量化为特征图上的整数点坐标值。
2.将量化后的边界区域平均分割成kxk个单元(bin),对每一个单元的边界进行量化

举例说明:

如上图所示:卷积网络实现对原图的32倍下采样。假定原图中有一region proposal,大小为665x665,映射到特征图中的大小:665/32=20.78,即20.78x20.78,由于像素为整数,RoiPool在计算的时候会进行取整操作,于是,进行所谓的第一次量化,即映射的特征图大小为20x20;假定pooling后固定成7x7大小的特征图,所以将上面在 feature map上映射的20x20的 region proposal划分成49个同等大小的小区域,每个小区域的大小20/7=2.86(Rol bin)即2.86x2.86,此时,进行第二次量化,故小区域大小变成2x2(Rol bin),原本在特征图上映射的20x20大小的region proposal,偏差成大小为14x14的,对应到原图的偏差(2.86-2)x32=27.52

两次量化引入了Rol和提取特征之间的非对准;这种误差对于分类任务的影响可能不大,但对于定位和像素级的任务影响不可忽略

RoiAlign和Roipooling的目的是一样的,但为了消除量化误差,其实现的方式有所区别:取消量化操作,使用双线性插值法的方法获得坐标为浮点数的像素点上的图像数值:

针对上图,映射得到特征图中的大小:665/32=20.78,即20.78x20.78,此时,RoiAlign没有像RoiPooling那样就行取整操作,而是保留浮点数; pooling后固定成7x7大小的特征图,所以,将在 feature map上映射的20.78x20.78的region proposal 划分成49个同等大小的小区域,每个小区域的大小20.78/7=2.97,即2.97x2.97(Rol bin,不取整),对于每个2.97x2.97的小区域,平分四份,每一份取其中心点位置,而中心点位置的像素,采用双线性插值法进行计算,这样,就会得到四个点的像素值,如下图,最后采用最大值池化或平均池化得到一个7x7的特征图。

RoiAlign将计算得到的每个Rol bin分成四份,如上图四个红色叉叉‘×’所示,该点我们称为原图中虚拟点(又称双线性插值的网格点,比如20.56这个浮点数);其值由其四周的最近的四个真实存在的像素值通过双线性插值的方式计算得到,(比如(20.56,20.56)是根据(20,20)(20,21)(21,20)(21,21)四个点的像素求出),然后对求得的四个值进行max pooling操作,获得每一个Rol bin的输出结果;整个过程中没有用到量化操作,没有引入误差,即原图中的像素和feature map中的像素是完全对齐的,没有偏差。

3.算法的优缺点

Faster Rcnn作为一种经典的Two-Stage算法,已经在学术界和工业界得到了广泛的应用,其精度也得到了证明,其优点主要包括以下几点:

1.模型精度较高:存在两次的定位调整,坐标值的预测更加精细化
2.正负样本的比例控制的好;输入rpn会生成很多的正负样本,但真正用于训练的正负样本数量却并不多,且比例控制的很好
3.RPN阶段会生成很多的先验框,模型训练前期变相的增加的很多随机裁剪的目标,相对于加入了一种额外的数据增强方式

缺点:

1.相对one-stage系列的算法而言,速度要慢一些
2.背景误检率高;只有部分负样本用于训练,背景的学习相对来说不是很充分

关于Faster Rcnn的一些理解相关推荐

  1. faster rcnn源码理解(二)之AnchorTargetLayer(网络中的rpn_data)

    转载自:faster rcnn源码理解(二)之AnchorTargetLayer(网络中的rpn_data) - 野孩子的专栏 - 博客频道 - CSDN.NET http://blog.csdn.n ...

  2. 深度学习目标检测模型全面综述:Faster R-CNN、R-FCN和SSD

    为什么80%的码农都做不了架构师?>>>    Faster R-CNN.R-FCN 和 SSD 是三种目前最优且应用最广泛的目标检测模型,其他流行的模型通常与这三者类似.本文介绍了 ...

  3. 目标检测——从RCNN到Faster RCNN 串烧

    目标检测--从RCNN到Faster RCNN 串烧 https://blog.csdn.net/xyy19920105/article/details/50817725 本人小硕一枚,方向是深度学习 ...

  4. 人工智能学习07--pytorch10--目标检测:RCNN、Fast RCNN、Faster RCNN

    括号里都是弹幕大佬的高赞发言 1 前言 Two Stage检测过程分两步走 前景:需要检测的目标 背景:不感兴趣的 生成候选框:将感兴趣目标框选出来,但是没有进行分类 具体使用哪一种,根据项目需求 自 ...

  5. 你真的理解Faster RCNN吗?捋一捋Pytorch官方Faster RCNN代码

    作者丨白裳@知乎 来源丨https://zhuanlan.zhihu.com/p/145842317 编辑丨极市平台 目前 pytorch 已经在 torchvision 模块集成了 FasterRC ...

  6. faster rcnn的源码理解(一)SmoothL1LossLayer论文与代码的结合理解

    转载自:faster rcnn的源码理解(一)SmoothL1LossLayer论文与代码的结合理解 - 野孩子的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/u ...

  7. Faster RCNN代码理解(Python) ---训练过程

    最近开始学习深度学习,看了下Faster RCNN的代码,在学习的过程中也查阅了很多其他人写的博客,得到了很大的帮助,所以也打算把自己一些粗浅的理解记录下来,一是记录下自己的菜鸟学习之路,方便自己过后 ...

  8. faster rcnn resnet_RCNN, Fast R-CNN 与 Faster RCNN理解及改进方法

    RCNN 这个网络也是目标检测的鼻祖了.其原理非常简单,主要通过提取多个Region Proposal(候选区域)来判断位置,作者认为以往的对每个滑动窗口进行检测算法是一种浪费资源的方式.在RCNN中 ...

  9. 收藏 | 万字长文带你理解Pytorch官方Faster RCNN代码

    点上方蓝字计算机视觉联盟获取更多干货 在右上方 ··· 设为星标 ★,与你不见不散 仅作学术分享,不代表本公众号立场,侵权联系删除 转载于:作者丨白裳@知乎 来源丨https://zhuanlan.z ...

  10. (转)Faster R-CNN的训练过程的理解

    转载链接:http://blog.csdn.net/weixin_40449426/article/details/78141635 我才刚刚学习Faster R-CNN,看了好多博客,觉得对知识点讲 ...

最新文章

  1. poj 3984 迷宫问题 BFS
  2. 用matlab仿真函数在空间分布,1.3 信道函数免费阅读_MATLAB R2016a通信系统建模与仿真28个案例分析免费全文_百度阅读...
  3. 11无监听程序_腾讯开心鼠英语 小程序实践与总结
  4. Re:从零开始的Spring Session(二)
  5. 并发服务器设计思路,参考apache学习UDP和QoS,研究成果
  6. mysql查看版本号_十分钟了解MySQL事务机制
  7. Codevs 1025 选菜
  8. 华为的鸿蒙系统和苹果的操作系统有什么区别?
  9. 诸事不顺--今日宜睡大觉
  10. Java中Collection接口
  11. 汉字在字库中的偏移地址计算
  12. flashfxp安装,8步完成flashfxp安装
  13. Excel-几行几行进行转置
  14. win10隐藏输入法指示器的设置方法
  15. linux下的orre命令,鳥哥的 Linux 私房菜
  16. 数据湖:数据同步工具NiFi
  17. 星起航:抖音小店体验分低怎么办,如何提高店铺体验评分?
  18. 如何用python画出一般函数图_python如何画函数图像
  19. 对浏览器内核的理解和常见的浏览器内核
  20. 经典PID在智能自寻迹小车中的应用分析

热门文章

  1. CMMI4过程域之“需求管理”
  2. 点分十进制IP和网络字节序IP互转
  3. laravel中数据显示(默认值和下拉option默认选中)
  4. jdk动态代理使用详解
  5. Java 大白话讲解设计模式之 -- 建造者(Builder)模式
  6. Centos7 搭建 Socks 服务
  7. matlab 求解发动机换算转速,简单一个公式,教你用发动机转速计算车速!
  8. 创建美区苹果账户ID
  9. python如何安装numpy模块?
  10. 文献笔记(7)(2017ISSCC 14.3)