nnunet(三) common questions

https://github.com/MIC-DKFZ/nnUNet/blob/master/documentation/common_questions.md

Where can I find the segmentation metrics of my experiments?

训练完成后,每个fold的验证集结果存储在各自的输出文件夹中。如:${RESULTS_FOLDER}/nnUNet/3d_fullres/Task003_Liver/nnUNetTrainerV2__nnUNetPlansv2.1/fold_0。训练结束后会有validation_raw和validation_raw_postprocessed的子文件夹,每个文件夹中都有一个summary.json文件,包含segmentation metrics。里面有每个验证case的单独metrics,在底部还有所有cases的平均值。

Cross-validation metrics只有在five folds都跑完的时候才能用,需要先运行nnUNet_determine_postprocessing,可以通过nnUNet_determine_postprocessing -h查看。一般会先收集验证集的five folds的预测结果,然后在计算metrics,然后在决定使用什么样的后处理。所有的命令都执行完了之后,会在输出目录中创建新的文件夹,${RESULTS_FOLDER}/nnUNet/3d_fullres/Task003_Liver/nnUNetTrainerV2__nnUNetPlansv2.1/:cv_niftis_raw 交叉验证的原始预测结果;cv_niftis_postprocessed加入后处理后的预测结果。 两个文件夹中都有包含metrics的summary.json文件。

nnU-Net会忽略每个单独折叠上的后处理,因为它需要为整个交叉验证找到一个最优的后处理配置,单独的折叠后处理结果只是为了开发!

Test set results 在后面会单独讲到。

Ensemble performance运行完nnUNet_find_best_configuration之后可以在${RESULTS_FOLDER}/nnUNet/ensembles/TASKNAME中找到整体性能,summary.csv用于快速预览,在相应的子文件夹中d的summary.json有详细结果。

What postprocessing is selected?

执行完nnUNet_determine_postprocessing 后(nnUNet_determine_postprocessing -h可以查到对应的帮助文件),会在训练的输出文件夹${RESULTS_FOLDER}/nnUNet/3d_fullres/Task003_Liver/nnUNetTrainerV2__nnUNetPlansv2.1/中生成postprocessing.json文件,如果打开这个json文件,里面for_which_classes字段中有一些字段,如 LiTS中 (classes 0: bg, 1: liver, 2: tumor) 

