Skip to content

Commit 2c949e4

Browse files
authored
Merge 6b4d9fa into 194c1c9
2 parents 194c1c9 + 6b4d9fa commit 2c949e4

File tree

2 files changed

+247
-2
lines changed

2 files changed

+247
-2
lines changed

README_zh-CN.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ MMSegmentation 是一个基于 PyTorch 的语义分割开源工具箱。它是 O
9090

9191
## 安装
9292

93-
请参考[快速入门文档](docs/get_started.md#installation)进行安装和数据集准备。
93+
请参考[快速入门文档](docs_zh-CN/get_started.md#installation)进行安装和数据集准备。
9494

9595
## 快速入门
9696

97-
请参考[训练教程](docs/train.md)[测试教程](docs/inference.md)学习 MMSegmentation 的基本使用。
97+
请参考[训练教程](docs_zh-CN/train.md)[测试教程](docs_zh-CN/inference.md)学习 MMSegmentation 的基本使用。
9898
我们也提供了一些进阶教程,内容覆盖了[增加自定义数据集](docs/tutorials/customize_datasets.md)[设计新的数据预处理流程](docs/tutorials/data_pipeline.md)[增加自定义模型](docs/tutorials/customize_models.md)[增加自定义的运行时配置](docs/tutorials/customize_runtime.md)
9999
除此之外,我们也提供了很多实用的[训练技巧说明](docs/tutorials/training_tricks.md)
100100

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,246 @@
11
# 教程 6: 自定义运行设定
2+
3+
## 自定义优化设定
4+
5+
### 自定义 PyTorch 支持的优化器
6+
7+
我们已经支持 PyTorch 自带的所有优化器,唯一需要修改的地方是在配置文件里的 `optimizer` 域里面。
8+
例如,如果您想使用 `ADAM` (注意如下操作可能会让模型表现下降),可以使用如下修改:
9+
10+
```python
11+
optimizer = dict(type='Adam', lr=0.0003, weight_decay=0.0001)
12+
```
13+
14+
为了修改模型的学习率,使用者仅需要修改配置文件里 optimizer 的 `lr` 即可。
15+
使用者可以参照 PyTorch 的 [API 文档](https://pytorch.org/docs/stable/optim.html?highlight=optim#module-torch.optim)
16+
直接设置参数。
17+
18+
### 自定义 自己实现的优化器
19+
20+
#### 1. 定义一个新的优化器
21+
22+
一个自定义的优化器可以按照如下去定义:
23+
24+
假如您想增加一个叫做 `MyOptimizer` 的优化器,它的参数分别有 `a`, `b`, 和 `c`
25+
您需要创建一个叫 `mmseg/core/optimizer` 的新文件夹。
26+
然后再在文件,即 `mmseg/core/optimizer/my_optimizer.py` 里面去实行这个新优化器:
27+
28+
```python
29+
from .registry import OPTIMIZERS
30+
from torch.optim import Optimizer
31+
32+
33+
@OPTIMIZERS.register_module()
34+
class MyOptimizer(Optimizer):
35+
36+
def __init__(self, a, b, c)
37+
38+
```
39+
40+
#### 2. 增加优化器到注册表 (registry)
41+
42+
为了让上述定义的模块被框架发现,首先这个模块应该被导入到主命名空间 (main namespace) 里。
43+
有两种方式可以实现它。
44+
45+
- 修改 `mmseg/core/optimizer/__init__.py` 来导入它。
46+
47+
新的被定义的模块应该被导入到 `mmseg/core/optimizer/__init__.py` 这样注册表将会发现新的模块并添加它。
48+
49+
```python
50+
from .my_optimizer import MyOptimizer
51+
```
52+
53+
- 在配置文件里使用 `custom_imports` 去手动添加它。
54+
55+
```python
56+
custom_imports = dict(imports=['mmseg.core.optimizer.my_optimizer'], allow_failed_imports=False)
57+
```
58+
59+
`mmseg.core.optimizer.my_optimizer` 模块将会在程序运行的开始被导入,并且 `MyOptimizer` 类将会自动注册。
60+
需要注意只有包含 `MyOptimizer` 类的包 (package) 应当被导入。
61+
`mmseg.core.optimizer.my_optimizer.MyOptimizer` **不能** 被直接导入。
62+
63+
事实上,使用者完全可以用另一个按这样导入方法的文件夹结构,只要模块的根路径已经被设置到 `PYTHONPATH` 里面。
64+
65+
#### 3. 在配置文件里定义优化器
66+
67+
之后您可以在配置文件的 `optimizer` 域里面使用 `MyOptimizer`
68+
在配置文件里,优化器被定义在 `optimizer` 域里,如下所示:
69+
70+
```python
71+
optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)
72+
```
73+
74+
为了使用您自己的优化器,这个域可以被改成:
75+
76+
```python
77+
optimizer = dict(type='MyOptimizer', a=a_value, b=b_value, c=c_value)
78+
```
79+
80+
### 自定义优化器的构造器 (constructor)
81+
82+
有些模型可能需要在优化器里有一些特别参数的设置,例如 批归一化层 (BatchNorm layers) 的 权重衰减 (weight decay)。
83+
使用者可以通过自定义优化器的构造器去微调这些细粒度参数。
84+
85+
```python
86+
from mmcv.utils import build_from_cfg
87+
88+
from mmcv.runner.optimizer import OPTIMIZER_BUILDERS, OPTIMIZERS
89+
from mmseg.utils import get_root_logger
90+
from .my_optimizer import MyOptimizer
91+
92+
93+
@OPTIMIZER_BUILDERS.register_module()
94+
class MyOptimizerConstructor(object):
95+
96+
def __init__(self, optimizer_cfg, paramwise_cfg=None):
97+
98+
def __call__(self, model):
99+
100+
return my_optimizer
101+
102+
```
103+
104+
默认的优化器构造器的实施可以参照 [这里](https://github.com/open-mmlab/mmcv/blob/9ecd6b0d5ff9d2172c49a182eaa669e9f27bb8e7/mmcv/runner/optimizer/default_constructor.py#L11) ,它也可以被用作新的优化器构造器的模板。
105+
106+
### 额外的设置
107+
108+
优化器没有实施的一些技巧应该通过优化器构造器 (optimizer constructor) 或者钩 (hook) 去实施,如设置基于参数的学习率 (parameter-wise learning rates)。我们列出一些常见的设置,它们可以稳定或加速模型的训练。
109+
如果您有更多的设置,欢迎在 PR 和 issue 里面提交。
110+
111+
- __使用梯度截断 (gradient clip) 去稳定训练__:
112+
一些模型需要梯度截断去稳定训练过程,如下所示:
113+
114+
```python
115+
optimizer_config = dict(
116+
_delete_=True, grad_clip=dict(max_norm=35, norm_type=2))
117+
```
118+
119+
如果您的配置继承自已经设置了 `optimizer_config` 的基础配置 (base config),您可能需要 `_delete_=True` 来重写那些不需要的设置。更多细节请参照 [配置文件文档](https://mmsegmentation.readthedocs.io/en/latest/config.html) 。
120+
121+
- __使用动量计划表 (momentum schedule) 去加速模型收敛__:
122+
我们支持动量计划表去让模型基于学习率修改动量,这样可能让模型收敛地更快。
123+
动量计划表经常和学习率计划表 (LR scheduler) 一起使用,例如如下配置文件就在 3D 检测里经常使用以加速收敛。
124+
更多细节请参考 [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) 的实施。
125+
126+
```python
127+
lr_config = dict(
128+
policy='cyclic',
129+
target_ratio=(10, 1e-4),
130+
cyclic_times=1,
131+
step_ratio_up=0.4,
132+
)
133+
momentum_config = dict(
134+
policy='cyclic',
135+
target_ratio=(0.85 / 0.95, 1),
136+
cyclic_times=1,
137+
step_ratio_up=0.4,
138+
)
139+
```
140+
141+
## 自定义训练计划表
142+
143+
我们根据默认的训练迭代步数 40k/80k 来设置学习率,这在 MMCV 里叫做 [`PolyLrUpdaterHook`](https://github.com/open-mmlab/mmcv/blob/826d3a7b68596c824fa1e2cb89b6ac274f52179c/mmcv/runner/hooks/lr_updater.py#L196) 。
144+
我们也支持许多其他的学习率计划表:[这里](https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/hooks/lr_updater.py) ,例如 `CosineAnnealing``Poly` 计划表。下面是一些例子:
145+
146+
- 步计划表 Step schedule:
147+
148+
```python
149+
lr_config = dict(policy='step', step=[9, 10])
150+
```
151+
152+
- 余弦退火计划表 ConsineAnnealing schedule:
153+
154+
```python
155+
lr_config = dict(
156+
policy='CosineAnnealing',
157+
warmup='linear',
158+
warmup_iters=1000,
159+
warmup_ratio=1.0 / 10,
160+
min_lr_ratio=1e-5)
161+
```
162+
163+
## 自定义工作流 (workflow)
164+
165+
工作流是一个专门定义运行阶数和轮数 (running order and epochs) 的阶段或轮数 (phase, epochs) 的列表。
166+
默认情况下它设置成:
167+
168+
```python
169+
workflow = [('train', 1)]
170+
```
171+
172+
意思是训练是跑 1 个 epoch。有时候使用者可能想检查模型在验证集上的一些指标(如 损失 loss,精确性 accuracy),我们可以这样设置工作流:
173+
174+
```python
175+
[('train', 1), ('val', 1)]
176+
```
177+
178+
于是 1 个 epoch 训练,1 个 epoch 验证将交替运行。
179+
180+
**注意**:
181+
182+
1. 模型的参数在验证的阶段不会被自动更新。
183+
2. 配置文件里的关键词 `total_epochs` 仅控制训练的 epochs 数目,而不会影响验证时的工作流。
184+
3. 工作流 `[('train', 1), ('val', 1)]``[('train', 1)]` 将不会改变 `EvalHook` 的行为,因为 `EvalHook``after_train_epoch`
185+
召唤而且验证的工作流仅仅影响通过 `after_val_epoch` 召唤的钩 (hooks)。因此, `[('train', 1), ('val', 1)]``[('train', 1)]`
186+
的区别仅在于 runner 将在每次训练 epoch 结束后计算在验证集上的损失。
187+
188+
## 自定义钩 (hooks)
189+
190+
### 使用 MMCV 实施的 钩 (hooks)
191+
192+
如果钩已经在 MMCV 里被实施,如下所示,您可以直接修改配置文件来使用钩:
193+
194+
```python
195+
custom_hooks = [
196+
dict(type='MyHook', a=a_value, b=b_value, priority='NORMAL')
197+
]
198+
```
199+
200+
### 修改默认的运行时间钩 (runtime hooks)
201+
202+
以下的常用的钩没有被 `custom_hooks` 注册:
203+
204+
- log_config
205+
- checkpoint_config
206+
- evaluation
207+
- lr_config
208+
- optimizer_config
209+
- momentum_config
210+
211+
在这些钩里,只有 logger hook 有 `VERY_LOW` 优先级,其他的优先级都是 `NORMAL`
212+
上述提及的教程已经包括了如何修改 `optimizer_config``momentum_config``lr_config`
213+
这里我们展示我们如何处理 `log_config``checkpoint_config``evaluation`
214+
215+
#### 检查点配置文件 (Checkpoint config)
216+
217+
MMCV runner 将使用 `checkpoint_config` 去初始化 [`CheckpointHook`](https://github.com/open-mmlab/mmcv/blob/9ecd6b0d5ff9d2172c49a182eaa669e9f27bb8e7/mmcv/runner/hooks/checkpoint.py#L9).
218+
219+
```python
220+
checkpoint_config = dict(interval=1)
221+
```
222+
223+
使用者可以设置 `max_keep_ckpts` 来仅保存一小部分检查点或者通过 `save_optimizer` 来决定是否保存优化器的状态字典 (state dict of optimizer)。 更多使用参数的细节请参考 [这里](https://mmcv.readthedocs.io/en/latest/api.html#mmcv.runner.CheckpointHook) 。
224+
225+
#### 日志配置文件 (Log config)
226+
227+
`log_config` 包裹了许多日志钩 (logger hooks) 而且能去设置间隔 (intervals)。现在 MMCV 支持 `WandbLoggerHook``MlflowLoggerHook``TensorboardLoggerHook`
228+
详细的使用请参照 [文档](https://mmcv.readthedocs.io/en/latest/api.html#mmcv.runner.LoggerHook) 。
229+
230+
```python
231+
log_config = dict(
232+
interval=50,
233+
hooks=[
234+
dict(type='TextLoggerHook'),
235+
dict(type='TensorboardLoggerHook')
236+
])
237+
```
238+
239+
#### 评估配置文件 (Evaluation config)
240+
241+
`evaluation` 的配置文件将被用来初始化 [`EvalHook`](https://github.com/open-mmlab/mmsegmentation/blob/e3f6f655d69b777341aec2fe8829871cc0beadcb/mmseg/core/evaluation/eval_hooks.py#L7) 。
242+
除了 `interval` 键,其他的像 `metric` 这样的参数将被传递给 `dataset.evaluate()`
243+
244+
```python
245+
evaluation = dict(interval=1, metric='mIoU')
246+
```

0 commit comments

Comments
 (0)