Skip to content

Commit 3336abf

Browse files
authored
[Doc] Translate tutorial 6_customize_runtime (#1313)
* Translate Tutorial 6_runtime_setting draft * Translate Tutorial 6_runtime_setting polish * Translate Tutorial 6_customize_runtime - fix indexing * Translate Tutorial 6_customize_runtime - refine * Translate Tutorial 6_customize_runtime - regulate blank
1 parent 4853b4b commit 3336abf

File tree

3 files changed

+343
-4
lines changed

3 files changed

+343
-4
lines changed

README_CN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ MMPose 也提供了其他更详细的教程:
109109
* [如何设计数据处理流程](docs/zh_cn/tutorials/3_data_pipeline.md)
110110
* [如何增加新模块](docs/zh_cn/tutorials/4_new_modules.md)
111111
* [如何导出模型为 onnx 格式](docs/zh_cn/tutorials/5_export_model.md)
112-
* [如何自定义模型运行参数](docs/en/tutorials/6_customize_runtime.md)(英文)
112+
* [如何自定义运行配置](docs/zh_cn/tutorials/6_customize_runtime.md)
113113

114114
## 模型库
115115

docs/zh_cn/getting_started.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,4 +277,4 @@ CUDA_VISIBLE_DEVICES=4,5,6,7 GPUS=4 ./tools/slurm_train.sh ${PARTITION} ${JOB_NA
277277
- [如何设计数据处理流程](tutorials/3_data_pipeline.md)
278278
- [如何增加新模块](tutorials/4_new_modules.md)
279279
- [如何导出模型为 onnx 格式](tutorials/5_export_model.md)
280-
- [如何自定义模型运行参数](tutorials/6_customize_runtime.md)
280+
- [如何自定义运行配置](tutorials/6_customize_runtime.md)
Lines changed: 341 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,342 @@
1-
# 教程 6: 自定义运行时设置
1+
# 教程 6: 自定义运行配置
22

3-
内容建设中……
3+
在这篇教程中,我们将会介绍如何在您的项目中自定义优化方法、训练策略、工作流和钩子。
4+
5+
<!-- TOC -->
6+
7+
- [自定义优化方法](#自定义优化方法)
8+
- [使用PyTorch支持的优化器](#使用PyTorch支持的优化器)
9+
- [使用自己实现的优化器](#使用自己实现的优化器)
10+
- [1. 定义一个新优化器](#1-定义一个新优化器)
11+
- [2. 注册这个优化器](#2-注册这个优化器)
12+
- [3. 在配置文件中指定优化器](#3-在配置文件中指定优化器)
13+
- [自定义优化器构造器](#自定义优化器构造器)
14+
- [更多设置](#更多设置)
15+
- [自定义训练策略](#自定义训练策略)
16+
- [自定义工作流](#自定义工作流)
17+
- [自定义钩子](#customize-hooks)
18+
- [使用自己实现的钩子](#customize-self-implemented-hooks)
19+
- [1. 定义一个新的钩子](#1-定义一个新的钩子)
20+
- [2. 注册这个新的钩子](#2-注册这个新的钩子)
21+
- [3. 修改配置文件](#3-修改配置文件)
22+
- [使用MMCV中的钩子](#使用MMCV中的钩子)
23+
- [修改默认的运行钩子](#修改默认的运行钩子)
24+
- [模型权重文件配置](#模型权重文件配置)
25+
- [日志配置](#日志配置)
26+
- [测试配置](#测试配置)
27+
28+
<!-- TOC -->
29+
30+
## 自定义优化方法
31+
32+
### 使用PyTorch支持的优化器
33+
34+
我们现已支持PyTorch自带的所有优化器。若要使用这些优化器,用户只需在配置文件中修改 `optimizer` 这一项。比如说,若您想使用 `Adam` 优化器,可以对配置文件做如下修改
35+
36+
```python
37+
optimizer = dict(type='Adam', lr=0.0003, weight_decay=0.0001)
38+
```
39+
40+
若要修改模型的学习率,用户只需在配置文件中修改优化器的 `lr` 参数。优化器各参数的设置可参考PyTorch的[API文档](https://pytorch.org/docs/stable/optim.html?highlight=optim#module-torch.optim)
41+
42+
例如,用户想要使用在PyTorch中配置为 `torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False)``Adam` 优化器,可按照以下形式修改配置文件。
43+
44+
```python
45+
optimizer = dict(type='Adam', lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False)
46+
```
47+
48+
### 使用自己实现的优化器
49+
50+
#### 1. 定义一个新优化器
51+
52+
如果您想添加一个新的优化器,名字叫`MyOptimizer`,参数包括 `a``b``c`,可以按照以下步骤定义该优化器。
53+
54+
首先,创建一个新目录 `mmpose/core/optimizer`
55+
然后,在新文件 `mmpose/core/optimizer/my_optimizer.py` 中实现该优化器:
56+
57+
```python
58+
from .builder import OPTIMIZERS
59+
from torch.optim import Optimizer
60+
61+
62+
@OPTIMIZERS.register_module()
63+
class MyOptimizer(Optimizer):
64+
65+
def __init__(self, a, b, c):
66+
67+
```
68+
69+
#### 2. 注册这个优化器
70+
71+
新优化器必须先导入主命名空间才能被成功调用。有两种实现方式。
72+
73+
- 修改 `mmpose/core/optimizer/__init__.py` 来导入
74+
75+
新定义的优化器得在 `mmpose/core/optimizer/__init__.py` 中被导入,注册器才能发现并添加它。
76+
77+
```python
78+
from .my_optimizer import MyOptimizer
79+
```
80+
81+
- 在配置文件中使用 `custom_imports` 手动导入
82+
83+
```python
84+
custom_imports = dict(imports=['mmpose.core.optimizer.my_optimizer'], allow_failed_imports=False)
85+
```
86+
87+
在程序运行之初,库 `mmpose.core.optimizer.my_optimizer` 将会被导入。此时类 `MyOptimizer` 会自动注册。
88+
注意只有包含类 `MyOptimizer` 的库才能被导入。 `mmpose.core.optimizer.my_optimizer.MyOptimizer` **不可以**被直接导入。
89+
90+
#### 3. 在配置文件中指定优化器
91+
92+
在新优化器 `MyOptimizer` 注册之后,它可以在配置文件中通过 `optimizer` 调用。
93+
在配置文件中,优化器通过 `optimizer` 以如下方式指定:
94+
95+
```python
96+
optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)
97+
```
98+
99+
如果要使用自己实现的新优化器 `MyOptimizer`,可以进行如下修改:
100+
101+
```python
102+
optimizer = dict(type='MyOptimizer', a=a_value, b=b_value, c=c_value)
103+
```
104+
105+
### 自定义优化器构造器
106+
107+
有些模型可能需要在优化器里对一些特别参数进行设置,例如批归一化层的权重衰减系数。
108+
用户可以通过自定义优化器构造器来实现这些精细参数的调整。
109+
110+
```python
111+
from mmcv.utils import build_from_cfg
112+
113+
from mmcv.runner.optimizer import OPTIMIZER_BUILDERS, OPTIMIZERS
114+
from mmpose.utils import get_root_logger
115+
from .my_optimizer import MyOptimizer
116+
117+
118+
@OPTIMIZER_BUILDERS.register_module()
119+
class MyOptimizerConstructor:
120+
121+
def __init__(self, optimizer_cfg, paramwise_cfg=None):
122+
pass
123+
124+
def __call__(self, model):
125+
126+
return my_optimizer
127+
```
128+
129+
[这里](https://github.com/open-mmlab/mmcv/blob/9ecd6b0d5ff9d2172c49a182eaa669e9f27bb8e7/mmcv/runner/optimizer/default_constructor.py#L11)是默认优化器构造器的实现。它还可以用作新的优化器构造器的模板。
130+
131+
### 更多设置
132+
133+
有些优化器没有实现的功能可以通过优化器构造器(例如对不同权重设置不同学习率)或者钩子实现。
134+
我们列出了一些用于稳定、加速训练的常用设置。欢迎通过PR、issue提出更多这样的设置。
135+
136+
- __使用梯度截断来稳定训练__
137+
有些模型需要梯度截断来使梯度数值保持在某个范围,以让训练过程更加稳定。例如:
138+
139+
```python
140+
optimizer_config = dict(grad_clip=dict(max_norm=35, norm_type=2))
141+
```
142+
143+
- __使用动量策略加速模型收敛__
144+
我们支持根据学习率来修改模型动量的动量调度器。它可以让模型收敛更快。
145+
动量调度器通常和学习率调度器一起使用。例如3D检测中使用下面的配置来加速收敛。
146+
更多细节可以参考 [CyclicLrUpdater](https://github.com/open-mmlab/mmcv/blob/f48241a65aebfe07db122e9db320c31b685dc674/mmcv/runner/hooks/lr_updater.py#L327)[CyclicMomentumUpdater](https://github.com/open-mmlab/mmcv/blob/f48241a65aebfe07db122e9db320c31b685dc674/mmcv/runner/hooks/momentum_updater.py#L130) 的实现。
147+
148+
```python
149+
lr_config = dict(
150+
policy='cyclic',
151+
target_ratio=(10, 1e-4),
152+
cyclic_times=1,
153+
step_ratio_up=0.4,
154+
)
155+
momentum_config = dict(
156+
policy='cyclic',
157+
target_ratio=(0.85 / 0.95, 1),
158+
cyclic_times=1,
159+
step_ratio_up=0.4,
160+
)
161+
```
162+
163+
## 自定义训练策略
164+
165+
我们默认使用的学习率变化策略为阶梯式衰减策略,即MMCV中的[`StepLRHook`](https://github.com/open-mmlab/mmcv/blob/f48241a65aebfe07db122e9db320c31b685dc674/mmcv/runner/hooks/lr_updater.py#L153)
166+
此外,我们还支持很多[学习率变化策略](https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/hooks/lr_updater.py),例如余弦退火策略 `CosineAnnealing` 和多项式策略 `Poly`。其调用方式如下
167+
168+
- 多项式策略:
169+
170+
```python
171+
lr_config = dict(policy='poly', power=0.9, min_lr=1e-4, by_epoch=False)
172+
```
173+
174+
- 余弦退火策略:
175+
176+
```python
177+
lr_config = dict(
178+
policy='CosineAnnealing',
179+
warmup='linear',
180+
warmup_iters=1000,
181+
warmup_ratio=1.0 / 10,
182+
min_lr_ratio=1e-5)
183+
```
184+
185+
## 自定义工作流
186+
187+
我们推荐用户在每轮训练结束后对模型进行评估,即采用 `EpochEvalHook` 工作流。不过很多用户仍采用 `val` 工作流。
188+
189+
工作流是一个由(阶段,轮数)构成的列表,它规定了程序运行中不同阶段的顺序和轮数。默认的工作流为
190+
191+
```python
192+
workflow = [('train', 1)]
193+
```
194+
195+
即“训练 1 轮”。
196+
有时候用户可能想要计算模型在验证集上的某些指标(例如损失、准确率)。此时可将工作流设定为
197+
198+
```python
199+
[('train', 1), ('val', 1)]
200+
```
201+
202+
即1轮训练后进行1轮验证,两者交替进行。
203+
204+
```{note}
205+
1. 进行验证时,模型权重不会发生变化。
206+
1. 配置文件中,参数 `total_epochs` 只控制训练轮数,不影响验证工作流
207+
1. 工作流 `[('train', 1), ('val', 1)]` 和 `[('train', 1)]` 不会改变 `EpochEvalHook` 的行为。因为 `EpochEvalHook` 只在 `after_train_epoch` 中被调用。而验证工作流只会影响被 `after_val_epoch` 调用的钩子。
208+
因此,工作流 `[('train', 1), ('val', 1)]` 与 `[('train', 1)]` 唯一的差别就是运行程序会在每轮训练后计算模型在验证集上的损失。
209+
```
210+
211+
## 自定义钩子
212+
213+
### 使用自己实现的钩子
214+
215+
#### 1. 定义一个新的钩子
216+
217+
下面的例子展示了如何定义一个新的钩子并将其用于训练。
218+
219+
```python
220+
from mmcv.runner import HOOKS, Hook
221+
222+
223+
@HOOKS.register_module()
224+
class MyHook(Hook):
225+
226+
def __init__(self, a, b):
227+
pass
228+
229+
def before_run(self, runner):
230+
pass
231+
232+
def after_run(self, runner):
233+
pass
234+
235+
def before_epoch(self, runner):
236+
pass
237+
238+
def after_epoch(self, runner):
239+
pass
240+
241+
def before_iter(self, runner):
242+
pass
243+
244+
def after_iter(self, runner):
245+
pass
246+
```
247+
248+
用户需要根据钩子的实际用途定义该钩子在 `before_run``after_run``before_epoch``after_epoch``before_iter` 以及 `after_iter` 中的行为。
249+
250+
#### 2. 注册这个新的钩子
251+
252+
定义好钩子 `MyHook` 之后,我们需要将其导入。假设 `MyHook` 在文件 `mmpose/core/utils/my_hook.py` 中定义,则有两种方式可以导入:
253+
254+
- 通过修改 `mmpose/core/utils/__init__.py` 进行导入。
255+
256+
新定义的模块需要被导入到 `mmpose/core/utils/__init__.py` 才能被注册器找到并添加:
257+
258+
```python
259+
from .my_hook import MyHook
260+
```
261+
262+
- 在配置文件中使用 `custom_imports` 手动导入
263+
264+
```python
265+
custom_imports = dict(imports=['mmpose.core.utils.my_hook'], allow_failed_imports=False)
266+
```
267+
268+
#### 3. 修改配置文件
269+
270+
```python
271+
custom_hooks = [
272+
dict(type='MyHook', a=a_value, b=b_value)
273+
]
274+
```
275+
276+
用户可以通过将钩子的参数 `priority` 设置为 `'NORMAL'``'HIGHEST'` 来设定它的优先级
277+
278+
```python
279+
custom_hooks = [
280+
dict(type='MyHook', a=a_value, b=b_value, priority='NORMAL')
281+
]
282+
```
283+
284+
钩子在注册时,其优先级默认为 `NORMAL`
285+
286+
### 使用MMCV中的钩子
287+
288+
用户可以直接修改配置文件来调用MMCV中已实现的钩子
289+
290+
```python
291+
mmcv_hooks = [
292+
dict(type='MMCVHook', a=a_value, b=b_value, priority='NORMAL')
293+
]
294+
```
295+
296+
### 修改默认的运行钩子
297+
298+
有部分常用钩子没有通过 `custom_hooks` 注册。在导入MMCV时,它们会自动注册。这些钩子包括:
299+
300+
- log_config
301+
- checkpoint_config
302+
- evaluation
303+
- lr_config
304+
- optimizer_config
305+
- momentum_config
306+
307+
这些钩子中,只有日志钩子的优先级为 `VERY_LOW`,其他钩子的优先级都是 `NORMAL`
308+
前面的教程已经讲述了如何修改 `optimizer_config``momentum_config``lr_config`。这里我们介绍如何修改 `log_config``checkpoint_config``evaluation`
309+
310+
#### 模型权重文件配置
311+
312+
MMCV的运行程序会使用 `checkpoint_config` 来初始化 [`CheckpointHook`](https://github.com/open-mmlab/mmcv/blob/9ecd6b0d5ff9d2172c49a182eaa669e9f27bb8e7/mmcv/runner/hooks/checkpoint.py#L9)
313+
314+
```python
315+
checkpoint_config = dict(interval=1)
316+
```
317+
318+
用户可以通过设置 `max_keep_ckpts` 来保存有限的模型权重文件;通过设置 `save_optimizer` 以决定是否保存优化器的状态。
319+
[这份文档](https://mmcv.readthedocs.io/en/latest/api.html#mmcv.runner.CheckpointHook)介绍了更多参数的细节。
320+
321+
#### 日志配置
322+
323+
日志配置 `log_config` 可以设置多个日志钩子,并且可以设定记录间隔。目前MMCV支持的日志钩子包括 `WandbLoggerHook``MlflowLoggerHook``TensorboardLoggerHook`
324+
[这份文档](https://mmcv.readthedocs.io/en/latest/api.html#mmcv.runner.LoggerHook)介绍了更多日志钩子的使用细节。
325+
326+
```python
327+
log_config = dict(
328+
interval=50,
329+
hooks=[
330+
dict(type='TextLoggerHook'),
331+
dict(type='TensorboardLoggerHook')
332+
])
333+
```
334+
335+
#### 测试配置
336+
337+
测试配置 `evaluation` 可以用来初始化 [`EvalHook`](https://github.com/open-mmlab/mmpose/blob/master/mmpose/core/evaluation/eval_hooks.py#L11)
338+
除了参数 `interval`,其他参数(例如 `metric`)会被传递给 `dataset.evaluate()`
339+
340+
```python
341+
evaluation = dict(interval=1, metric='mAP')
342+
```

0 commit comments

Comments
 (0)