纯 Python 风格的配置#
纯 Python 风格的配置文件,即 lazy import
模式,它能够充分利用 Python 的语法规则,支持导出成 json
和 yaml
格式。
from pathlib import Path
import sys
temp_dir = Path(".temp")
sys.path.extend([str(temp_dir)])
temp_dir.mkdir(exist_ok=True)
模块构建#
配置文件写法:
%%file {temp_dir}/optimizer.py
from torch.optim import SGD
optimizer = dict(type=SGD, lr=0.1)
Writing .temp/optimizer.py
构建流程:
import torch.nn as nn
from mmengine.config import Config
from mmengine.registry import OPTIMIZERS
cfg = Config.fromfile(f'{temp_dir}/optimizer.py')
model = nn.Conv2d(1, 1, 1)
cfg.optimizer.params = model.parameters()
optimizer = OPTIMIZERS.build(cfg.optimizer)
继承配置#
纯 Python 风格的配置文件通过 import
语法来实现继承,这样做的好处是,可以直接跳转到被继承的配置文件中,方便阅读和跳转。变量的继承规则(增删改查)完全对齐 Python 语法,例如我想修改 base
配置文件中 optimizer
的学习率:
from mmengine.config import read_base
with read_base():
from .optimizer import *
# optimizer 为 base 配置文件定义的变量
optimizer.update(
lr=0.01,
)
备注
需要注意的是,纯 Python 风格的配置文件中,字典的 update
方法与 dict.update()
稍有不同。纯 Python 风格的 update
会递归地去更新字典中的内容,例如:
x = dict(a=1, b=dict(c=2, d=3))
x.update(dict(b=dict(d=4)))
# 配置文件中的 update 规则:
# {a: 1, b: {c: 2, d: 4}}
# 普通 dict 的 update 规则:
# {a: 1, b: {d: 4}}
可见在配置文件中使用 update
方法会递归地去更新字段,而不是简单的覆盖。