保姆級教程:nnUnet在2維影像的訓練和測試

Minerva_發表於2021-01-01

保姆級教程:nnUnet在2維影像的訓練和測試

一、 nnUnet介紹

nnUnet方法源自論文

《Automated Design of Deep Learning Methods for Biomedical Image Segmentation》,來自德國癌症研究中心。

原始碼地址:https://github.com/MIC-DKFZ/nnUNet。
nnUNet濃縮了醫學影像的語義分割領域的大部分知識,並且具備自動為不同任務設計不同訓練方案的框架,不需要人工進行調參。

流程如下

  1. 自動對不同的資料屬性(圖片質量、圖片模態、圖片大小、體素大小、類別比率等)進行分析,生成獨一無二的資料指紋(data fingerprint),表示資料集的關鍵屬性;
  2. 制定獨一無二的訓練方案管道指紋(pipeline fingerprint),表示‘管道’關鍵的優化設計;
  3. 資料預處理和資料增強;
  4. 採用2D、3D和3D_Cascaded三個網路分別訓練,得出各自的模型(三個網路結構共享一個“管道指紋”,五折交叉驗證);
  5. 選擇出最優的模型進行推理。

nnUNet在19個國際競賽中取得最優結果,而且在49個任務的大多數中,都達到了SOTA級別。這些任務包括器官的分割、器官的子結構分割、腫瘤分割、病灶分割等,而且是在多個模態下,例如MRI、CT、EM等。

基本結構就是Unet
在這裡插入圖片描述

下圖左邊是原資料的標籤,右邊是nnUNet模型的推理結果。
在這裡插入圖片描述

二、環境配置

首先建立nnUnet2環境並啟用,之後安裝必要的包

source activate nnUnet2

在終端中執行匯出命令,設定環境變數

export nnUNet_raw_data_base="/data/Project/nnUnet/Data/nnUNet_raw"
export nnUNet_preprocessed="/data/Project/nnUnet/Data/nnUNet_preprocessed"
export RESULTS_FOLDER="/data/Project/nnUnet/Data/nnUNet_trained_models"

三、資料配置

我們的2維原始資料長這樣~
在這裡插入圖片描述

將2維資料轉換為3維資料,其實就是z軸為1的3維資料,具體程式碼在關注公眾號後回覆:2DDataProcessTo3D.py即可下載
幾個注意的點:
nnUnet的資料格式是固定的,Task002_Heart由Task+ID+資料名組成,imagesTr是訓練資料,imagesTs是測試資料,labelsTr是訓練資料的標籤,資料樣本la_003_0000.nii.gz由case樣本名字+模態標誌+.nii.gz組成,不同的模態用0000/0001/0002/0003區分,我把新的任務ID設定為100。
示例樹結構:

nnUNet_raw_data_base/nnUNet_raw_data/Task002_Heart
├── dataset.json
├── imagesTr
│   ├── la_003_0000.nii.gz
│   ├── la_004_0000.nii.gz
│   ├── ...
├── imagesTs
│   ├── la_001_0000.nii.gz
│   ├── la_002_0000.nii.gz
│   ├── ...
└── labelsTr
    ├── la_003.nii.gz
    ├── la_004.nii.gz
    ├── ...

我們的原始2維資料是RGB三通道的,我們可以把RGB三通道的資料看成3個模態,分別提取不同通道的資料,形狀轉換成(1,width, height),採用SimpleITK儲存為3維資料。
imagesTr:
在這裡插入圖片描述

labelsTr:
在這裡插入圖片描述

製作dataset.json,前面的內容模仿給定的格式,按照自己的資料修改一下內容,
在這裡插入圖片描述

dataset.json裡的資料名去掉了模態標誌,所以每個資料看起來有三個重複名字,在後面讀圖的時候會自動新增模態標誌。

四、預處理

nnUNet_plan_and_preprocess -t 100 -data23d 2 --verify_dataset_integrity

這裡我增加了一個設定引數data23d用來指定要處理的是2維資料還是3維資料,在sanity_checks.py中做如下設定,

if data23d == '2':
        expected_train_identifiers = np.unique(expected_train_identifiers)
        expected_test_identifiers = np.unique(expected_test_identifiers)
        print('train num', len(expected_train_identifiers))
        print('test num:', len(expected_test_identifiers))

nnU-Net提取資料集指紋(一組特定於資料集的屬性,例如影像大小,體素間距,強度資訊等)。nnUNet_plan_and_preprocess使用2D U-Net以及所有適用的3D U-Net的預處理資料建立子資料夾。它還將為2D和3D配置建立“計劃”檔案(帶有ending.pkl)。這些檔案包含生成的分割管道配置,並且將被nnUNetTrainer讀取。
此資訊用於建立三個U-Net配置:
一個2D U-Net
一個以全解析度影像執行的3D U-Net
一個3D U-Net級聯
在這裡插入圖片描述

