nnunet(四) extending nnunet

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

Extending/Changing nnU-Net

把代码先下下来,然后参照着修改。

Changes to blueprint parameters

本节提供有关如何实现损失函数loss function,训练计划training schedule,学习率learning rates,优化器optimizer,一些架构参数architecture parameters,数据扩充data augmentation等方面的指导。所有这些参数都是nnU-Net trainer class的一部分,我们已经在上面几节中看到了。2D, 3D low resolution 和 3D full resolution U-Net默认都使用nnUNetTrainerV2。cascade中的3D full resolution U-Net默认使用nnUNetTrainerV2CascadeFullRes。nnU-Net中的Trainer classes彼此继承,例如nnUNetTrainerV2CascadeFullRes将nnUNetTrainerV2作为父类,并且只覆盖特定的级联代码。

由于使用trainer class的继承,更改可以很容易地集成到nnU-Net中,而且只需很少的工作量。只需创建一个新的trainer class(带有一些自定义名称),更改需要更改的函数,然后在训练期间通过它的名称指定这个类,就可以了。

这个过程需要新类放在nnunet.training.network_training中!不要将它保存在其他地方,否则nnU-Net将无法找到它!同样的名字也不要用两次!nnU-Net总是选择与请求名称匹配的第一个trainer。

不要担心overwriting另一个trainer class的结果。nnU-Net会使用trainer class名来创建保存输出结果的文件夹。由于nnU-Net的blueprint参数可能发生的各种变化,作者在这里仅给出一个在哪里查找哪种修改的摘要。在方法开发过程中,作者已经创建了大量的nnU-Net blueprint变体,它们应该能很好地指示从哪里开始:

Type of modificationExamples
loss functionnnunet.training.network_training.loss_function.*
data augmentationnnunet.training.network_training.data_augmentation.*
Optimizer, lr, momentumnnunet.training.network_training.optimizer_and_lr.*
(Batch)Normalizationnnunet.training.network_training.architectural_variants.nnUNetTrainerV2_BN.py
nnunet.training.network_training.architectural_variants.nnUNetTrainerV2_FRN.py
nnunet.training.network_training.architectural_variants.nnUNetTrainerV2_GN.py
nnunet.training.network_training.architectural_variants.nnUNetTrainerV2_NoNormalization_lr1en3.py
Nonlinearitynnunet.training.network_training.architectural_variants.nnUNetTrainerV2_ReLU.py
nnunet.training.network_training.architectural_variants.nnUNetTrainerV2_Mish.py
Architecturennunet.training.network_training.architectural_variants.nnUNetTrainerV2_3ConvPerStage.py
nnunet.training.network_training.architectural_variants.nnUNetTrainerV2_ResencUNet
...(see nnunet.training.network_training and subfolders)

 Nonlinearity是指激活函数了,Architecture值得是unet组合结构。

Changes to Inferred Parameters

inferred parameters是根据dataset fingerprint来确定的,dataset fingerprint是一种对训练数据属性的低维表示。例如,它从训练数据中捕捉图像形状image shapes、体素间距voxel spacings和强度信息intensity information。数据集指纹是由DatasetAnalyzer(位于nnunet.preprocessing中)在运行nnUNet_plan_and_preprocess时创建的。

