MONAI Bundle 配置#

monai.bundle 模块支持通过结构化配置构建基于 Python 的工作流。

主要有三大优势:

  • 通过将系统参数设置与 Python 代码分离,提供了良好的可读性和易用性。

  • 以相对高层级描述工作流,并允许使用不同的底层实现。

  • 联邦学习和 AutoML 等高层级学习范式可以与组件细节解耦。

目录

基础示例#

作为工作流一部分的组件可以使用 JSONYAML 语法指定,例如,网络架构定义可以存储在包含以下内容的 demo_config.json 文件中:

{
  "demo_net": {
    "_target_": "monai.networks.nets.BasicUNet",
    "spatial_dims": 3,
    "in_channels": 1,
    "out_channels": 2,
    "features": [16, 16, 32, 32, 64, 64]
  }
}

或者使用 YAML 格式(demo_config.yaml):

demo_net:
  _target_: monai.networks.nets.BasicUNet
  spatial_dims: 3
  in_channels: 1
  out_channels: 2
  features: [16, 16, 32, 32, 64, 64]

配置解析器可以将组件实例化为 Python 对象:

>>> from monai.bundle import ConfigParser
>>> config = ConfigParser()
>>> config.read_config("demo_config.json")
>>> net = config.get_parsed_content("demo_net", instantiate=True)
BasicUNet features: (16, 16, 32, 32, 64, 64).
>>> print(type(net))
<class 'monai.networks.nets.basic_unet.BasicUNet'>

或者额外调整输入参数后再实例化组件:

>>> config["demo_net"]["features"] = [32, 32, 32, 64, 64, 64]
>>> net = config.get_parsed_content("demo_net", instantiate=True)
BasicUNet features: (32, 32, 32, 64, 64, 64).

有关 ConfigParser API 的更多详细信息,请参阅 monai.bundle.ConfigParser

语法示例详解#

除了普通文本外,还有一些字符和关键字会被特殊解释,以下是语法示例:

在配置中引用 Python 对象#

"@preprocessing::transforms::keys"

