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"

描述: $ 后面跟着导入语句的处理方式与 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_ 指定引用(以 @ 开头的字符串)或 Python 表达式,这些引用或表达式将在 _target_ 对象实例化之前进行评估/实例化。当组件不通过其参数明确依赖于其他 ConfigItems,但需要先实例化/评估依赖项时,这非常有用。

  • _disabled_ 指定一个标志,指示是否跳过实例化。

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

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

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

    • "callable" – 返回一个可调用对象,可以是 _target_ 本身,或者如果提供了 kwargs,则作为 functools.partial(_target_, **kwargs) 的偏函数。这对于定义将在以后实例化或调用的类或函数很有用。用户可以预定义 _target_ 的一些参数,然后在以后用附加参数调用它。

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

多个配置文件#

描述: 可以在命令行上指定多个配置文件。这些配置文件的内容将被合并。当多个配置文件中指定了相同的键时,与该键关联的值将按照配置文件指定的顺序被覆盖。如果期望的行为是合并两个文件中的值,则第二个配置文件中的键应以 + 为前缀。合并内容的价值类型必须匹配,并且都必须是 dict 或都必须是 list 类型。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 是以下之一:runverify_metadatackpt_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 的(可选)依赖项,请确保提供安装说明给用户。

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

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