nnUNet_plan_and_preprocess使用所谓的ExperimentPlanners来运行适当过程。2D U-Net默认的ExperimentPlanner class为ExperimentPlanner2D_v21,3D full resolution U-Net 和U-Net cascade默认的ExperimentPlanner class为ExperimentPlanner3d_v21。就像nnUNetTrainers一样,ExperimentPlanners也是彼此继承,只需很少的编程工作即可合并更改。就像trainers一样,只需给你的自定义ExperimentPlanners一个唯一的名字,并将它们保存在nnunet.experiment_planning的子文件夹中。然后运行nnUNet_plan_and_preprocess时指定class name,nnUNet_plan_and_preprocess将自动找到它们。当继承ExperimentPlanners时,您必须覆盖类变量self.data_identifier和self.plans_fname(https://github.com/MIC-DKFZ/nnUNet/blob/master/nnunet/experiment_planning/alternative_experiment_planning/normalization/experiment_planner_3DUNet_CT2.py)。如果您省略了这一步,planner将覆盖plans file及其继承的planner的preprocessed data 。

要使用自定义配置进行训练,只需在调用nnUNet_train命令时用-p指定正确的plans标识符。plans文件还包含在ExperimentPlanner中指定的data_identifier,因此trainer class将自动知道应该使用哪些数据。

针对inferred parameters可能的调整包括:一个不同的方式来优先处理batch size和patch size(目前,nnU-Net优先处理patch size),对架构模板实例architecture template instantiation的spacing信息的不同处理,改变target spacing的定义,或者使用不同的策略寻找3d low resolution U-Net 配置。

nnunet.experiment_planning文件夹包含几个ExperimentPlanner示例,这些ExperimentPlanner示例修改inferred parameters的各个方面。可以参考这些示例。

如果希望运行不同的preprocessing,很可能必须实现自己的Preprocessor class。ExperimentPlanner使用的preprocessor class是在其preprocessor_name类变量中指定的。3D中默认为self.preprocessor_name = "GenericPreprocessor",2D中默认为PreprocessorFor2D (2D preprocessor忽略第一个轴的target spacing,以确保图像只在指定的轴上进行重新采样)。GenericPreprocessor(以及您实现的所有自定义预处理器Preprocessors)必须位于nnunet.preprocessing中。preprocessor_name(通过ExperimentPlanner)保存在计划文件 plans file中,这样nnUNetTrainer就知道在推理过程中必须使用哪个预处理程序来匹配训练数据的预处理。

对preprocessing pipeline的修改可以是对MRI图像添加偏置场校正bias field correction、不同的CT预处理方案或对各向异性数据和分割的不同的重采样策略。https://github.com/MIC-DKFZ/nnUNet/blob/master/nnunet/preprocessing/preprocessing.py

当实现一个自定义预处理器preprocessor时,你也应该创建一个自定义的ExperimentPlanner来使用它(通过self.preprocessor_name)。这个 experiment planner 还必须使用匹配的data_identifier和plans_fname,以确保没有其他数据被覆盖。

Use a different network architecture

改变nnU-Net中的网络架构很容易,但不容易解释。你实现的任何新的分割网络都需要了解来自它的nnU-Net请求(做了多少下采样操作,是否使用深度监督,卷积核大小应该是多少)。它需要能够动态地改变其拓扑结构,就像我们的Generic_UNet实现一样。https://github.com/MIC-DKFZ/nnUNet/blob/master/nnunet/network_architecture/generic_UNet.py。此外,它必须能够生成一个用于估计显存消耗的值。作者为Generic_UNet实现的是有效地计算给定配置中所有特征图中的体素数。尽管这个估计忽略了参数的个数,但作者发现它很有效。除非您实现了一个参数数量不合理的网络结构,否则在训练期间使用的大部分VRAM将被特征图所占用,所以可以忽略(大部分)参数。要实现自己的网络,关键是要理解我们在这里计算的数字不能直接解释为显存消耗(除了卷积convolutions的特征映射之外,其他因素也发挥了作用,比如实例规范化instance normalization。这是非常难以预测的,因为有几种不同的算法用于执行卷积,每种算法都有自己的显存需求。我们用cudnn.benchmark=True训练模型,因此无法预测使用哪种算法)。所以,要解决这个问题最直接的方法,我们手动指定适合GPU的最大配置(手动定义dowmsampling,补丁patch size等)并使用这个值(-10%左右被保存)作为使用这个架构的ExperimentPlanner参考。

为了说明这个过程,我们实现了一个U-Net with a residual encoder(参见generic_modular_residual_UNet.py中的FabiansUNet)。这个UNet有一个名为use_this_for_3D_configuration的类变量。这个值在(同一个python文件)find_3d_configuration中的代码中可以找到。相应的ExperimentPlanner ExperimentPlanner3DFabiansResUNet_v21将此值与当前配置的网络拓扑生成的值(也由FabiansUNet.compute_approx_vram_consumption计算)进行比较,以确保GPU显存目标得到满足。

Tutorials

作者已经创建了关于如何手动编辑计划文件plans files、更改目标间距target spacing和更改预处理的归一化方案normalization的教程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值