Detectron2源码阅读笔记-(一)Config&Trainer
代码结构概览
核心部分
- configs:储存各种网络的yaml配置文件
- datasets:存放数据集的地方
- detectron2:运行代码的核心组件
- tools:提供了运行代码的入口以及一切可视化的代码文件。
Tutorial部分
- demo:显而易见就是demo
- docs: 同样显而易见。。
- tests:提供了一些测试代码
- projects:提供了真实的项目代码示例,之后自己的代码结构可参照这个结构写。
代码逻辑分析
超参数配置
进入tools/train_net.py的main函数,第一行cfg = setup(args)是配置参数。Detectron2中的参数配置使用了yacs这个库,这个库能够很好地重用和拼接超参数文件配置。
我们先看一下detrctron2/config/的文件结构:
compat.py: 应该是对之前的Detectron库的兼容吧,可忽略。config.py: 定义了一个CfgNode类,这个类继承自fvcore库(fb写的一个共公共库,提供一些共享的函数,方便各种不同项目使用)中定义的CfgNode,总之就是不断继承。。。继承关系是这样的:
detrctron2.config.CfgNode->fcvore.common.config.CfgNode->yacs.config.CfgNode->dict
另外该文件还提供了get_cfg()方法,该方法会返回一个含有默认配置的CfgNode,而这些默认的配置值在下面的default.py中定义了,之所以这样做是因为要配置的默认值太多了,所以为了文档清晰才写到了一个新的文件中去,不过,yacs库的作者也建议这样做。default.py: 如上面所说,该文件定义了各种参数的默认值。
了解配置函数的方法后我们再回到tools/train_net.py,我们一行一行的来理解。
tools/train_net.py
from detectron2.config import get_cfg
from detectron2.engine import DefaultTrainer, default_argument_parser, default_setup, hooks, launch
...
def setup(args):
"""
Create configs and perform basic setups.
"""
cfg = get_cfg()
cfg.merge_from_file(args.config_file)
cfg.merge_from_list(args.opts)
cfg.freeze()
default_setup(cfg, args)
return cfg
- cfg = get_cfg(): 获取已经配置好默认参数的cfg
- cfg.merge_from_file(args.config_file):config_file是指定的yaml配置文件,通过
merge_from_file这个函数会将yaml文件中指定的超参数对默认值进行覆盖。 - cfg.merge_from_list(args.opts):
merge_from_list作用同上面的类似,只不过是通过命令行的方式覆盖。
例如
opts = ["SYSTEM.NUM_GPUS", 8, "TRAIN.SCALES", "(1, 2, 3, 4)"]
cfg.merge_from_list(opts)
print("cfg\n",cfg)
那么最后会有
cfg
... (一些默认值超参数)
SYSTEM:
NUM_GPUS: 8
TRAIN:
SCALES: (1,2,3,4)
- cfg.freeze(): freeze函数的作用是将超参数值冻结,避免被程序不小心修改。
- default_setup(cfg, args):
default_setup是detectron2/engine/default.py中提供的一个默认配置函数,具体是怎么配置的这里不详细说明了。不过需要知道的值这个文件中还提供了很多其他的配置函数,例如还提供了两个类:DefaultPredictor和DefaultTrainer。
Trainer
既然上面提到了DefaultTrainer,那么我们就从这个类入手了解一下detectron2.engine,其代码结构如下:
train_loop.py: 这个函数主要作用是提供了三个重要的类:HookBase: 这是一个Hook的基类,用于指定在训练前后或者每一个step前后需要做什么事情,所以根据特定的需求需要对如下四种方法做不同的定义:before_train,after_train,before_step,after_step。以before_step。TrainerBase: 该类中定义的函数可以归纳成三种:register_hooks:这个很好理解,就是将用户定义的一些hooks进行注册,说大白话就是把若干个Hook放在一个list里面去。之后只需要遍历这个list依次执行就可以了。- 第二类其实就是上面提到的遍历hook list并执行hook,不过这个遍历有四种,分别是
before_train,after_train,before_step,after_step。还有一个就是run_step,这个函数其实就是平常我们在编写训练过程的代码,例如读数据,训练模型,获取损失值,求导数,反向梯度更新等,只不过在这个类里面没有定义。 - 第三类就是
train函数,它有两个参数,分别是开始的迭代数和最大的迭代数。之后就是重复依次执行第二类中的函数指定迭代次数。
SimpleTrainer:其实就是继承自TrainerBase,然后定义了run_step等方法。我们后面也可以继承这个类做进一步的自定义。
defaults.py: 上面已介绍,提供了两个类:DefaultPredictor和DefaultTrainer,这个DefaultTrainer就继承自SimpleTrainer,所以存在如下继承关系:
detectron2.engine.default.DefaultTrainer->detectron2.engine.train_loop.SimpleTrainer->detectron2.engine.train_loop.TrainerBasehooks.py:定义了很多继承自train_loop.HookBase的Hook。launch.py: 前面提到过,可以理解成代码启动器,可以根据命令决定是否采用分布式训练(或者单机多卡)或者单机单卡训练。
好了,我们继续回到tools/train_net.py的main函数,代码如下所示。
def main(args):
cfg = setup(args)
if args.eval_only:
...
trainer = Trainer(cfg)
trainer.resume_or_load(resume=args.resume)
if cfg.TEST.AUG.ENABLED:
trainer.register_hooks(
[hooks.EvalHook(0, lambda: trainer.test_with_TTA(cfg, trainer.model))]
)
return trainer.train()
可以看到下面定义了一个Trainer,它继承自detectron2.engine.default.DefaultTrainer,这个父类会自动解析cfg。之后只需要调用trainer.train()就可以开始训练了。
小结