針對我們的2維資料只建立2D U-Net的計劃。

五、訓練過程

我是在11G的2080ti GPU卡進行訓練,分別做5折交叉驗證,如:

CUDA_VISIBLE_DEVICES=1 nnUNet_train 2d nnUNetTrainerV2 Task100_PapSmear 0  --npz
CUDA_VISIBLE_DEVICES=1 nnUNet_train 2d nnUNetTrainerV2 Task100_PapSmear 1  --npz
CUDA_VISIBLE_DEVICES=1 nnUNet_train 2d nnUNetTrainerV2 Task100_PapSmear 2  --npz
CUDA_VISIBLE_DEVICES=1 nnUNet_train 2d nnUNetTrainerV2 Task100_PapSmear 3  --npz
CUDA_VISIBLE_DEVICES=1 nnUNet_train 2d nnUNetTrainerV2 Task100_PapSmear 4  --npz

執行過程如下:
在這裡插入圖片描述
中間的網路結構忽略。。。
在這裡插入圖片描述

這樣我們的訓練就開始了,每個epoch會列印訓練損失、驗證損失、幾個類的平均dice、當前學習率、執行時間,並儲存模型,這裡的Dice_nulcear Just For papsmear是我自己單獨加的一個dice,大家可以忽略也可以自己插入想監測的引數。
預設訓練1000個epoch,之後會生成對應fold的檔案:
在這裡插入圖片描述

六、確定最佳的U-Net配置

執行完5折交叉驗證後,可以確定最佳的配置,下面的100是Task的ID,我們這個任務是100,

nnUNet_find_best_configuration -m 2d -t 100 –strict

執行後會在路徑nnUNet_trained_models/nnUNet/ensembles/Task100_PapSmear下生成
在這裡插入圖片描述

也會生成執行推斷的方法

nnUNet_predict -i FOLDER_WITH_TEST_CASES -o OUTPUT_FOLDER_MODEL1 -tr nnUNetTrainerV2 -ctr nnUNetTrainerV2CascadeFullRes -m 2d -p nnUNetPlansv2.1 -t Task100_PapSmear

在這裡插入圖片描述

七、執行推斷

根據前面生成的推斷方法,修改對應輸入-i和輸出-o資料夾,

nnUNet_predict -i /data/Project/nnUnet/Data/nnUNet_raw/nnUNet_raw_data/Task100_PapSmear/imagesTs/ -o /data/Project/nnUnet/Data/nnUNet_raw/nnUNet_raw_data/Task100_PapSmear/imagesTsPred/ -tr nnUNetTrainerV2 -ctr nnUNetTrainerV2CascadeFullRes -m 2d -p nnUNetPlansv2.1 -t Task100_PapSmear

執行過程如下:
在這裡插入圖片描述
在前面給定的輸出資料夾生成五折交叉驗證的整合結果
在這裡插入圖片描述

之後重新讀取輸出結果後,儲存為2維影像,即為分割結果
在這裡插入圖片描述

其中一張影像的分割結果如下:
在這裡插入圖片描述
總體而言,nnUnet的效能還是很強勁的,在之前的研究中,我們分別採用過三種方法對該資料集進行分割:

1:Automated Segmentation of Cervical Nuclei in Pap Smear Images using Deformable Multi-path Ensemble Model,連結https://arxiv.org/abs/1812.00527
2:PGU-net+: Progressive Growing of U-net+ for Automated Cervical Nuclei Segmentation,連結https://arxiv.org/abs/1911.01062
3:ASCNet: Adaptive-Scale Convolutional Neural Networks for Multi-Scale Feature Learning,連結https://arxiv.org/abs/1907.03241
分別獲得的分割Dice為:0.933、0.926、0.915,nnUnet的分割Dice為0.9624040666779203!!!
最後祝大家新年快樂,2021年衝鴨!!!

在這裡插入圖片描述
掃它!掃它!掃它!
原文連結:https://mp.weixin.qq.com/s?__biz=MzUxNTY1MjMxNQ==&mid=2247485749&idx=1&sn=fe177c36279be704aede749e522b691d&chksm=f9b22681cec5af976da604bb403bb6dde52c5742ecddd34e1862fb6957e2086752a14f233961&token=335739667&lang=zh_CN#rd

致謝:文章在nnUnet介紹部分主要參考CSDN博主:花捲湯圓的文章:
(四:2020.07.28)nnUNet最舒服的訓練教程(讓我的奶奶也會用nnUNet(上))(11.05更新)
https://blog.csdn.net/weixin_42061636/article/details/107623757

相關文章