之前的文章简要介绍了Faster-RCNN等物体检测的算法,本文将从代码角度详细分析介绍Faster-RCNN的实现。本文使用的代码参考了chenyuntc的实现,代码的位置看这里。需要注意的是,本文使用的框架是Pytorch。

数据载入

数据载入部分的代码主要见./data/dataset.py中的类DatasetTestDataset

数据载入部分的逻辑如下:

  1. 从VOC数据集中获得img, bbox, label
  2. img, bbox进行放缩(放缩的目的是让图片处于合适的大小,这样预先指定锚框才有意义)
  3. img进行标准化正则处理
  4. 如果是训练阶段,将img翻转以增加训练数据

网络结构

FasterRCNN的网络结构如下图所示:

FasterRCNN结构的代码主要见./model.faster_rcnn.py,其结构包含三大部分:

  1. 预训练的CNN模型 decom_vgg16
  2. rpn网络RegionProposalNetwork
  3. roi及以上网络VGG16RoIHead

下面,将以放缩后大小为[1, 3, 600, 800]的图片为例针对每个部分分别介绍。图像类别共计21类(包含背景)。

预训练的CNN模型

该部分代码见./model/vgg16.py

输入:图片,大小[1, 3, 600, 800] 

输出:特征图features,大小[1, 512, 37, 50]


其逻辑如下:

  1. 载入预先训练好的CNN模型VGG16。
  2. 将模型拆分为两部分extractorclassifier。其中,extractor的参数固定。
  3. 图片通过extractor可以得到特征图features。根据extractor中池化参数可知图像通过extractor缩小了16倍。

rpn网络

该部分代码见./model/rpn.py

输入:特征图features,大小[1, 512, 37, 50] 

输出:

  • rpn_locs:rpn对位置的修正,大小[1, 16650, 4]
  • rpn_scores :rpn判断区域前景背景,大小[1, 16650, 2]
  • rois:rpn筛选出的roi的位置,大小[300, 4]
  • roi_indices:rpn筛选出的roi对应的图片索引,大小[300]
  • anchor:原图像的锚点,大小[16650, 4]

其中,16650是放缩后的图像所产生的所有锚点(37*50*9),每个锚点都对应了一个rp。通过 rpn_scores以及nms可以得到筛选后的大小为300的roi。


其逻辑如下:

  1. 对特征图features以基准长度为16、选择合适的ratiosscales取基准锚点anchor_base。(选择长度为16的原因是图片大小为600*800左右,基准长度16对应的原图区域是256*256,考虑放缩后的大小有128*128,512*512比较合适)
  2. 根据anchor_base在原图上获得anchors
  3. 对特征图features采用卷积得到rpn_locsrpn_scores
  4. 根据anchorsrpn_locs获得修正后的rp
  5. rp进一步修正获得roisroi_indices,修正包括超出边界的部分截断、移除太小的、nms。

roi及以上网络

该部分代码见./model/roi_module.py

输入:

  • features:特征图,大小[1, 512, 37, 50]
  • rois:rpn筛选出的roi的位置,大小[300, 4]
  • roi_indices:rpn筛选出的roi对应的图片索引,大小[300]

输出:

  • roi_cls_locsroi位置的修正,大小[300, 84]
  • roi_scoresroi各类的分数,大小[300, 21]

其逻辑如下:

  1. 通过RoIPooling2D将大小不同的roi变成大小一致,得到pooling后的特征,大小为[300, 512, 7, 7]
  2. 接入预训练的CNN模型引入的classifier
  3. 分别接入全连接得到roi_cls_locsroi_scores

训练

训练部分的代码主要见./trainer/trainer.py中的FasterRCNNTrainer中的train_step函数。

训练部分的核心是loss如何求取。

loss求取前网络的步骤如下:

  1. 预训练CNN特征提取:输入imgextractor获得features
  2. rpn网络得到roi:输入featuresrpn获得rpn_locsrpn_scoresroisroi_indicesanchor
  3. 抽样roi:输入roisbboxlabelProposalTargetCreator获得sample_roigt_roi_locgt_roi_label。该步骤的含义是得到正负例比例和位置合适的roi
  4. head网络得到roi的位置修正与分数:输入features,sample_roi,sample_roi_index得到roi_cls_locroi_score

各个loss求取的方式如下:

  1. rpn_loc_loss:已知rpn_loc,需要先根据anchorbbox得到真实的gt_rpn_locgt_rpn_label。该处loss的计算只考虑前景,所以根据rpn_loc,gt_rpn_loc,gt_rpn_label计算L1-LOSS即可。
  2. rpn_cls_loss:根据rpn_scoregt_rpn_label计算二分类的交叉熵即可。
  3. roi_loc_loss:已知roi_loc,在sample roi的过程中已获得gt_roi_locgt_roi_label。根据roi_loc,gt_roi_loc,gt_roi_label计算L1-LOSS即可。
  4. roi_cls_loss:根据roi_scoregt_roi_label计算多分类的交叉熵即可。

整体的loss为以上各loss相加求和。

测试

