- 人工智能
- 深度学习
- 计算机视觉
- 医疗健康
【免费下载链接】nnUNet
导读
本文是 nnU-Net 从 V1 迁移到 V2 的速查指南,面向已经使用过旧版 nnU-Net、希望平滑升级到当前仓库nnunetv2的用户。文章以仓库中的 documentation/tldr_migration_guide_from_v1.md 为核心骨架,结合环境变量配置、数据集格式、region-based 训练说明以及pyproject.toml中的命令注册源码,逐条讲解 V2 与 V1 的差异、迁移工具的正确用法,以及从规划预处理到推理后处理的完整命令行工作流。读完本文,你将能把自己的 V1 Task 数据集转换为 V2 Dataset 格式,并独立跑通nnUNetv2_plan_and_preprocess → nnUNetv2_train → nnUNetv2_find_best_configuration → nnUNetv2_predict → nnUNetv2_apply_postprocessing全流程。
V2 与 V1 可以共存:互不干扰的安装与并行使用
迁移的第一步并不需要卸载旧版本。官方 TLDR 指南明确指出:nnU-Net V2 可以与 V1 同时安装在同一环境中,二者不会互相干扰。原因在于:
- V2 的代码包名为
nnunetv2(见 pyproject.toml 中[tool.setuptools.packages.find]的include = ["nnunetv2*"]),与 V1 的nnunet包完全隔离; - V2 的所有命令行工具都以
nnUNetv2开头(详见下文),不会与 V1 的nnUNet_*命令冲突; - V2 使用独立的环境变量名(
nnUNet_raw/nnUNet_preprocessed/nnUNet_results),存储原始数据、预处理数据和训练结果的目录与 V1 的nnUNet_raw_data_base等默认路径不冲突。
因此,你在迁移期间可以放心地继续用 V1 处理旧模型推理,同时用 V2 训练新数据集。
环境变量:名称不同,职责相同
V1 迁移到 V2 后,环境变量的命名发生了变化,这是最容易踩坑的地方。根据 documentation/setting_up_paths.md,V2 需要以下三个核心环境变量:
| 环境变量 | 用途 | 存放内容 |
|---|---|---|
nnUNet_raw | 原始数据目录 | 每个数据集一个子文件夹,命名形如DatasetXXX_YYY |
nnUNet_preprocessed | 预处理数据目录 | 预处理后的数据,训练时也从此目录读取;建议放在低延迟高吞吐的 NVMe SSD 上 |
nnUNet_results | 模型权重目录 | 训练得到的模型权重;下载预训练模型时也保存在这里 |
其中nnUNet_raw下的目录结构为:
nnUNet_raw/Dataset001_NAME1 ├── dataset.json ├── imagesTr ├── imagesTs # 可选 └── labelsTr nnUNet_raw/Dataset002_NAME2 ├── dataset.json ├── imagesTr ├── imagesTs # 可选 └── labelsTr在 Linux/macOS 下,可将以下内容追加到~/.bashrc(zsh 用户是~/.zshrc)实现永久生效:
export nnUNet_raw="/media/fabian/nnUNet_raw" export nnUNet_preprocessed="/media/fabian/nnUNet_preprocessed" export nnUNet_results="/media/fabian/nnUNet_results"也可以每次临时设置,或直接以前缀方式给单条命令注入变量:
nnUNet_results="/media/fabian/nnUNet_results" nnUNet_preprocessed="/media/fabian/nnUNet_preprocessed" nnUNetv2_train [...]Windows 下 PowerShell 使用$Env:nnUNet_raw = "C:/Users/fabian/nnUNet_raw",Command Prompt 使用set nnUNet_raw=C:/Users/fabian/nnUNet_raw。验证是否设置成功,Linux/macOS 执行echo ${nnUNet_raw},PowerShell 执行echo $Env:nnUNet_raw,Command Prompt 执行echo %nnUNet_raw%。
此外还有一个可选的nnUNet_extTrainer变量:当需要从nnunetv2包外部加载自定义nnUNetTrainer子类(例如运行别人用自定义 trainer 训练的模型做推理)时,将其设置为包含 trainer 代码的一个或多个目录,多个目录用系统路径分隔符(Linux/macOS 用:,Windows 用;)隔开。完整说明见 documentation/how-to/share-models-with-custom-trainers.md。
核心命名变化:Task 变成 Dataset
V1 中数据集被称为TaskXXX_YYY(如Task027_ACDC),V2 中统一改名为DatasetXXX_NAME(如Dataset027_ACDC)。其中XXX是三位数据集 ID(如 001、002、043、999),NAME是自定义的数据集名称。这一命名的改变贯穿所有命令:nnUNetv2_train 2 3d_fullres 0中的2会被自动解析为Dataset002_*(见 run_training.py 中get_trainer_from_args对输入 ID/名称的转换逻辑,maybe_convert_to_dataset_name 负责 ID 到名称的换算)。
数据集结构:目录不变,能力更强
目录骨架保持一致
V2 数据集仍沿用 V1 的三件套结构:imagesTr(训练图像)、labelsTr(训练标签)与dataset.json(元数据),imagesTs可选存放测试图像(nnU-Net 不会使用它,仅是遗留自 MSD 的存放习惯)。以 MSD 的 BrainTumour 数据集为例:
nnUNet_raw/Dataset001_BrainTumour/ ├── dataset.json ├── imagesTr │ ├── BRATS_001_0000.nii.gz # FLAIR │ ├── BRATS_001_0001.nii.gz # T1w │ ├── BRATS_001_0002.nii.gz # T1gd │ ├── BRATS_001_0003.nii.gz # T2w │ └── ... ├── imagesTs │ └── ... └── labelsTr ├── BRATS_001.nii.gz └── ...图像命名遵循{CASE_IDENTIFIER}_{XXXX}.{FILE_ENDING}约定,其中XXXX是四位通道/模态标识符(如0000表示 T1、0001表示 T2),标签命名为{CASE_IDENTIFIER}.{FILE_ENDING}。同一训练病例的所有输入通道必须具有相同几何信息(形状、spacing 等)并已完成配准。
支持更多文件格式(V2 最大变化之一)
V2 通过BaseReaderWriter抽象了图像/分割图的读写,不再强制把所有数据转成.nii.gz。默认支持的格式包括(详见 documentation/dataset_format.md 与 nnunetv2/imageio/readme.md):
- NaturalImage2DIO:
.png、.bmp、.tif、.tiff(2D 自然图像,RGB 三通道可存于同一文件) - NibabelIO:
.nii.gz、.nrrd、.mha - NibabelIOWithReorient:
.nii.gz、.nrrd、.mha(会重定向到 RAS 坐标系) - SimpleITKIO:
.nii.gz、.nrrd、.mha - Tiff3DIO:
.tif、.tiff(3D TIFF 栈,需同名.json文件提供 spacing 信息)
需要注意两个限制:一是图像与分割图必须使用同一格式(不能训练.png却在推理时用.jpg);二是只能使用无损压缩格式(不能有.jpg之类的有损格式,以免破坏分割标签)。内部预处理存储会使用 nnU-Net 自有格式,与原始输入格式无关,这是出于性能考虑。
额外的好处是:V2原生支持 2D 输入图像,不再需要把 2D 数据转成伪 3D nifti。2D 数据集的转换范例见 Dataset120_RoadSegmentation.py。
dataset.json 被大幅简化
V2 的dataset.json相比 V1 精简了很多字段,示例(MSD Prostate):
{ "channel_names": { "0": "T2", "1": "ADC" }, "labels": { "background": 0, "PZ": 1, "TZ": 2 }, "numTraining": 32, "file_ending": ".nii.gz", "overwrite_image_reader_writer": "SimpleITKIO" }V1 迁移到 V2 时的字段变化要点:
modality改名为channel_names——去掉对医学图像的强偏向,同时channel_names会影响归一化策略:标记为CT的通道使用基于前景强度的全局归一化,其他名称的通道使用逐通道 z-score 归一化;labels的键值方向反转——V1 是value: name,V2 是name: value,这是为了支持 hierarchical/region-based 训练(详见下节);- 新增
file_ending——用于声明数据集采用的文件扩展名,支持不同输入文件类型; - 新增可选的
overwrite_image_reader_writer——可指定某个(自定义)ReaderWriter 类;不提供时 nnU-Net 自动选择; regions_class_order——仅 region-based 训练时使用。
官方推荐使用工具函数自动生成dataset.json,即nnunetv2.dataset_conversion.generate_dataset_json模块中的 generate_dataset_json(可通过from nnunetv2.dataset_conversion.generate_dataset_json import generate_dataset_json调用)。该函数的关键参数包括:
channel_names: dict——通道索引到通道名的映射,注意索引会被强制转为字符串键;labels: dict——标签名到整数值(或整数元组)的映射,nnU-Net 要求值连续且0为背景;若值出现(1, 2, 3)形式的元组,则视为 region-based 训练,此时必须同时提供regions_class_order,否则函数会直接断言报错;num_training_cases: int——用于核对训练病例是否齐全;file_ending: str——图像与分割图必须一致;overwrite_image_reader_writer——需要特殊 IO 类时,可继承BaseReaderWriter后按名称在此引用;- 其余
dataset_name、reference、release、license、description、citation等字段仅为元数据完备性,不会被 nnU-Net 使用;**kwargs中的内容会原样写入dataset.json。
dataset_conversion目录(nnunetv2/dataset_conversion)下还有大量数据集转换示例脚本(MSD、BraTS、ACDC、AMOS、KiTS2023、AutoPETII、ToothFairy2 等),不能直接运行(需要修改路径),但非常适合作为自定义数据集转换的模板。
labels 键值反转背后的原因:Region-based 训练
V2 将labels从{0: "name"}改为{"name": 0},直接动机是支持 region-based training(区域化训练,用于处理重叠/层级标签)。在 V1 的标签表示下,一个像素只能属于一个语义类;而 region-based 训练允许目标区域由多个标签合并而成。
以 BraTS 为例,常规标签声明为:
"labels": { "background": 0, "edema": 1, "non_enhancing_and_necrosis": 2, "enhancing_tumor": 3 }region-based 训练则改为:
"labels": { "background": 0, "whole_tumor": [1, 2, 3], "tumor_core": [2, 3], "enhancing_tumor": 3 }, "regions_class_order": [1, 2, 3]regions_class_order告诉 nnU-Net 如何把区域表示转换回整数标签图:列表长度须等于区域数(不含背景),依次把对应标签放入对应区域的预测位置,后写入的条目会覆盖先前的。因此设置顺序时要遵循“先整体区域、后子结构”的原则(例如先 whole_tumor 再 tumor_core 再 enhancing_tumor),否则子结构会被整体区域覆盖丢失。由于这个转换对声明顺序极其敏感,自动生成 dataset.json 时必须保证字典键不被按字母序排序(即json.dump()时设置sort_keys=False)。nnU-Net 在 region-based 训练下会直接基于区域而非单个标签做评估和模型选择。
命令迁移:nnUNet_*→nnUNetv2_*
V2 的所有命令以nnUNetv2开头,用法与 V1 大部分一致但并非完全相同,遇到不确定时直接加-h查看帮助。命令的注册定义在 pyproject.toml 的[project.scripts]中,常见命令及对应源码入口如下:
| 命令 | 源码入口 |
|---|---|
nnUNetv2_plan_and_preprocess | plan_and_preprocess_entrypoints.py |
nnUNetv2_train | run_training.py |
nnUNetv2_predict | predict_from_raw_data.py |
nnUNetv2_find_best_configuration | find_best_configuration.py |
nnUNetv2_apply_postprocessing | remove_connected_components.py |
nnUNetv2_convert_old_nnUNet_dataset | convert_raw_dataset_from_old_nnunet_format.py |
nnUNetv2_convert_MSD_dataset | convert_MSD_dataset.py |
nnUNetv2_ensemble | ensemble.py |
nnUNetv2_determine_postprocessing | remove_connected_components.py |
nnUNetv2_evaluate_folder/nnUNetv2_evaluate_simple | evaluate_predictions.py |
nnUNetv2_export_model_to_zip/nnUNetv2_install_pretrained_model_from_zip | model_sharing/entry_points.py |
数据迁移:nnUNetv2_convert_old_nnUNet_dataset
V1 的原始数据集可以迁移,但V1 训练好的模型不能迁移——那些模型请继续用旧版 nnU-Net 做推理。迁移命令用法:
nnUNetv2_convert_old_nnUNet_dataset /media/isensee/raw_data/nnUNet_raw_data_base/nnUNet_raw_data/Task027_ACDC Dataset027_ACDC第一个参数是旧 Task 的完整路径(V2 不知道 V1 任务的位置,只传任务名会失败),第二个参数是新的数据集名称(必须符合DatasetXXX_NAME约定)。源码实现(convert_raw_dataset_from_old_nnunet_format.py)会执行以下操作:
- 检查目标
DatasetXXX_NAME目录是否已存在,存在则直接抛错中止(防止破坏已有数据); - 复制
imagesTr、labelsTr,若存在则一并复制imagesTs、labelsTs、imagesVal、labelsVal; - 复制旧
dataset.json后做字段迁移:删除 V1 的tensorImageSize、numTest、training、test字段,把modality重命名为channel_names(值深拷贝); - 把
labels从{int: name}反转成{name: int}({j: int(i) for i, j in ...items()}); - 写入
file_ending: ".nii.gz"(旧数据集默认 nifti)。
详细用法可运行nnUNetv2_convert_old_nnUNet_dataset -h查看。另外,MSD 官方数据集可用 convert_msd_dataset.md 中描述的nnUNetv2_convert_MSD_dataset转换。
更新已有数据集的最佳实践
当数据集需要更新时,最佳实践是:先删除nnUNet_preprocessed/DatasetXXX_NAME下的预处理数据以保证全新开始,然后替换nnUNet_raw中的数据并重新运行nnUNetv2_plan_and_preprocess,可选地再清理旧的训练结果目录。
迁移后的标准工作流:五个核心命令
TLDR 指南给出迁移后最常用的命令顺序,下面逐一展开(含命令行参数说明):
1.nnUNetv2_plan_and_preprocess:规划与预处理
nnUNetv2_plan_and_preprocess -d 2-d指定数据集 ID(或名称)。该命令会依次完成:提取数据集指纹(nnUNetv2_extract_fingerprint)、基于指纹自动规划实验方案(nnUNetv2_plan_experiment)、执行预处理(nnUNetv2_preprocess)。其分解子命令同样注册在 plan_and_preprocess_entrypoints.py。预处理结果写入nnUNet_preprocessed/DatasetXXX_NAME/,其中包含训练与交叉验证所需的全部数据以及生成的 plans 文件(默认nnUNetPlans.json)。
2.nnUNetv2_train:训练
nnUNetv2_train 2 3d_fullres 0三个位置参数依次是数据集 ID/名称、配置(configuration,如2d、3d_fullres、3d_lowres)、fold(0–4 的 5 折交叉验证,或all)。可选参数(来自 run_training.py 的 argparse 定义):
-tr:指定自定义 trainer 类名,默认nnUNetTrainer;-p:指定 plans 标识符,默认nnUNetPlans;-pretrained_weights:加载预训练权重(beta 功能,谨慎使用);-num_gpus:多 GPU 训练时指定 GPU 数;--npz:在最终验证时额外保存 softmax 概率为 npz(ensemble 寻找最佳组合时需要);--c:从最新 checkpoint 继续训练;--val:仅运行验证(要求训练已完成);--val_best:用checkpoint_best而非checkpoint_final做验证(与--disable_checkpointing不兼容);--disable_checkpointing:禁用 checkpoint 保存(适合测试);-device:cuda/cpu/mps,不要用它指定 GPU 编号,应使用CUDA_VISIBLE_DEVICES=X nnUNetv2_train [...]。
训练结束后,在nnUNet_results/DatasetXXX_NAME/下会得到各 fold 的模型权重与验证结果。从源码结构看,run_training.py统一了三种训练启动方式:外部启动器(torchrun 等)、-num_gpus X单机多卡、单进程训练,并自动处理 checkpoint 加载与验证流程(run_training→launch_training→execute_training→run_training/perform_actual_validation)。
3.nnUNetv2_find_best_configuration:寻找最优配置
nnUNetv2_find_best_configuration 2 -c 2d 3d_fullres-c后列出参与比较的配置。该命令会在nnUNet_preprocessed/DatasetXXX_NAME/目录下生成inference_instructions.txt文件,其中写明了该数据集最优配置(或最优集成方案)下做推理的精确命令,是推理阶段最可靠的参考。该命令的配套入口还有nnUNetv2_accumulate_crossval_results(汇总各折交叉验证结果)与nnUNetv2_determine_postprocessing(确定后处理方案),详见 find_best_configuration.py 与 accumulate_cv_results.py。
4.nnUNetv2_predict:推理
nnUNetv2_predict -i INPUT_FOLDER -o OUTPUT_FOLDER -c 3d_fullres -d 2关键参数(来自 predict_from_raw_data.py 的 argparse 定义):
-i:输入文件夹,文件通道编号需与训练一致(_0000等),文件扩展名也必须与训练数据集一致;-o:输出文件夹,不存在会自动创建;-d:数据集 ID 或名称;-c:推理所用配置(必须位于-p指定的 plans 中);-p:plans 标识符,默认nnUNetPlans;-tr:训练所用的 trainer 类名,默认nnUNetTrainer;-f:使用哪些 fold 的模型,默认(0, 1, 2, 3, 4)(全部五折集成);-step_size:滑窗步长,默认 0.5(越大越快但精度略降,不能大于 1,官方推荐默认值);--disable_tta:关闭测试时镜像增强(更快但不推荐);--save_probabilities:导出概率图(多配置 ensemble 必需);--continue_prediction:继续被中断的预测(不覆盖已有文件);-chk:使用的 checkpoint 文件名,默认checkpoint_final.pth;-npp/-nps:预处理/导出进程数,默认各 3(过多可能导致内存溢出);-num_parts/-part_id:将预测任务分片提交(多 GPU 并行推理时使用,需自行用CUDA_VISIBLE_DEVICES分配 GPU);-device:cuda/cpu/mps;--not_on_device:对大尺寸病例关闭“全流程在设备上执行”,节省显存。
若需要直接从模型文件夹推理而不依赖nnUNet_results环境变量,可使用nnUNetv2_predict_from_modelfolder(同样注册于 predict_from_raw_data.py)。
5.nnUNetv2_apply_postprocessing:应用后处理
nnUNetv2_apply_postprocessing该命令读取inference_instructions.txt中的指示,对预测结果应用已确定的后处理方案(通常是基于连通域的标签移除/保留,见 remove_connected_components.py)。后处理方案的确定由nnUNetv2_determine_postprocessing完成,配合 ensemble(nnUNetv2_ensemble)可构成完整的“多配置集成 + 后处理”推理链。
迁移核对清单
完成迁移后,可按以下清单自查:
- 三个环境变量(
nnUNet_raw/nnUNet_preprocessed/nnUNet_results)已正确设置且可用echo验证; - 旧 Task 已通过
nnUNetv2_convert_old_nnUNet_dataset转换为DatasetXXX_NAME,且dataset.json中labels已变为name: value方向、modality已改名为channel_names、新增了file_ending; - 无需转换的旧 V1 模型仍用旧版 nnU-Net 推理,未混入 V2 流程;
- 按“plan_and_preprocess → train → find_best_configuration → predict → apply_postprocessing”顺序执行,并以
inference_instructions.txt作为推理命令的最终依据; - 所有命令均以
nnUNetv2开头,不确定参数时使用-h查看帮助。
结语
从 V1 到 V2 的迁移并不复杂:命名上Task→Dataset、命令前缀nnUNet_→nnUNetv2_,结构上数据集目录骨架保持不变但文件格式支持大幅扩展、dataset.json被精简且labels键值反转以支持 region-based 训练,环境上新增了三个独立环境变量,迁移工具仅支持原始数据而不支持已训练模型。掌握这些差异,配合-h帮助与inference_instructions.txt,即可顺利在 V2 上重建你的分割实验流程。
- 人工智能
- 深度学习
- 计算机视觉
- 医疗健康
【免费下载链接】nnUNet
相关推荐
Gatsby v0 到 v1 迁移指南:从 config.toml 到 gatsby-config.js、从 wrapper 到模板组件的完整升级路径
Gatsby v0 到 v1 迁移指南:从 config.toml 到 gatsby config.js、从 wrapper 到模板组件的完整升级路径 本篇指南
前端静态站点Web框架mimalloc版本迁移指南:从v1到v2再到v3的升级路径
mimalloc版本迁移指南:从v1到v2再到v3的升级路径 概述:为什么需要版本迁移? mimalloc作为Microsoft开发的高性能内存分配器,在v1、
内存管理系统编程node-fetch API版本迁移终极指南:从v1到v3的完整升级路径
node fetch API版本迁移终极指南:从v1到v3的完整升级路径 node fetch作为将浏览器Fetch API引入Node.js的轻量级模块,在v
后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考