MONAI Bundle 配置#
monai.bundle
模块支持通过结构化配置构建基于 Python 的工作流。
主要优点有三方面:
它通过将系统参数设置与 Python 代码分离,提供了良好的可读性和可用性。
它在较高层面描述工作流,并允许不同的底层实现。
更高层面的学习范式,例如联邦学习和 AutoML,可以与组件细节解耦。
内容
一个基本示例#
工作流中的组件可以使用 JSON
或 YAML
语法指定,例如,网络架构定义可以存储在 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_
指定,输入参数为 args1
和 args2
。该字典将在运行时实例化为一个 Pytorch 对象。
_target_
是 monai bundle 语法中指定 Python 对象名称的必需键。args1
和 args2
应与要实例化的 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 覆盖。imports
和 preprocessing#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 指南。
建议#
支持
YAML
和JSON
,但不支持这些格式的高级特性。为配置元素使用有意义的名称可以提高可读性。
虽然可以使用 bundle 语法构建复杂的配置,但更推荐使用表达式或引用稀疏的简单结构。
对于配置中的
$import <module>
,如果<module>
不是 MONAI 的(可选)依赖项,请确保提供安装说明给用户。由于
#
、::
和$
可能会被shell
或CLI
工具以不同的方式解释,可能需要在命令行中为它们添加转义字符或引号,例如:"\$torch.device('cuda:1')"
、"'train_part#trainer'"
。有关更多详细信息和示例,请参阅 教程。