ivadomed / model-spinal-rootlets

Deep-learning based segmentation of the spinal nerve rootlets
5 stars 2 forks source link

Lumbar rootlets - first model training #48

Open valosekj opened 4 months ago

valosekj commented 4 months ago

Dataset201_LumbarRootlets and Dataset202_LumbarRootlets

This issue summarizes the training of the first models (Dataset201_LumbarRootlets - semantic, Dataset202_LumbarRootlets - binary) for lumbar dorsal rootlets.

Steps

  1. Fixing different resolution and dimensions of images and labels (#46)
# "SPpre"
for sub in 04 05 14 15 20;do flirt -in sub-CTS${sub}_ses-SPpre_T2w_rootlets_resampled.nii.gz -ref sub-CTS${sub}_ses-SPpre_acq-zoomit_T2w.nii.gz -applyxfm -usesqform -out sub-CTS${sub}_ses-SPpre_T2w_rootlets_resampled_inzoomit.nii.gz -interp nearestneighbour;done

# image 10 has different fname: "SPanat"
flirt -in sub-CTS10_ses-SPanat_T2w_rootlets_resampled.nii.gz  -ref sub-CTS10_ses-SPanat_acq-zoomit_T2w.nii.gz  -applyxfm -usesqform -out sub-CTS10_ses-SPanat_T2w_rootlets_resampled_inzoomit.nii.gz -interp nearestneighbour
  1. Preparing nnUNet folders
mkdir imagesTr
cp sub-CTS04_ses-SPpre_acq-zoomit_T2w.nii.gz imagesTr/sub-CTS04_ses-SPpre_T2w_001_0000.nii.gz
cp sub-CTS05_ses-SPpre_acq-zoomit_T2w.nii.gz imagesTr/sub-CTS05_ses-SPpre_T2w_002_0000.nii.gz
cp sub-CTS10_ses-SPanat_acq-zoomit_T2w.nii.gz imagesTr/sub-CTS10_ses-SPanat_T2w_003_0000.nii.gz
cp sub-CTS14_ses-SPpre_acq-zoomit_T2w.nii.gz imagesTr/sub-CTS14_ses-SPpre_T2w_004_0000.nii.gz
cp sub-CTS15_ses-SPpre_acq-zoomit_T2w.nii.gz imagesTr/sub-CTS15_ses-SPpre_T2w_005_0000.nii.gz
cp sub-CTS20_ses-SPpre_acq-zoomit_T2w.nii.gz imagesTr/sub-CTS20_ses-SPpre_T2w_006_0000.nii.gz
mkdir labelsTr
cp sub-CTS04_ses-SPpre_T2w_rootlets_resampled_inzoomit.nii.gz labelsTr/sub-CTS04_ses-SPpre_T2w_001.nii.gz
cp sub-CTS05_ses-SPpre_T2w_rootlets_resampled_inzoomit.nii.gz labelsTr/sub-CTS05_ses-SPpre_T2w_002.nii.gz
cp sub-CTS10_ses-SPanat_T2w_rootlets_resampled_inzoomit.nii.gz labelsTr/sub-CTS10_ses-SPanat_T2w_003.nii.gz
cp sub-CTS14_ses-SPpre_T2w_rootlets_resampled_inzoomit.nii.gz labelsTr/sub-CTS14_ses-SPpre_T2w_004.nii.gz
cp sub-CTS15_ses-SPpre_T2w_rootlets_resampled_inzoomit.nii.gz labelsTr/sub-CTS15_ses-SPpre_T2w_005.nii.gz
cp sub-CTS20_ses-SPpre_T2w_rootlets_resampled_inzoomit.nii.gz labelsTr/sub-CTS20_ses-SPpre_T2w_006.nii.gz
  1. Changing label values to be consecutive (this is required by nnUNet)

(recoding using recode_nii.py)

$ cd labelsTr
$ for file in *nii.gz;do get_unique_values $file;done

[ 0. 20. 21. 22. 23. 24. 25. 26. 27.]
[ 0. 20. 21. 22. 23. 24. 25. 26.]
[ 0. 20. 21. 22. 23. 24. 25. 26. 27.]
[ 0. 20. 21. 22. 23. 24. 25. 26. 27. 28.]
[ 0. 20. 21. 22. 23. 24. 25. 26. 27. 28.]
[ 0. 20. 21. 22. 23. 24. 25. 26. 27. 28.]

$ for file in *nii.gz;do get_unique_values $file; python recode_nii.py $file $file; get_unique_values $file; done

[0. 1. 2. 3. 4. 5. 6. 7. 8.]
[0. 1. 2. 3. 4. 5. 6. 7.]
[0. 1. 2. 3. 4. 5. 6. 7. 8.]
[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
  1. Training semantic (level-specific) model Dataset201_LumbarRootlets

fold1, 4 training and 2 validation images.

dataset.json ```json { "name": "Dataset201_LumbarRootlets", "description": "Dataset201_LumbarRootlets", "channel_names": { "0": "acq-zoomit_T2w" }, "labels": { "background":0, "lvl1":1, "lvl2":2, "lvl3":3, "lvl4":4, "lvl5":5, "lvl6":6, "lvl7":7, "lvl8":8, "lvl9":9 }, "numTraining": 6, "file_ending": ".nii.gz", "overwrite_image_reader_writer": "SimpleITKIO" } ```
nnUNetv2_plan_and_preprocess -d 201 --verify_dataset_integrity -c 3d_fullres
CUDA_VISIBLE_DEVICES=3 nnUNetv2_train 201 3d_fullres 0 -tr nnUNetTrainer_2000epochs
  1. Training binary (all rootlets set to 1) model Dataset202_LumbarRootlets

fold1, 4 training and 2 validation images.

$ cd labelsTr
$ for file in *nii.gz;do sct_maths -i $file -bin 0.5 -o $file;done
$ for file in *nii.gz;do get_unique_values $file;done
[0. 1.]
[0. 1.]
[0. 1.]
[0. 1.]
[0. 1.]
[0. 1.]
dataset.json ```json { "name": "Dataset201_LumbarRootlets", "description": "Dataset201_LumbarRootlets", "channel_names": { "0": "acq-zoomit_T2w" }, "labels": { "background":0, "lvl1":1 }, "numTraining": 6, "file_ending": ".nii.gz", "overwrite_image_reader_writer": "SimpleITKIO" } ```
nnUNetv2_plan_and_preprocess -d 202 --verify_dataset_integrity -c 3d_fullres
CUDA_VISIBLE_DEVICES=3 nnUNetv2_train 202 3d_fullres 0 -tr nnUNetTrainer_2000epochs
valosekj commented 4 months ago

Dataset203_LumbarRootlets

Trying a binary model trained on both cervical (n=31) and lumbar (n=6) rootlets:

  1. merge Dataset202_LumbarRootlets and Dataset012_M5
  2. binarize all labels using for file in *nii.gz;do sct_maths -i $file -bin 0.5 -o $file;done
  3. train:
nnUNetv2_plan_and_preprocess -d 203 --verify_dataset_integrity -c 3d_fullres
CUDA_VISIBLE_DEVICES=2 nnUNetv2_train 203 3d_fullres 0   # I do not use `-tr` --> 1000 epochs in default
valosekj commented 4 months ago

Observations so far: Dataset202_LumbarRootlets (binary, trained on 6 lumbar labels only) is performing the best so far. Models comparison on a testing image unseen during the training/validation:

Kapture 2024-06-04 at 18 01 45

Legend:


Next step: try transfer learning, i.e., pre-train on cervical, finetune on lumbar

jcohenadad commented 4 months ago

@valosekj how different are the labels performed by Raphaelle and that performed by Theo/you? If too different, the model will get confused.

valosekj commented 4 months ago

@valosekj how different are the labels performed by Raphaelle and that performed by Theo/you?

Cervical and lumbar labels differ a lot. Lumbar rootlets have much greater angulation and thus a greater overlap between levels.

If too different, the model will get confused.

Indeed, this was my concern and why I tried the lumbar model only.

Cervical ![Kapture 2024-06-06 at 15 32 20](https://github.com/ivadomed/model-spinal-rootlets/assets/39456460/4eb8f441-7896-43c6-adea-68b171aaa147)
Lumbar ![Kapture 2024-06-06 at 15 36 12](https://github.com/ivadomed/model-spinal-rootlets/assets/39456460/46a19122-30dc-4d69-a664-165d29a60d98)
jcohenadad commented 4 months ago

aouch! that is a tricky project indeed 😅