# 配置文档 MMOCR 主要使用 Python 文件作为配置文件。其配置文件系统的设计整合了模块化与继承的思想,方便用户进行各种实验。 ## 常见用法 ```{note} 本小节建议结合 [配置(Config)](https://github.com/open-mmlab/mmengine/blob/main/docs/zh_cn/tutorials/config.md) 中的初级用法共同阅读。 ``` MMOCR 最常用的操作为三种:配置文件的继承,对 `_base_` 变量的引用以及对 `_base_` 变量的修改。对于 `_base_` 的继承与修改, MMEngine.Config 提供了两种语法,一种是针对 Python,Json, Yaml 均可使用的操作;另一种则仅适用于 Python 配置文件。在 MMOCR 中,我们**更推荐使用只针对Python的语法**,因此下文将以此为基础作进一步介绍。 这里以 `configs/textdet/dbnet/dbnet_resnet18_fpnc_1200e_icdar2015.py` 为例,说明常用的三种用法。 ```Python _base_ = [ '_base_dbnet_resnet18_fpnc.py', '../_base_/datasets/icdar2015.py', '../_base_/default_runtime.py', '../_base_/schedules/schedule_sgd_1200e.py', ] # dataset settings ic15_det_train = _base_.ic15_det_train ic15_det_train.pipeline = _base_.train_pipeline ic15_det_test = _base_.ic15_det_test ic15_det_test.pipeline = _base_.test_pipeline train_dataloader = dict( batch_size=16, num_workers=8, persistent_workers=True, sampler=dict(type='DefaultSampler', shuffle=True), dataset=ic15_det_train) val_dataloader = dict( batch_size=1, num_workers=4, persistent_workers=True, sampler=dict(type='DefaultSampler', shuffle=False), dataset=ic15_det_test) ``` ### 配置文件的继承 配置文件存在继承的机制,即一个配置文件 A 可以将另一个配置文件 B 作为自己的基础并直接继承其中的所有字段,从而避免了大量的复制粘贴。 在 dbnet_resnet18_fpnc_1200e_icdar2015.py 中可以看到: ```Python _base_ = [ '_base_dbnet_resnet18_fpnc.py', '../_base_/datasets/icdar2015.py', '../_base_/default_runtime.py', '../_base_/schedules/schedule_sgd_1200e.py', ] ``` 上述语句会读取列表中的所有基础配置文件,它们中的所有字段都会被载入到 dbnet_resnet18_fpnc_1200e_icdar2015.py 中。我们可以通过在 Python 解释中运行以下语句,了解配置文件被解析后的结构: ```Python from mmengine import Config db_config = Config.fromfile('configs/textdet/dbnet/dbnet_resnet18_fpnc_1200e_icdar2015.py') print(db_config) ``` 可以发现,被解析的配置包含了所有base配置中的字段和信息。 ```{note} 请注意:各 _base_ 配置文件中不能存在同名变量。 ``` ### `_base_` 变量的引用 有时,我们可能需要直接引用 `_base_` 配置中的某些字段,以避免重复定义。假设我们想要获取 `_base_` 配置中的变量 `pseudo`,就可以直接通过 `_base_.pseudo` 获得 `_base_` 配置中的变量。 该语法已广泛用于 MMOCR 的配置中。MMOCR 中各个模型的数据集和管道(pipeline)配置都引用于*基本*配置。如在 ```Python ic15_det_train = _base_.ic15_det_train # ... train_dataloader = dict( # ... dataset=ic15_det_train) ``` ### `_base_` 变量的修改 在 MMOCR 中不同算法在不同数据集通常有不同的数据流水线(pipeline),因此经常会会存在修改数据集中 `pipeline` 的场景。同时还存在很多场景需要修改 `_base_` 配置中的变量,例如想修改某个算法的训练策略,某个模型的某些算法模块(更换 backbone 等)。用户可以直接利用 Python 的语法直接修改引用的 `_base_` 变量。针对 dict,我们也提供了与类属性修改类似的方法,可以直接修改类属性修改字典内的内容。 1. 字典 这里以修改数据集中的 `pipeline` 为例: 可以利用 Python 语法修改字典: ```python # 获取 _base_ 中的数据集 ic15_det_train = _base_.ic15_det_train # 可以直接利用 Python 的 update 修改变量 ic15_det_train.update(pipeline=_base_.train_pipeline) ``` 也可以使用类属性的方法进行修改: ```Python # 获取 _base_ 中的数据集 ic15_det_train = _base_.ic15_det_train # 类属性方法修改 ic15_det_train.pipeline = _base_.train_pipeline ``` 2. 列表 假设 `_base_` 配置中的变量 `pseudo = [1, 2, 3]`, 需要修改为 `[1, 2, 4]`: ```Python # pseudo.py pseudo = [1, 2, 3] ``` 可以直接重写: ```Python _base_ = ['pseudo.py'] pseudo = [1, 2, 4] ``` 或者利用 Python 语法修改列表: ```Python _base_ = ['pseudo.py'] pseudo = _base_.pseudo pseudo[2] = 4 ``` ### 命令行修改配置 有时候我们只希望修部分配置,而不想修改配置文件本身。例如实验过程中想更换学习率,但是又不想重新写一个配置文件,可以通过命令行传入参数来覆盖相关配置。 我们可以在命令行里传入 `--cfg-options`,并在其之后的参数直接修改对应字段,例如我们想在运行 train 的时候修改学习率,只需要在命令行执行: ```Shell python tools/train.py example.py --cfg-options optim_wrapper.optimizer.lr=1 ``` 更多详细用法参考[命令行修改配置](https://github.com/open-mmlab/mmengine/blob/main/docs/zh_cn/tutorials/config.md#%E5%91%BD%E4%BB%A4%E8%A1%8C%E4%BF%AE%E6%94%B9%E9%85%8D%E7%BD%AE) ## 配置内容 通过配置文件与注册器的配合,MMOCR 可以在不侵入代码的前提下修改训练参数以及模型配置。具体而言,用户可以在配置文件中对如下模块进行自定义修改:环境配置、Hook 配置、日志配置、训练策略配置、数据相关配置、模型相关配置、评测配置、可视化配置。 本文档将以文字检测算法 `DBNet` 和文字识别算法 `CRNN` 为例来详细介绍 Config 中的内容。
### 环境配置 ```Python default_scope = 'mmocr' env_cfg = dict( cudnn_benchmark=True, mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0), dist_cfg=dict(backend='nccl')) random_cfg = dict(seed=None) ``` 主要包含三个部分: - 设置所有注册器的默认 `scope` 为 `mmocr`, 保证所有的模块首先从 `MMOCR` 代码库中进行搜索。若果该模块不存在,则继续从上游算法库 `MMEngine` 和 `MMCV` 中进行搜索(详见[注册器](https://github.com/open-mmlab/mmengine/blob/main/docs/zh_cn/tutorials/registry.md)。 - `env_cfg` 设置分布式环境配置, 更多配置可以详见 [MMEngine Runner](https://github.com/open-mmlab/mmengine/blob/main/docs/zh_cn/tutorials/runner.md) - `random_cfg` 设置 numpy, torch,cudnn 等随机种子,更多配置详见 [Runner](https://github.com/open-mmlab/mmengine/blob/main/docs/zh_cn/tutorials/runner.md) ### Hook 配置 Hook 主要分为两个部分,默认 hook 以及自定义 hook。默认 hook 为所有任务想要运行所必须的配置,自定义 hook 一般服务于特定的算法或某些特定任务(目前为止 MMOCR 中没有自定义的 Hook)。 ```Python default_hooks = dict( timer=dict(type='IterTimerHook'), # 时间记录,包括数据增强时间以及模型推理时间 logger=dict(type='LoggerHook', interval=1), # 日志打印间隔 param_scheduler=dict(type='ParamSchedulerHook'), # 与param_scheduler 更新学习率等超参 checkpoint=dict(type='CheckpointHook', interval=1),# 保存 checkpoint, interval控制保存间隔 sampler_seed=dict(type='DistSamplerSeedHook'), # 多机情况下设置种子 sync_buffer=dict(type='SyncBuffersHook'), # 同步多卡情况下,buffer visualization=dict( # 用户可视化val 和 test 的结果 type='VisualizationHook', interval=1, enable=False, show=False, draw_gt=False, draw_pred=False)) custom_hooks = [] ``` 这里简单介绍几个经常可能会变动的 hook,通用的修改方法参考[修改配置](#base-变量的修改)。 - `LoggerHook`:用于配置日志记录器的行为。例如,通过修改 `interval` 可以控制日志打印的间隔,每 `interval` 次迭代 (iteration) 打印一次日志,更多设置可参考 [LoggerHook API](mmengine.hooks.LoggerHook)。 - `CheckpointHook`:用于配置模型断点保存相关的行为,如保存最优权重,保存最新权重等。同样可以修改 `interval` 控制保存 checkpoint 的间隔。更多设置可参考 [CheckpointHook API](mmengine.hooks.CheckpointHook) - `VisualizationHook`:用于配置可视化相关行为,例如在验证或测试时可视化预测结果,默认为关。同时该 Hook 依赖[可视化配置](#TODO)。想要了解详细功能可以参考 [Visualizer](visualization.md)。更多配置可以参考 [VisualizationHook API](mmocr.engine.hooks.VisualizationHook)。 如果想进一步了解默认 hook 的配置以及功能,可以参考[钩子(Hook)](https://github.com/open-mmlab/mmengine/blob/main/docs/zh_cn/tutorials/hook.md)。 ### 日志配置 此部分主要用来配置日志配置等级以及日志处理器。 ```Python log_level = 'INFO' # 日志记录等级 log_processor = dict(type='LogProcessor', window_size=10, by_epoch=True) ``` - 日志配置等级与 [logging](https://docs.python.org/3/library/logging.html) 的配置一致, - 日志处理器主要用来控制输出的格式,详细功能可参考[记录日志](https://github.com/open-mmlab/mmengine/blob/main/docs/zh_cn/advanced_tutorials/logging.md): - `by_epoch=True` 表示按照epoch输出日志,日志格式需要和 `train_cfg` 中的 `type='EpochBasedTrainLoop'` 参数保持一致。例如想按迭代次数输出日志,就需要令 `log_processor` 中的 ` by_epoch=False` 的同时 `train_cfg` 中的 `type = 'IterBasedTrainLoop'`。 - `window_size` 表示损失的平滑窗口,即最近 `window_size` 次迭代的各种损失的均值。logger 中最终打印的 loss 值为经过各种损失的平均值。 ### 训练策略配置 此部分主要包含优化器设置、学习率策略和 `Loop` 设置。 对不同算法任务(文字检测,文字识别,关键信息提取),通常有自己任务常用的调参策略。这里列出了文字识别中的 `CRNN` 所用涉及的相应配置。 ```Python # 优化器 optim_wrapper = dict( type='OptimWrapper', optimizer=dict(type='Adadelta', lr=1.0)) param_scheduler = [dict(type='ConstantLR', factor=1.0)] train_cfg = dict(type='EpochBasedTrainLoop', max_epochs=5, # 训练轮数 val_interval=1) # 评测间隔 val_cfg = dict(type='ValLoop') test_cfg = dict(type='TestLoop') ``` - `optim_wrapper` : 主要包含两个部分,优化器封装 (OptimWrapper) 以及优化器 (Optimizer)。详情使用信息可见 [MMEngine 优化器封装](https://github.com/open-mmlab/mmengine/blob/main/docs/zh_cn/tutorials/optim_wrapper.md) - 优化器封装支持不同的训练策略,包括混合精度训练(AMP)、梯度累加和梯度截断。 - 优化器设置中支持了 PyTorch 所有的优化器,所有支持的优化器见 [PyTorch 优化器列表](torch.optim.algorithms)。 - `param_scheduler` : 学习率调整策略,支持大部分 PyTorch 中的学习率调度器,例如 `ExponentialLR`,`LinearLR`,`StepLR`,`MultiStepLR` 等,使用方式也基本一致,所有支持的调度器见[调度器接口文档](mmengine.optim.scheduler), 更多功能可以[参考优化器参数调整策略](https://github.com/open-mmlab/mmengine/blob/main/docs/zh_cn/tutorials/param_scheduler.md) - `train/test/val_cfg` : 任务的执行流程,MMEngine 提供了四种流程:`EpochBasedTrainLoop`, `IterBasedTrainLoop`, `ValLoop`, `TestLoop` 更多可以参考[循环控制器](https://github.com/open-mmlab/mmengine/blob/main/docs/zh_cn/tutorials/runner.md)。 ### 数据相关配置textdet |
_base_ | datasets | icdar_datasets.py ctw1500.py ... |
数据集配置 |
schedulers | schedule_adam_600e.py ... |
训练策略配置 | ||
defaults_runtime.py |
- | 环境配置 默认hook配置 日志配置 权重加载配置 评测配置 可视化配置 |
||
dbnet | _base_dbnet_resnet18_fpnc.py | - | 网络配置 数据流水线 |
|
dbnet_resnet18_fpnc_1200e_icdar2015.py | - | Dataloader 配置 数据流水线(Optional) |