纯 Python 风格的配置

纯 Python 风格的配置#

纯 Python 风格的配置文件,即 lazy import 模式,它能够充分利用 Python 的语法规则,支持导出成 jsonyaml 格式。

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 方法会递归地去更新字段,而不是简单的覆盖。