MONAI Bundle 规范#
概述#
这是 MONAI Bundle (MB) 格式的规范,用于描述可移植的深度学习模型。MB 的目标是定义一个封装好的网络或模型,其中包含让用户和程序了解如何使用该模型及其用途所需的关键信息。一个 Bundle 包含存储为 pickled 状态字典(state dictionary)的单个网络权重,以及可选的 Torchscript 对象和/或 ONNX 对象。此外还包含 JSON 文件,用于存储关于模型的元数据、构建训练、推理和后处理转换序列的信息、纯文本说明、法律信息以及模型创建者希望包含的其他数据。
本规范定义了 Bundle 必须具备的目录结构以及必须包含的必要文件。其他文件也可以被包含在内,目录可以打包成 zip 文件,或者作为额外文件直接包含在 Torchscript 文件中。
目录结构#
MONAI Bundle 主要定义为一个目录,其中包含一组专门命名的子目录,用于存放模型、元数据文件和许可证。根目录应以模型名称命名,在本例中称为“ModelName”,并应包含以下结构:
ModelName
┣━ LICENSE
┣━ configs
┃ ┗━ metadata.json
┣━ models
┃ ┣━ model.pt
┃ ┣━ *model.ts
┃ ┗━ *model.onnx
┗━ docs
┣━ *README.md
┗━ *license.txt
为了使目录构成一个有效的 Bundle,必须包含以下必需文件(文件名必须固定):
LICENSE:软件本身的许可证,包含配置文件和模型权重。
metadata.json:JSON 格式的元数据信息,涉及模型类型、输入和输出张量的定义、模型及所用软件的版本,以及下文描述的其他信息。
model.pt:已保存模型的状态字典;实例化模型所需的信息必须在元数据文件中找到。
以下文件是可选的,但如果存在,必须使用上述目录中给出的文件名:
model.ts:如果模型可以正确保存为此格式,则为 Torchscript 保存的模型。
model.onnx:如果模型可以正确保存为此格式,则为 ONNX 模型。
README.md:以 Markdown 格式编写的关于模型、如何使用模型、作者信息等的通俗语言说明。
license.txt:附加到数据的软件许可证;如果不需要许可证,可以留空。
其他文件可以包含在上述任何目录中。例如,configs 可以包含进一步的配置 JSON 或 YAML 文件,用于定义训练或推理脚本、覆盖配置值、定义网络实例化等。一个常见的包含文件是 inference.json,它用于定义一个基本的推理脚本,该脚本使用存储的网络和输入文件来生成预测输出文件。
归档格式#
Bundle 目录及其内容可以压缩成一个 zip 文件,构成一个单一的文件包。当解压到一个目录时,此文件将重现上述目录结构,并且其本身也应以其包含的模型命名。例如,ModelName.zip 至少应包含 ModelName/configs/metadata.json 和 ModelName/models/model.pt。因此,解压时会将文件放置在 ModelName 目录中,而不是当前工作目录中。
Torchscript 文件格式本身也是一个具有特定结构的 zip 文件。使用 save_net_with_metadata 创建此类归档文件时,可以通过将 metadata.json 的内容作为函数的 meta_values 参数包含,并将其他文件作为 more_extra_files 条目包含,来创建符合 MB 标准的 Torchscript 文件。这些文件将存储在 zip 文件的 extras 目录中,并可以通过 load_net_with_metadata 或任何其他能够读取 zip 数据的库/工具检索。在此格式中,model.* 文件显然是不需要的,但 README.md、license.txt 以及提供的任何其他文件可以作为额外的 extras 文件添加。
MONAI 的 bundle 子模块包含许多命令行程序。要生成 Torchscript bundle,请结合一组指定组件(例如保存的权重文件和元数据文件)使用 ckpt_export。配置文件可以作为定义 ConfigParser 使用的 Python 结构的 JSON 或 YAML 字典提供,但无论格式如何,生成的 bundle Torchscript 对象都将以 JSON 格式存储这些文件。
metadata.json 文件#
该文件包含与模型相关的元数据信息,包括输入和输出的形状与格式、输出的含义、所处模型的类型以及其他信息。JSON 结构是一个字典,包含一组定义的键以及用户指定的其他键。强制键如下:
version:存储模型的版本,这允许区分同一模型的多个版本。版本应遵循语义化版本控制,并且仅包含文件名中合法的字符,因为我们可能会将版本包含在 bundle 文件名中。
monai_version:生成该 bundle 时所用的 MONAI 版本,预期后续版本也能正常工作。
pytorch_version:生成该 bundle 时所用的 Pytorch 版本,预期后续版本也能正常工作。
numpy_version:生成该 bundle 时所用的 Numpy 版本,预期后续版本也能正常工作。
required_packages_version:将所需包名与其版本相关联的字典。这些是除 MONAI 基础要求之外,该 bundle 绝对需要的包。例如,如果 bundle 必须加载 Nifti 文件,则需要 Nibabel 包。
task:关于模型预期用途的通俗语言描述。
description:关于模型是什么、做什么等的更详细的通俗语言描述。
authors:声明模型的作者。
copyright:声明模型的版权。
network_data_format:定义(主)模型输入和输出的格式、形状和含义,包含“inputs”和“outputs”键,将命名的输入/输出与其格式说明符(定义如下)相关联。还有一个可选的“post_processed_outputs”键,说明应用后处理转换后“outputs”的格式;这用于描述如果 bundle 的最终输出与原始网络输出不同时的最终输出。这些键也可以关联到原始值(数字、字符串、布尔值),而不是下面指定的张量格式。
张量格式说明符用于定义输入和输出张量及其含义,并且必须是一个至少包含以下键的字典:
type:张量代表的数据类型:“image”代表任何空间规则数据,无论是实际图像还是仅具有该形状的数据;“series”代表值的时间序列(例如信号);“tuples”代表由已知数量值定义的一系列项(例如 ND 空间中的 N 维点);“probabilities”代表一组概率(例如分类器输出),这对于解释数据的维度和形状代表什么以及允许用户推测如何绘制数据非常有用。
format:存储什么格式的信息,已知格式列表见下文。
modality:描述模态、协议类型、捕获技术种类或数据中未通过其类型或格式描述的其他属性,已知模态有“MR”、“CT”、“US”、“EKG”,但也可以包含任何自定义类型或协议类型(例如“T1”),默认值为“n/a”。
num_channels:张量具有的通道数,假设通道维度优先。
spatial_shape:空间维度的形状,格式为“[H]”、“[H, W]”或“[H, W, D]”,H、W 和 D 的可能值见下文。
dtype:张量的数据类型,例如“float32”、“int32”。
value_range:输入数据预期具有的最小值和最大值,格式为“[MIN, MAX]”,如果未知则为“[]”。
is_patch_data:如果数据是输入/输出张量的补丁或整个张量,则为“true”,否则为“false”。
channel_def:将通道索引与通道包含内容的通俗语言描述相关联的字典。
可选键:
changelog:将以前的版本名称与描述该版本的字符串相关联的字典。
intended_use:模型用于什么,即它完成了什么任务。
data_source:关于训练/验证数据来源的描述。
data_type:用于训练/验证的源数据类型。
references:与模型相关的已发表参考资料列表。
supported_apps:使用 bundle 的受支持应用程序列表,例如,如果 bundle 与 MONAI Label 应用程序兼容,则会包含 ‘monai-label’。
*_data_format:定义次要模型的输入和输出的格式、形状和含义。这包含与 network_data_format 相同种类的信息,用于描述提供辅助功能的网络,例如,在数据发送到此 bundle 的主网络之前,用于识别图像中的 ROI 以进行裁剪的定位网络。
用作输入和输出的张量格式可用于指定这些值的语义含义,稍后由处理 bundle 的软件使用,以确定如何处理和解释此数据。MONAI 使用多种类型的图像数据,以及其他数据类型,如点云、字典序列、时间信号等。以下列表提供了一组支持的张量“format”定义,但并不详尽,用户可以提供自己的定义,由模型用户自行解释。
magnitude:具有一个或多个通道的连续量值 ND 场,例如具有 1 个通道的 MR T1 图像或具有 3 个通道的自然 RGB 图像。
hounsfield:以 Hounsfield 单位给出的半分类值 ND 场,例如 CT 图像。
kspace:与 MR 成像相关的 2D/3D 傅里叶变换图像。
raw:被认为来自图像采集设备未经处理的值的 ND 场,例如直接来自 MR 扫描仪而未进行重建或其他处理。
labels:具有 N 个 one-hot 通道的 ND 分类图像,用于 N 类分割/标签,“channel_def”用通俗语言说明了每个通道的解释,对于每个像素/体素,预测的标签是最大通道值的索引。
classes:具有 N 个通道的 ND 分类图像,用于 N 类类别,“channel_def”用通俗语言说明了每个通道的解释,这允许进行多类标记,因为通道不需要是 one-hot 编码的。
segmentation:具有一个通道的 ND 分类图像,将每个像素/体素分配给“channel_def”中描述的标签。
points:ND 空间中的点/节点/坐标/顶点/向量列表,形状为 [I, N],表示 I 个点,具有 N 个维度。
normals:ND 空间中的向量列表(可能是单位长度),形状为 [I, N],表示 I 个向量,具有 N 个维度。
indices:指向顶点数组和/或其他表示一组形状的数组的索引列表,形状为 [I, N],表示由 N 个值定义的 I 个形状。
sequence:具有一个或多个通道的时间相关值序列,例如信号或字典查找句子,形状为 [C, N],表示在 N 个时间点上的 C 个数据通道。
latent:来自网络某一层潜空间的 ND 张量数据。
gradient:来自网络某一层梯度的 ND 张量。
对于接受不同形状输入的模型,空间形状定义可能很复杂,特别是如果对这些形状有特定条件的话。形状被指定为正整数(固定大小)列表或包含定义大小依赖条件的表达式的字符串列表。这可以是“*”(表示任何大小),或者使用带有 Python 数学运算符和单字符变量的表达式来表示对未知数量的依赖。例如,“2**p”表示大小必须是 2 的幂,“2**p*n”必须是 2 的幂的倍数。变量在维度表达式之间共享,空间形状示例:[“*”, “16*n”, “2**p*n”]。
用于验证此文件的 JSON 模式的下载链接可以在其中找到,键名为“schema”。
一个 JSON 元数据文件示例
{
"schema": "https://github.com/Project-MONAI/MONAI-extra-test-data/releases/download/0.8.1/meta_schema_20220324.json",
"version": "0.1.0",
"changelog": {
"0.1.0": "complete the model package",
"0.0.1": "initialize the model package structure"
},
"monai_version": "0.9.0",
"pytorch_version": "1.10.0",
"numpy_version": "1.21.2",
"required_packages_version": {"nibabel": "3.2.1"},
"task": "Decathlon spleen segmentation",
"description": "A pre-trained model for volumetric (3D) segmentation of the spleen from CT image",
"authors": "MONAI team",
"copyright": "Copyright (c) MONAI Consortium",
"data_source": "Task09_Spleen.tar from http://medicaldecathlon.com/",
"data_type": "dicom",
"image_classes": "single channel data, intensity scaled to [0, 1]",
"label_classes": "single channel data, 1 is spleen, 0 is everything else",
"pred_classes": "2 channels OneHot data, channel 1 is spleen, channel 0 is background",
"eval_metrics": {
"mean_dice": 0.96
},
"intended_use": "This is an example, not to be used for diagnostic purposes",
"references": [
"Xia, Yingda, et al. '3D Semi-Supervised Learning with Uncertainty-Aware Multi-View Co-Training.' arXiv preprint arXiv:1811.12506 (2018). https://arxiv.org/abs/1811.12506.",
"Kerfoot E., Clough J., Oksuz I., Lee J., King A.P., Schnabel J.A. (2019) Left-Ventricle Quantification Using Residual U-Net. In: Pop M. et al. (eds) Statistical Atlases and Computational Models of the Heart. Atrial Segmentation and LV Quantification Challenges. STACOM 2018. Lecture Notes in Computer Science, vol 11395. Springer, Cham. https://doi.org/10.1007/978-3-030-12029-0_40"
],
"network_data_format":{
"inputs": {
"image": {
"type": "image",
"format": "magnitude",
"modality": "MR",
"num_channels": 1,
"spatial_shape": [160, 160, 160],
"dtype": "float32",
"value_range": [0, 1],
"is_patch_data": false,
"channel_def": {"0": "image"}
}
},
"outputs":{
"pred": {
"type": "image",
"format": "labels",
"num_channels": 2,
"spatial_shape": [160, 160, 160],
"dtype": "float32",
"value_range": [],
"is_patch_data": false,
"channel_def": {"0": "background", "1": "spleen"}
}
}
}
}