nnUNet使用指南<1>:使用自己的数据集做分割训练

首先,看了看github上的readme,确实挺长。目前数据都有,就按照步骤一步一步来吧

设置路径

nnUNet需要设置三个路径:

  • nnUNet_raw_data_base: 用于存放原始数据和crop后的数据。该目录至少包含一个nnUNet_raw_data子文件夹
  • nnUNet_preprocessed:用于存放预处理数据,该数据将来会用于训练,建议放在SSD下
  • RESULTS_FOLDER:用于存放训练模型

使用文本编辑器打开.bashrc文件,将以上路径加入环境变量

sudo vim ~/.bashrc
export nnUNet_raw_data_base="/home/data/nnunet/nnUNet_raw_data_base"
export nnUNet_preprocessed="/home/data/nnunet/nnUNet_preprocessed"
export RESULTS_FOLDER="/home/data/nnunet/nnUNet_trained_models"
source ~/.bashrc # 使修改生效

数据格式转换

数据格式采用的使3D nifti files(.nii.gz),包括image和label文件,主要是排列顺序和存储的逻辑关系需要修改
每个分割任务以Task+三位数字组成,后面接任务名,存储逻辑关系如下:
nnUNet_raw_data_base/nnUNet_raw_data/
  ├── Task001_BrainTumour
  ├── Task002_Heart
  ├── Task003_Liver
  ├── Task004_Hippocampus
  ├── Task005_Prostate
  ├── …
在每个子任务下,存储逻辑关系如下:
Task001_BrainTumour/
  ├── dataset.json
  ├── imagesTr
  ├── (imagesTs)
  └── labelsTr
对于自己新建的任务,其任务ID应以100开始,以确保不会和作者提供的预训练模型冲突
对于每一个dataset,还需要有一个dataset.json来对数据集进行简单描述,包括数据的modality,例如CT为0,仅有一个模态,而MR数据则可以对应0,1,2,分别对应T1,T2,T1C等序列,label中同样有0对应背景,1对应分割区域,2,3等可对应多类别分割问题。Tr代表训练数据,Ts代表测试数据。在nnUNet/dataset_conversion下有针对不同分割比赛的数据集预处理方式,可以参考其做法完成自己的数据集预处理

自己的分割任务

我按照Task055_SegTHOR.py来生成我自己的数据集,然后开始数据预处理。第一步就是提取dataset的信息,包括image sizes, voxel spacings, intensity information等,运行以下代码:

nnUNet_plan_and_preprocess -t 111 --verify_dataset_integrity
$ 111是你自己的taskID

数据预处理完以后,就可以进行训练了

nnUNet_train CONFIGURATION TRAINER_CLASS_NAME TASK_NAME_OR_ID FOLD (additional options)

CONFIGURATION:UNet的配置信息(2d,3d_fullres,3d_lowres,3d_cascade_fullres,3d_cascade_lowres)
TRAINER_CLASS_NAME: 网络结构名称
TASK_NAME_OR_ID: 在哪个数据集上训练
FOLD:在哪个fold上训练
然后,就开始训练了

nnUNet_train 3d_fullres nnUNetTrainerV2 Task111_SegRec 0

先尝试3d-full-resolution
训练后的模型会保存在RESULTS_FOLDER下,具有类似的结构,以task002—heart为例:

For Task002_Heart (from the MSD), for example, this looks like this:

RESULTS_FOLDER/nnUNet/
├── 2d
│   └── Task02_Heart
│       └── nnUNetTrainerV2__nnUNetPlansv2.1
│           ├── fold_0
│           ├── fold_1
│           ├── fold_2
│           ├── fold_3
│           └── fold_4
├── 3d_cascade_fullres
├── 3d_fullres
│   └── Task02_Heart
│       └── nnUNetTrainerV2__nnUNetPlansv2.1
│           ├── fold_0
│           │   ├── debug.json
│           │   ├── model_best.model
│           │   ├── model_best.model.pkl
│           │   ├── model_final_checkpoint.model
│           │   ├── model_final_checkpoint.model.pkl
│           │   ├── network_architecture.pdf
│           │   ├── progress.png
│           │   └── validation_raw
│           │       ├── la_007.nii.gz
│           │       ├── la_007.pkl
│           │       ├── la_016.nii.gz
│           │       ├── la_016.pkl
│           │       ├── la_021.nii.gz
│           │       ├── la_021.pkl
│           │       ├── la_024.nii.gz
│           │       ├── la_024.pkl
│           │       ├── summary.json
│           │       └── validation_args.json
│           ├── fold_1
│           ├── fold_2
│           ├── fold_3
│           └── fold_4
└── 3d_lowres

目前还在继续训练中,如果说按照默认的50个epoch的情况,应该很快就可以训练完毕,考虑写一个shell脚本进行训练,后面会继续跟进,分析训练过程中的log以及nnUNet的源码

你可能感兴趣的:(nnUNet使用指南<1>:使用自己的数据集做分割训练)