至此我们对detectron2的逻辑有了大致的了解了,那么接下来我们来了解一下detectron2.engine.default.DefaultTrainer是如何解析cfg的,这部分内容请参见Detectron2代码阅读笔记-(二)。
Detectron2源码阅读笔记-(一)Config&Trainer的更多相关文章
- Detectron2源码阅读笔记-(二)Registry&build_*方法
Trainer解析 我们继续Detectron2代码阅读笔记-(一)中的内容. 上图画出了detectron2文件夹中的三个子文件夹(tools,config,engine)之间的关系.那么剩下的 ...
- Detectron2源码阅读笔记-(三)Dataset pipeline
构建data_loader原理步骤 # engine/default.py from detectron2.data import ( MetadataCatalog, build_detection ...
- CI框架源码阅读笔记4 引导文件CodeIgniter.php
到了这里,终于进入CI框架的核心了.既然是“引导”文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http://you.host.c ...
- CI框架源码阅读笔记3 全局函数Common.php
从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap ...
- CI框架源码阅读笔记2 一切的入口 index.php
上一节(CI框架源码阅读笔记1 - 环境准备.基本术语和框架流程)中,我们提到了CI框架的基本流程,这里再次贴出流程图,以备参考: 作为CI框架的入口文件,源码阅读,自然由此开始.在源码阅读的过程中, ...
- Apollo源码阅读笔记(二)
Apollo源码阅读笔记(二) 前面 分析了apollo配置设置到Spring的environment的过程,此文继续PropertySourcesProcessor.postProcessBeanF ...
- Apollo源码阅读笔记(一)
Apollo源码阅读笔记(一) 先来一张官方客户端设计图,方便我们了解客户端的整体思路. 我们在使用Apollo的时候,需要标记@EnableApolloConfig来告诉程序开启apollo配置,所 ...
- CI框架源码阅读笔记5 基准测试 BenchMark.php
上一篇博客(CI框架源码阅读笔记4 引导文件CodeIgniter.php)中,我们已经看到:CI中核心流程的核心功能都是由不同的组件来完成的.这些组件类似于一个一个单独的模块,不同的模块完成不同的功 ...
- 源码阅读笔记 - 1 MSVC2015中的std::sort
大约寒假开始的时候我就已经把std::sort的源码阅读完毕并理解其中的做法了,到了寒假结尾,姑且把它写出来 这是我的第一篇源码阅读笔记,以后会发更多的,包括算法和库实现,源码会按照我自己的代码风格格 ...
随机推荐
- Django学习----js传参给view.py
需求: 散点图中每选择一个点,获取到id之后传给view.py,根据这个id进行sql语句的查询. 问题: 要求实时查询 解决办法: ajax查询 js页面 .on("mousedown&q ...
- 自定义Ribbon的负载均衡策略
自定义负载均衡策略 官方文档指出:自定义的负载均衡配置类不能放在 @componentScan 所扫描的当前包下及其子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,也就是说我们 ...
- html5 audio标签切换播放音乐的方法
html5 audio标签切换播放音乐的方法<pre><audio id="music1" preload loop="loop">&l ...
- python入门之名称空间
name = 'tank' 什么是名称空间? 存放名字的空间 如果你想访问一个变量值,必须先访问对应的名称空间,拿到名字和对应的内存地址的绑定关系 名称空间的分类: 1.内置名称空间: python提 ...
- laravel门面与服务提供者区别
laravel门面模式与服务提供者区别 以 Laravel 自带的文件系统为例,在 config/app.php 的配置文件的 providers 数组中,注册了一个服务提供者: Illuminate ...
- Win10创建mysql8.0桌面快捷方式以及启动mysql.exe闪退问题
1.先找到mysql的bin目录,将Mysql.exe发送快捷方式到桌面. 2.然后右键选择属性,将目标后面添加上 -uroot -p 我的完整目标如下: E:\mysql-8.0.17-winx64 ...
- 017 使用域名访问本地项目---涉及switchhost和Nginx
1.统一环境 我们现在访问页面使用的是:http://localhost:9001 实际开发中,会有不同的环境: 开发环境:自己的电脑 测试环境:提供给测试人员使用的环境 预发布环境:数据是和生成环境 ...
- Effective.Java第34-44条(枚举)
34. 使用枚举类型替代整型常量 常量的语义表达不清晰,只能靠前面的名称来区分.枚举具有可读性.更安全.更强大等优势.而且枚举类型对象之间的值比较可以使用==来比较值是否相等的,不是必须使用equa ...
- Vue父组件如何调用子组件(弹出框)中的方法的问题
如果子组件是一个弹出框,只有在触发某个点击事件时弹出框才能出现(也就是说在父组件中的子组件使用上用了v-if),那在父组件上如果不点击弹出框是不能获取到$ref的. 原因就是:引用指向的是子组件创建的 ...
- 干货|Dubbo社区开发者日经验分享
Hello,各位小伙伴大家好,我是小栈君,昨天也就是2019年10月26日,有幸在成都参加了由阿里举办的"Dubbo社区开发者日". 本次活动汇聚了各方面的大神欢聚一堂,主要是对现 ...