"for_which_classes": [
        [
            1,
            2
        ],
        1

这意味着nnU-Net将首先合并对象(包括第1类和第2类),然后删除除最大组件外的所有组件(本质上是包括2:tumor在内的1:liver),然后在第二步中也移除1:liver类中除最大连接组件外的所有组件。

如果你运行了nnUNet_find_best_configuration,就不需要在单独运行nnUNet_determine_postprocessing 了,因为nnUNet_find_best_configuration会自动执行nnUNet_determine_postprocessing 。

整体结果和后处理将存储在${RESULTS_FOLDER}/nnUNet/ensembles中(这些都将由nnUNet_find_best_configuration生成)。

Evaluating test set results

使用nnUNet_evaluate_folder来计算测试集度量。

nnUNet_evaluate_folder -ref FOLDER_WITH_GT -pred FOLDER_WITH_PREDICTIONS -l 1 2 3 4

 这个例子是一个有4个前景类(标签1、2、3、4)的数据集。FOLDER_WITH_GT和FOLDER_WITH_PREDICTIONS预测的类别必须相同,分别包含每种情况的真实标记和预测标记。文件必须是nifti(以.nii.gz结尾)。

Creating and managing data splits

在每次训练开始时,nnU-Net将在预处理好的训练集中检查splits_final.pkl文件是否存在,如果文件不存在,nnU-Net将创建自己的数据划分:使用所有可用的训练数据,进行five-fold cross-validation。nnU-Net需要这种five-fold cross-validation才能确定后处理、运行model/ensemble部分。

然而,在某些情况下,您可能想创建自己的数据划分,例如

  1. 在像ACDC这样的数据集中,几个训练案例是连接的(每个患者有两个时间步骤),您可能需要手动创建数据划分,以确保适当的数据集分类。
  2. cases由多个标注器标注,您可以使用这些标注作为单独的训练示例。
  3. 如果您正在使用domain transfer进行实验,您可能希望只对来自domain A的训练,并在domain B上验证。

创建自己的数据划分很简单:splits_final.pkl文件包含以下数据结构(假设有五个训练数据A、B、C、D、E):

splits = [
    {'train': ['A', 'B', 'C', 'D'], 'val': ['E']},
    {'train': ['A', 'B', 'C', 'E'], 'val': ['D']},
    {'train': ['A', 'B', 'D', 'E'], 'val': ['C']},
    {'train': ['A', 'C', 'D', 'E'], 'val': ['B']},
    {'train': ['B', 'C', 'D', 'E'], 'val': ['A']}
]

使用batchgenerators.utilities.file_and_folder_operations中的load_pickle和save_pickle来loading/storing划分splits。

splits是一个长度为NUMBER_OF_FOLDS的list列表,列表中的每个条目都是一个字典,以'train'和'val'作为keys,并将相应的数据名称(名称中不含有_0000等!)作为值。

nnU-Net的five-fold cross validation将始终创建len(splits)=5的列表。但可以随意修改。值得注意的是,如果您只定义了4 splits(fold 0-3),然后在训练时设置fold=4(这将是第5次拆分split),nnU-Net将输出一条警告并继续使用随机的80:20数据拆分。

How can I swap component XXX (for example the loss) of nnU-Net?

nnU-Net中的所有变化都以相同的方式处理:

  1. 创建一个新的nnU-Net trainer类。将文件放在nnunet.training.network_training文件夹中(任何子文件夹都可以。如果你创建了一个新的子文件夹,请确保包含一个空的__init__.py文件!)
  2. 确保创建的trainer类从想要更改的trainer派生(最有可能是nnUNetTrainerV2)
  3. 确定需要overwriter的函数。您可能必须向上查找继承层次结构才能找到它!
  4. 在自定义trainer中overwriter该函数,确保函数中的更改与nnU-Net的其余部分是兼容的。

如果不知道到底怎么改,这些修改具体应该是什么样子是很难说的。在GitHub上打开新问题之前,请先查看nnunet.training.network_training文件夹!有很多修改pipeline各个部分的例子。

参考https://github.com/MIC-DKFZ/nnUNet/blob/master/documentation/extending_nnunet.md

How does nnU-Net handle multi-modal images?

多模态图像被视为彩色通道。BraTS为每个训练案例提供T1、T1c、T2和Flair图像,因此有4个输入通道。

Why does nnU-Net not use all my GPU memory?

nnU-net及其所有参数都针对使用约8GB VRAM进行网络训练的训练设置,直接使用默认设置也用不起来多余的显存。除非你可以做以下调整:

  1. 手动编辑plans files以增加batch size。batch size梯度越好(噪声越少),如果数据集较大,可能会提高模型性能。注意nnU-Net总是运行1000个epochs,每个epochs有250次迭代(250000次迭代)。因此,训练时间与batch size近似呈线性增长(batch size为4需要的训练时间是batch size为2的两倍!)
  2. 手动编辑plans files以增加patch size。一般不要轻易修改!如果修改了patch size,训练时间也会增加! 后面的第3步是增加patch size的较好方法。
  3. 使用较大的GPU显存预算可以运行nnUNet_plan_and_preprocess。这将使nnU-Net plan在experiment planning间获得更大的patch size。这可能会改变patch size、network topology、batch size如果有nnU-Net cascade的话也会受到影响。要使用不同的内存预算,需要指定不同的experiment planner,例如nnUNet_plan_and_preprocess -t TASK_ID -pl2d None -pl3d ExperimentPlanner3D_v21_32GB(注意-pl2d None将禁用2D U-Net配置。目前没有larger 2D U-Nets的planner)。作者有8GB(默认),11GB和32GB的planners可用。如果你需要一个不同GPU大小的planner,你应该能够用11GB或32GB的planner代码,快速地拼凑出你自己的planner(2D planner也是如此)。请注意,作者已经对这些planner进行了测试,并没有发现使用它们会提高分割性能。训练时间也比默认时间长。

Do I need to always run all U-Net configurations?

上面的model training pipeline是为挑战赛设置的。根据您的任务,您可能不想训练所有的U-Net模型,也可能不想一直运行交叉验证。以下是一些关于U-Net模型训练的建议:

  1. 可以肯定地说,平均而言,3D U-Net模型(3d_fullres)是最robust的。如果你只是想使用nnU-Net进行分割,作者建议你从这个开始。
  2. 如果你对3D U-Net的结果不满意,你可以尝试以下方法:
    1. 如果你的数据非常大,以至于3d U-Net的patch size只覆盖了图像的很小一部分,也就是标记不能有效的包含在patch size中,那么3d U-Net可能无法捕获足够的上下文信息以使其有效。如果是这种情况,您应该考虑运行3d U-Net级联(3d_lowres和3d_cascade_fullres)
    2. 如果数据是各向异性的,也就是spacing差异很大,那么2D U-Net可能是更好的选择(decathlon的Promise12, ACDC, task05_Prostate就是各向异性数据的例子)

您不必一直运行 five-fold cross-validation 。如果想测试single mode的性能,请使用all代替FOLD对应的number。要注意的数这里不会给出对训练集性能的评估。你也不能自动识别应该使用哪个ensembling,nnU-Net也不能配置postprocessing。

注意:当你打算运行cascade时,不要使用fold=all !你必须在3d_lowres中运行cross-validation,这样你才能得到正确的(=不过拟合)low resolution predictions。

Sharing Models

可以将RESULTS_FOLDER/nnUNet中相应的输出文件夹发送给想要共享的人,来共享训练过的模型。然后,对方可以使用nnU-Net对该模型进行inference。

现在还可以使用nnUNet_export_model_to_zip将训练过的模型(或多个模型)导出到zip文件。然后,接收方可以使用nnUNet_install_pretrained_model_from_zip从这个zip文件中安装模型。

Can I run nnU-Net on smaller GPUs?

nnU-Net保证在11GB显存的gpu上运行。许多配置也可以在8GB显存上运行。如果你有11GB的显存,仍然有out of memory的错误,请阅读“nnU-Net training: RuntimeError: CUDA out of memory”。https://github.com/MIC-DKFZ/nnUNet/blob/master/nnunet/preprocessing/preprocessing.py

如果你想配置nnU-Net来使用不同大小的GPU显存,只需调整相应的GPU显存估算的参考值(有一些松弛,因为整个事情不是一门精确的科学!)例如在experiment_planner_baseline_3DUNet_v21_11GB.py 中作者提供了一个例子,试图最大化GPU显存,使用11GB,而不是默认的留下更多的headroom的8GB)。这里可以通过下面这一行实现:

ref = Generic_UNet.use_this_for_batch_size_computation_3D * 11 / 8

8是当前使用的(大概),11是目标。如果CUDA不存在out of memory问题,只需减少reference值即可。您应该将此调整作为单独的ExperimentPlanner类的一部分进行。请在这里阅读使用说明。https://github.com/MIC-DKFZ/nnUNet/blob/master/documentation/extending_nnunet.md

Why is no 3d_lowres model created?

只有当3d_fullres中的patch size小于3d_fullres数据voxels of the median shape的1/8时,才创建3d_lowres(例如,肝脏约为512x512x512,而patch size为128x128x128,也就是是1/64,因此创建3d_lowres)。通过更改experiment_planned.configuration中的HOW_MUCH_OF_A_PATIENT_MUST_THE_NETWORK_SEE_AT_STAGE0的值,以强制为较小的数据集创建3d_lowres模型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值