描述: @ 字符表示引用 preprocessing::transforms::keys 中定义的另一个配置值。其中 :: 表示该配置文件的子结构。(#:: 的同义词,preprocessing#transforms#keys 指向同一个对象。)

"@preprocessing::1"

描述: 1 被视为整数引用,用于索引(从零开始)preprocessing 子结构。

通过以 # 开头的引用支持相对引用。例如,@#A 表示使用同一配置结构层级下的 A,而 @##A 指向上方一级层级中的 A

评估为 Python 表达式#

"$print(42)"

描述: $ 是一个特殊字符,表示在运行时执行 print(42)

"$[i for i in @datalist]"

描述: 使用 datalist 中的值作为输入,在运行时创建一个列表。

"$from torchvision.models import resnet18"

描述: $ 后跟 import 语句的处理方式与普通 Python 表达式略有不同。导入的模块 resnet18 将作为全局变量提供给其他配置部分。这是为了简化在配置中使用外部模块。

配置表达式可以使用 @ 来引用其他配置项。例如,在 $lambda x: x + @a + @b 中,@a@b 是对其他 Python 对象的引用,并作为“全局变量”提供给匿名函数。因此,可以在表达式中修改 Python 对象,例如 $lambda x: @my_list.pop() + x 将从 @my_list 中弹出最后一个元素并将其加到 x 上。

文本替换配置元素#

"%demo_config.json::demo_net::in_channels"

描述: % 字符表示一个宏,用于将当前配置元素替换为 demo_config.json 文件中 demo_net::in_channels 的文本。替换发生在实例化或评估组件之前。

实例化 Python 对象#

{
  "demo_name":{
    "_target_": "my.python.module.Class",
    "args1": "string",
    "args2": 42}
}

描述: 该字典定义了一个引用名称为 demo_name 的对象,其可实例化类型在 _target_ 中指定,并带有输入参数 args1args2。该字典将在运行时被实例化为 Pytorch 对象。

_target_ 是 MONAI Bundle 语法中指定 Python 对象名称的必要键。args1args2 应与要实例化的 Python 对象兼容。

{
  "component_name": {
    "_target_": "my.module.Class",
    "_desc_": "this is a customized class which also triggers 'cudnn_opt' reference",
    "_requires_": "@cudnn_opt",
    "_disabled_": "true",
    "_mode_":  "default"}
}

描述: _requires_, _disabled_, _desc__mode_ 是可选键。

  • _requires_ 指定在实例化 _target_ 对象之前需要评估/实例化的引用(以 @ 开头的字符串)或 Python 表达式。当组件不通过参数显式依赖其他 ConfigItems,但需要先实例化/评估依赖项时,这非常有用。

  • _disabled_ 指定是否跳过实例化的标志。

  • _desc_ 可用于提供自由文本描述。

  • _mode_ 指定实例化组件或调用可调用对象时的操作模式。目前支持以下值:

    • "default" (默认) – 返回 _target_(**kwargs) 的返回值。

    • "callable" – 返回一个可调用对象,要么是 _target_ 本身,如果提供了 kwargs,则作为 functools.partial(_target_, **kwargs) 的偏函数。适用于定义稍后将实例化或调用的类或函数。用户可以预定义 _target_ 的某些参数,并在稍后使用附加参数进行调用。

    • "debug" – 使用调试提示符执行并返回 pdb.runcall(_target_, **kwargs) 的返回值,另请参阅 pdb.runcall

多个配置文件#

描述: 可以在命令行中指定多个配置文件。这些配置文件的内容会被合并。当多个配置文件中指定了相同的键时,该键关联的值将被按指定顺序覆盖。如果期望的行为是合并两个文件中的值,则第二个配置文件中的键应加上 + 前缀。合并内容的值类型必须匹配且均为 dictlist 类型。dict 值将通过 update() 合并,list 值通过 extend() 连接。这是一个示例。在此情况下,“amp”值将被 extra_config.json 覆盖。importspreprocessing#transforms 列表将被合并。如果 "+imports" 中的值类型不是 list,则会抛出错误。

config.json

{
    "amp": "$True"
    "imports": [
	"$import torch"
    ],
    "preprocessing": {
        "_target_": "Compose",
        "transforms": [
	  "$@t1",
	  "$@t2"
        ]
    },
}

extra_config.json

{
    "amp": "$False"
    "+imports": [
	"$from monai.networks import trt_compile"
    ],
    "+preprocessing#transforms": [
        "$@t3"
    ]
}

命令行界面#

除了 Python API 外,还提供了一些命令行界面 (CLI) 来与 bundle 进行交互。主要用法是:

python -m monai.bundle COMMANDS

其中 COMMANDS 为以下之一:run, verify_metadata, ckpt_export, …(请参阅 python -m monai.bundle --help 获取可用选项列表)。

CLI 支持灵活的用例,例如在运行时覆盖配置和在文件中预定义参数。要显示命令(例如 run)的使用页面:

python -m monai.bundle run -- --help

此支持由 Python Fire 提供,请确保安装了该可选依赖项,例如使用 pip install monai[fire]pip install fire。有关 CLI 参数解析的详细信息,请参阅 Python Fire 指南

建议#

  • 支持 YAMLJSON,但不支持这些格式的高级特性。

  • 为配置元素使用有意义的名称可以提高可读性。

  • 虽然可以使用 Bundle 语法构建复杂的配置,但更推荐使用结构简单、少量使用表达式或引用的配置。

  • 对于配置中的 $import <module>,如果 <module> 不是 MONAI 的(可选)依赖项,请确保提供用户安装该 <module> 的说明。

  • 由于 #, ::$ 可能会被 shellCLI 工具以不同方式解释,在命令行中可能需要添加转义字符或引号,例如:"\$torch.device('cuda:1')", "'train_part#trainer'"

  • 有关更多详细信息和示例,请参阅 教程