FasterRCNN代码解读
之前的文章简要介绍了Faster-RCNN等物体检测的算法,本文将从代码角度详细分析介绍Faster-RCNN的实现。本文使用的代码参考了chenyuntc的实现,代码的位置看这里。需要注意的是,本文使用的框架是Pytorch。
数据载入
数据载入部分的代码主要见./data/dataset.py
中的类Dataset
与TestDataset
。
数据载入部分的逻辑如下:
- 从VOC数据集中获得
img, bbox, label
- 将
img, bbox
进行放缩(放缩的目的是让图片处于合适的大小,这样预先指定锚框才有意义) - 将
img
进行标准化正则处理 - 如果是训练阶段,将
img
翻转以增加训练数据
网络结构
FasterRCNN的网络结构如下图所示:
FasterRCNN结构的代码主要见./model.faster_rcnn.py
,其结构包含三大部分:
- 预训练的CNN模型
decom_vgg16
- rpn网络
RegionProposalNetwork
- roi及以上网络
VGG16RoIHead
下面,将以放缩后大小为[1, 3, 600, 800]
的图片为例针对每个部分分别介绍。图像类别共计21类(包含背景)。
预训练的CNN模型
该部分代码见./model/vgg16.py
。
输入:图片,大小[1, 3, 600, 800]
输出:特征图features
,大小[1, 512, 37, 50]
其逻辑如下:
- 载入预先训练好的CNN模型VGG16。
- 将模型拆分为两部分
extractor
,classifier
。其中,extractor
的参数固定。 - 图片通过
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。
其逻辑如下:
- 对特征图
features
以基准长度为16、选择合适的ratios
和scales
取基准锚点anchor_base
。(选择长度为16的原因是图片大小为600*800左右,基准长度16对应的原图区域是256*256,考虑放缩后的大小有128*128,512*512比较合适) - 根据
anchor_base
在原图上获得anchors
。 - 对特征图
features
采用卷积得到rpn_locs
和rpn_scores
- 根据
anchors
和rpn_locs
获得修正后的rp
- 对
rp
进一步修正获得rois
和roi_indices
,修正包括超出边界的部分截断、移除太小的、nms。
roi及以上网络
该部分代码见./model/roi_module.py
。
输入:
features
:特征图,大小[1, 512, 37, 50]
rois
:rpn筛选出的roi的位置,大小[300, 4]
roi_indices
:rpn筛选出的roi对应的图片索引,大小[300]
输出:
roi_cls_locs
:roi
位置的修正,大小[300, 84]
roi_scores
:roi
各类的分数,大小[300, 21]
其逻辑如下:
- 通过
RoIPooling2D
将大小不同的roi
变成大小一致,得到pooling后的特征,大小为[300, 512, 7, 7]
- 接入预训练的CNN模型引入的
classifier
- 分别接入全连接得到
roi_cls_locs
、roi_scores
训练
训练部分的代码主要见./trainer/trainer.py
中的FasterRCNNTrainer
中的train_step
函数。
训练部分的核心是loss如何求取。
loss求取前网络的步骤如下:
- 预训练CNN特征提取:输入
img
到extractor
获得features
- rpn网络得到roi:输入
features
到rpn
获得rpn_locs
,rpn_scores
,rois
,roi_indices
,anchor
- 抽样roi:输入
rois
,bbox
,label
到ProposalTargetCreator
获得sample_roi
,gt_roi_loc
,gt_roi_label
。该步骤的含义是得到正负例比例和位置合适的roi
。 - head网络得到roi的位置修正与分数:输入
features
,sample_roi
,sample_roi_index
得到roi_cls_loc
,roi_score
各个loss求取的方式如下:
rpn_loc_loss
:已知rpn_loc
,需要先根据anchor
和bbox
得到真实的gt_rpn_loc
和gt_rpn_label
。该处loss的计算只考虑前景,所以根据rpn_loc
,gt_rpn_loc
,gt_rpn_label
计算L1-LOSS即可。rpn_cls_loss
:根据rpn_score
和gt_rpn_label
计算二分类的交叉熵即可。roi_loc_loss
:已知roi_loc
,在sample roi的过程中已获得gt_roi_loc
,gt_roi_label
。根据roi_loc
,gt_roi_loc
,gt_roi_label
计算L1-LOSS即可。roi_cls_loss
:根据roi_score
和gt_roi_label
计算多分类的交叉熵即可。
整体的loss为以上各loss相加求和。
测试
训练部分的代码主要见./model/faster_rcnn.py
中的FasterRCNNTrainer
中的predict
函数。
其步骤如下:
- 图片预处理
- 预训练CNN特征提取:输入
img
到extractor
获得features
- rpn网络得到roi:输入
features
到rpn
获得rpn_locs
,rpn_scores
,rois
,roi_indices
,anchor
- head网络得到roi的位置修正与分数:输入
features
,rois
,roi_indices
得到roi_cls_loc
,roi_score
- 得到图片预测的bbox:输入
roi_cls_loc
、roi_score
、rois
,采用nms等方法得到预测的bbox
。
FasterRCNN代码解读的更多相关文章
- Android MVP模式 谷歌官方代码解读
Google官方MVP Sample代码解读 关于Android程序的构架, 当前(2016.10)最流行的模式即为MVP模式, Google官方提供了Sample代码来展示这种模式的用法. Repo ...
- 优秀开源代码解读之JS与iOS Native Code互调的优雅实现方案
简介 本篇为大家介绍一个优秀的开源小项目:WebViewJavascriptBridge. 它优雅地实现了在使用UIWebView时JS与ios 的ObjC nativecode之间的互调,支持消息发 ...
- SoftmaxLayer and SoftmaxwithLossLayer 代码解读
SoftmaxLayer and SoftmaxwithLossLayer 代码解读 Wang Xiao 先来看看 SoftmaxWithLoss 在prototext文件中的定义: layer { ...
- Hybrid----优秀开源代码解读之JS与iOS Native Code互调的优雅实现方案-备
本篇为大家介绍一个优秀的开源小项目:WebViewJavascriptBridge. 它优雅地实现了在使用UIWebView时JS与ios 的ObjC nativecode之间的互调,支持消息发送.接 ...
- Jsoup代码解读之六-防御XSS攻击
Jsoup代码解读之八-防御XSS攻击 防御XSS攻击的一般原理 cleaner是Jsoup的重要功能之一,我们常用它来进行富文本输入中的XSS防御. 我们知道,XSS攻击的一般方式是,通过在页面输入 ...
- Jsoup代码解读之五-实现一个CSS Selector
Jsoup代码解读之七-实现一个CSS Selector 当当当!终于来到了Jsoup的特色:CSS Selector部分.selector也是我写的爬虫框架webmagic开发的一个重点.附上一张s ...
- Jsoup代码解读之四-parser
Jsoup代码解读之四-parser 作为Java世界最好的HTML 解析库,Jsoup的parser实现非常具有代表性.这部分也是Jsoup最复杂的部分,需要一些数据结构.状态机乃至编译器的知识.好 ...
- Jsoup代码解读之三-Document的输出
Jsoup代码解读之三-Document的输出 Jsoup官方说明里,一个重要的功能就是output tidy HTML.这里我们看看Jsoup是如何输出HTML的. HTML相关知识 分析代码前 ...
- Jsoup代码解读之一-概述
Jsoup代码解读之一-概述 今天看到一个用python写的抽取正文的东东,美滋滋的用Java实现了一番,放到了webmagic里,然后发现Jsoup里已经有了…觉得自己各种不靠谱啊!算了,静下心来学 ...
随机推荐
- dubbo源码之服务发布与注册
服务端发布流程: dubbo 是基于 spring 配置来实现服务的发布的,对于dubbo 配置文件中看到的<dubbo:service>等标签都是服务发布的重要配置 ,对于这些提供可配置 ...
- 《剑指offer》 链表中倒数第k个节点
本题来自<剑指offer> 链表中倒数第k个节点 题目: 输入一个链表,输出该链表中倒数第k个结点. 思路: 倒数第k个节点,而且只能访问一遍链表,定义两个节点,两者之间相差k个距离,遍历 ...
- Django注册页面配置设计
一.上次回顾 Django数据的增查改删 models 中有userInfo 三个字段 user password phonenumber,models.userInfo.objects.all(). ...
- Python操作MySQL案例
最近都在学习Python代码,希望学会Python后,能给我带来更高的工作效率,所以每天坚持学习和拷代码,下面是一个Python操作MySQL的一个实例,该实例可以让更多的人更好了解MySQLdb模块 ...
- Python随手记—各种方法的使用
os.popen()方法的使用 os.popen()方法用于从一个命令打开一个管道. 语法:os.popen(command[, mode[, bufsize]]) 其中 command是使用的 ...
- python虚拟环境搭建
1.安装python环境 2.检查pip 3.pip install virtualenv 4.创建测试:virtualenv testvir 5.pip install virtualenvwra ...
- Html 文字排版
文字竖立排版,方法一 @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="v ...
- JavaScript学习:取数组中最大值和最小值
在实际业务中有的时候要取出数组中的最大值或最小值.但在数组中并没有提供arr.max()和arr.min()这样的方法.那么是不是可以通过别的方式实现类似这样的方法呢?那么今天我们就来整理取出数组中最 ...
- javascript数组(五)
一.创建数组.数组操作 数组是指的有序集合.每个值叫做元素,每个元素,每个元素在数组中都有梳子位置编号,也就是索引.JS中数组是弱类型的,数组中可以含有不同类型的元素.数组元素甚至可以是对象或其它数组 ...
- 【回顾】html简介、基础、元素
1.简介 什么是HTML? HTML 是用来描述网页的一种语言. HTML 指的是超文本标记语言: HyperText Markup Language HTML 不是一种编程语言,而是一种标记语言 标 ...