训练部分的代码主要见./model/faster_rcnn.py中的FasterRCNNTrainer中的predict函数。

其步骤如下:

  1. 图片预处理
  2. 预训练CNN特征提取:输入imgextractor获得features
  3. rpn网络得到roi:输入featuresrpn获得rpn_locsrpn_scoresroisroi_indicesanchor
  4. head网络得到roi的位置修正与分数:输入features,rois,roi_indices得到roi_cls_locroi_score
  5. 得到图片预测的bbox:输入roi_cls_locroi_scorerois,采用nms等方法得到预测的bbox

FasterRCNN代码解读的更多相关文章

  1. Android MVP模式 谷歌官方代码解读

    Google官方MVP Sample代码解读 关于Android程序的构架, 当前(2016.10)最流行的模式即为MVP模式, Google官方提供了Sample代码来展示这种模式的用法. Repo ...

  2. 优秀开源代码解读之JS与iOS Native Code互调的优雅实现方案

    简介 本篇为大家介绍一个优秀的开源小项目:WebViewJavascriptBridge. 它优雅地实现了在使用UIWebView时JS与ios 的ObjC nativecode之间的互调,支持消息发 ...

  3. SoftmaxLayer and SoftmaxwithLossLayer 代码解读

    SoftmaxLayer and SoftmaxwithLossLayer 代码解读 Wang Xiao 先来看看 SoftmaxWithLoss 在prototext文件中的定义: layer { ...

  4. Hybrid----优秀开源代码解读之JS与iOS Native Code互调的优雅实现方案-备

    本篇为大家介绍一个优秀的开源小项目:WebViewJavascriptBridge. 它优雅地实现了在使用UIWebView时JS与ios 的ObjC nativecode之间的互调,支持消息发送.接 ...

  5. Jsoup代码解读之六-防御XSS攻击

    Jsoup代码解读之八-防御XSS攻击 防御XSS攻击的一般原理 cleaner是Jsoup的重要功能之一,我们常用它来进行富文本输入中的XSS防御. 我们知道,XSS攻击的一般方式是,通过在页面输入 ...

  6. Jsoup代码解读之五-实现一个CSS Selector

    Jsoup代码解读之七-实现一个CSS Selector 当当当!终于来到了Jsoup的特色:CSS Selector部分.selector也是我写的爬虫框架webmagic开发的一个重点.附上一张s ...

  7. Jsoup代码解读之四-parser

    Jsoup代码解读之四-parser 作为Java世界最好的HTML 解析库,Jsoup的parser实现非常具有代表性.这部分也是Jsoup最复杂的部分,需要一些数据结构.状态机乃至编译器的知识.好 ...

  8. Jsoup代码解读之三-Document的输出

    Jsoup代码解读之三-Document的输出   Jsoup官方说明里,一个重要的功能就是output tidy HTML.这里我们看看Jsoup是如何输出HTML的. HTML相关知识 分析代码前 ...

  9. Jsoup代码解读之一-概述

    Jsoup代码解读之一-概述 今天看到一个用python写的抽取正文的东东,美滋滋的用Java实现了一番,放到了webmagic里,然后发现Jsoup里已经有了…觉得自己各种不靠谱啊!算了,静下心来学 ...

随机推荐

  1. LeetCode(104):二叉树的最大深度

    Easy! 题目描述: 给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例:给定二叉树 [3,9,20,null, ...

  2. java和python对比----1:

    对计算来说: java 除法: 3/4 ==0; pyhton 除法: 3/4 ==0 3//4==0.75

  3. MySQL数据库权限分类

    一.权限表 mysql数据库中的3个权限表:user .db. host 权限表的存取过程是: 1)先从user表中的host. user. password这3个字段中判断连接的IP.用户名.密码是 ...

  4. Gson将字符串转map时,int默认为double类型

      gson能够将json字符串转换成map, 但是在转成map时, 会默认将字符串中的int , long型的数字, 转换成double类型 , 数字会多一个小数点 , 如 1 会转成 1.0 Gs ...

  5. jmeter IP欺骗功能

    使用过loadrunner的同学,应该都了解有个IP欺骗功能,jmeter遇到类似需求怎样实现呢? 环境:windows7,jdk1.8,jmeter3.1 使用IP欺骗功能前提是本地有多个可用IP, ...

  6. Python数据分析几个比较常用的方法

    1,表头或是excel的索引如果是中文的话,输出会出错 ​​解决方法:python的版本问题!换成python3就自动解决了!当然也有其他的方法,这里就不再深究 2,如果有很多列,如何输出指定的列? ...

  7. gradle repo conf - maven-central.storage-download.googleapis.com

    repositories { google() jcenter() maven { // The google mirror is less flaky than mavenCentral() url ...

  8. Android Https双向认证 + GRPC

    keywords:android https 双向认证android GRPC https 双向认证 ManagedChannel channel = OkHttpChannelBuilder.for ...

  9. C# float与UInt16互转

    //float拆分成两个UInt16 public static UInt16 FloatToTwoUInt16(float f) { byte[] bs = BitConvert.GetBytes( ...

  10. [转] jQuery的deferred对象详解

    jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...