Skip to content

Commit

Permalink
Merge branch 'master' into adds-codeformat
Browse files Browse the repository at this point in the history
  • Loading branch information
wyli authored May 10, 2022
2 parents a62562e + 835918a commit 9e00628
Show file tree
Hide file tree
Showing 25 changed files with 2,312 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/workflows/chatops.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ jobs:
- name: dispatch
uses: peter-evans/[email protected]
with:
token: ${{ secrets.PR_MAINTAIN_WYLI }}
# reaction-token: ${{ secrets.GITHUB_TOKEN }}
reactions: false
config: >
Expand Down
63 changes: 63 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
default_language_version:
python: python3.8

ci:
autofix_prs: true
autoupdate_commit_msg: '[pre-commit.ci] pre-commit suggestions'
autoupdate_schedule: quarterly
# submodules: true

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace
- id: check-yaml
- id: check-docstring-first
- id: check-executables-have-shebangs
- id: check-toml
- id: check-case-conflict
- id: check-added-large-files
args: ['--maxkb=1024']
- id: detect-private-key

#- repo: https://github.com/asottile/pyupgrade
# rev: v2.23.2
# hooks:
# - id: pyupgrade
# args: [--py36-plus]
# name: Upgrade code

#- repo: https://github.com/asottile/yesqa
# rev: v1.2.3
# hooks:
# - id: yesqa
# name: Unused noqa

#- repo: https://github.com/PyCQA/isort
# rev: 5.9.3
# hooks:
# - id: isort
# name: Format imports

# - repo: https://github.com/psf/black
# rev: 21.7b0
# hooks:
# - id: black
# name: Format code

#- repo: https://github.com/executablebooks/mdformat
# rev: 0.7.8
# hooks:
# - id: mdformat
# additional_dependencies:
# - mdformat-gfm
# - mdformat_frontmatter
# exclude: CHANGELOG.md

# - repo: https://github.com/PyCQA/flake8
# rev: 3.9.2
# hooks:
# - id: flake8
# name: Check PEP8
115 changes: 115 additions & 0 deletions DiNTS/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# DiNTS

## Overview

Repository for Paper "DiNTS: Differentiable Neural Network Topology Search for 3D Medical Image Segmentation" (CVPR'21)

## Installation

The code was tested with Anaconda and Python 3.7. After installing the Anaconda environment:

Clone the repo:

Install dependencies:
For PyTorch dependency, see pytorch.org for more details.
Install custom dependencies, horovod and openmpi e.t.c:

Use docker files:
Create a Dockerfile with
```
FROM nvcr.io/nvidian/pytorch:20.03-py3
RUN HOROVOD_NCCL_LINK=SHARED HOROVOD_NCCL_LIB=/usr/lib/x86_64-linux-gnu HOROVOD_NCCL_INCLUDE=/usr/include HOROVOD_GPU_ALLREDUCE=NCCL HOROVOD_GPU_BROADCAST=NCCL HOROVOD_WITH_PYTORCH=1 pip install --no-cache-dir --upgrade horovod
RUN apt install graphviz
RUN pip install graphviz
RUN pip install torchviz
RUN pip install tensorboardx
RUN pip install monai
```

Then
```
docker build -f Dockerfile -t nvcr.io/nvidian/pytorch:20.03-py3-horovod .
```

Run into Docker:
```
sudo docker run -it --gpus all --pid=host --shm-size 8G -v /home/yufan/Projects/:/workspace/Projects/ nvcr.io/nvidian/pytorch:20.03-py3-horovod
```

## Commands

All the scripts are in `./code`, `main.sh` will call other
scripts to perform search (`search.sh`), retrain (`retrain.sh`), test on validation results (`test_val.sh`), inference on test data (`test.sh`) and fuse (`fuse.sh`) all 5 fold results. Need to change
variable values within submit_all.sh to run your specific experiments.
The general pipeline is:

search the model on each task independently and results will be saved in
```
/workspace/Projects/darts-oneshot/search-bilevel-ent-mem${MEM}-${TASK}
```
retrain the model given `${TASK}`, `${MODEL}`, `${FOLD}`, results will be saved in the save folder as the searched model folder
Record the best retrained model manually and change the numbers (BESTTask01 e.t.c) in `main.sh`
Test on validation results on test results
The test results will be saved in each retraining folder
Fuse the five fold results and the results will be saved in designated folder
(Needs to be combined with step 6) The fused results are upsampled results, needs to resample to the original nii data size. I downloaded the fused results to my local workstation and resampled it (using fuse.py). The path to the original msd dataset needs to be provided.

The above operations are performed by change the value of N in `main.sh` and run
bash `main.sh`
Also you need to change the values of TASKS, FOLDS e.t.c to run specific experiments

### Argument Explanation
The arguments can also be found in config.py. Here are some quick references:

- iters is the total searching or retraining iteration. warmup_iters in searching is the iterations where architecture is not updated (the lr_scheduler is working, the temperature is not annealed).
- EF is the temperature annealing scheme. 0 is no annealing, 2 is linear decay
- EP=1, EF=0, topology=1 means no temperature annealing, use topology loss and entropy loss (not degrading binarized model validation result).
- base_lr * gpu number will be the final network weights lr
- opset is the operation set. opset 0, and setting cellop=4 will be the same with C2FNAS. opset1 includes 5 operations, 3D conv, 3 psudo 3d. Details can be found in operation.py
- path_iters is the number of iteration to print out architecture informations. Also in sampling based searching strategy, this is the training iteration for each sampled sub-model
- path_num is the number of pathes per block during sampling based training
- use_max will use one-shot supernet training, not sampling based method (should always add this one if training the whole supernet)
- there are several other arguments like finetune, retrain (deprecated), ef_end. those are related to binarize the model in searching stage and then finetune it. We are not using it since we double the channel number during retraining.

## Utilities

To further fuse the output segmetnation masks, user needs to create a `.json` file describing shape of each image for resizing/re-sampling. An example is shown in `./code/msd_size.json`.
```
{
"Task07_Pancreas": {
"pancreas_044.nii.gz": [
512,
512,
87
],
"pancreas_144.nii.gz": [
512,
512,
48
],
"pancreas_039.nii.gz": [
512,
512,
87
]
}
}
```

## Bibtex
```
@inproceedings{he2021dints,
title={DiNTS: Differentiable Neural Network Topology Search for 3D Medical Image Segmentation},
author={He, Yufan and Yang, Dong and Roth, Holger and Zhao, Can and Xu, Daguang},
booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},
pages={5841--5850},
year={2021}
}
@inproceedings{yu2020c2fnas,
title={C2fnas: Coarse-to-fine neural architecture search for 3d medical image segmentation},
author={Yu, Qihang and Yang, Dong and Roth, Holger and Bai, Yutong and Zhang, Yixiao and Yuille, Alan L and Xu, Daguang},
booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},
pages={4126--4135},
year={2020}
}
```
Binary file added DiNTS/arch_code_cvpr.pth
Binary file not shown.
32 changes: 32 additions & 0 deletions DiNTS/configs/config_Task01_BrainTumour.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
augmentation_monai:
aug_0: RandRotated|keys~image,label|range_x~0.3|range_y~0.3|range_z~0.3|mode~bilinear,nearest|prob~0.2
aug_1: RandZoomd|keys~image,label|min_zoom~0.8|max_zoom~1.2|mode~trilinear,nearest|align_corners~True,None|prob~0.16
aug_2: RandGaussianSmoothd|keys~image|sigma_x~0.5,1.15|sigma_y~0.5,1.15|sigma_z~0.5,1.15|prob~0.15
aug_3: RandScaleIntensityd|keys~image|factors~0.3|prob~0.5
aug_4: RandShiftIntensityd|keys~image|offsets~0.1|prob~0.5
aug_5: RandGaussianNoised|keys~image|std~0.01|prob~0.15
aug_6: RandFlipd|keys~image,label|spatial_axis~0|prob~0.5
aug_7: RandFlipd|keys~image,label|spatial_axis~1|prob~0.5
aug_8: RandFlipd|keys~image,label|spatial_axis~2|prob~0.5
core:
amp: true
deterministic: false
foreground_crop_margin: 0
infer_num_sw_batch_size: 6
infer_num_tta: 1
infer_overlap_ratio: 0.625
infer_patch_size: 96,96,96
input_channels: 4
intensity_norm: NormalizeIntensityd|keys~image|nonzero~True|channel_wise~True
interpolation: Identityd|keys~image,label
learning_rate: 0.025
learning_rate_milestones: 0.2,0.4,0.6,0.8
num_epochs: 1695
num_epochs_per_validation: 80
num_images_per_batch: 2
num_patches_per_image: 1
num_sw_batch_size: 6
output_classes: 4
overlap_ratio: 0.625
patch_size: 96,96,96
random_seed: 888
32 changes: 32 additions & 0 deletions DiNTS/configs/config_Task02_Heart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
augmentation_monai:
aug_0: RandRotated|keys~image,label|range_x~0.3|range_y~0.3|range_z~0.3|mode~bilinear,nearest|prob~0.2
aug_1: RandZoomd|keys~image,label|min_zoom~0.8|max_zoom~1.2|mode~trilinear,nearest|align_corners~True,None|prob~0.16
aug_2: RandGaussianSmoothd|keys~image|sigma_x~0.5,1.15|sigma_y~0.5,1.15|sigma_z~0.5,1.15|prob~0.15
aug_3: RandScaleIntensityd|keys~image|factors~0.3|prob~0.5
aug_4: RandShiftIntensityd|keys~image|offsets~0.1|prob~0.5
aug_5: RandGaussianNoised|keys~image|std~0.01|prob~0.15
aug_6: RandFlipd|keys~image,label|spatial_axis~0|prob~0.5
aug_7: RandFlipd|keys~image,label|spatial_axis~1|prob~0.5
aug_8: RandFlipd|keys~image,label|spatial_axis~2|prob~0.5
core:
amp: true
deterministic: false
foreground_crop_margin: 0
infer_num_sw_batch_size: 6
infer_num_tta: 1
infer_overlap_ratio: 0.625
infer_patch_size: 96,96,96
input_channels: 1
intensity_norm: NormalizeIntensityd|keys~image|nonzero~True|channel_wise~True
interpolation: Spacingd|keys~image,label|pixdim~1.0,1.0,1.0|mode~bilinear,nearest|align_corners~True,True
learning_rate: 0.025
learning_rate_milestones: 0.2,0.4,0.6,0.8
num_epochs: 20800 #4GPU
num_epochs_per_validation: 1000 #4GPU
num_images_per_batch: 2
num_patches_per_image: 1
num_sw_batch_size: 6
output_classes: 2
overlap_ratio: 0.625
patch_size: 96,96,96
random_seed: 888
32 changes: 32 additions & 0 deletions DiNTS/configs/config_Task03_Liver.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
augmentation_monai:
aug_0: RandRotated|keys~image,label|range_x~0.3|range_y~0.3|range_z~0.3|mode~bilinear,nearest|prob~0.2
aug_1: RandZoomd|keys~image,label|min_zoom~0.8|max_zoom~1.2|mode~trilinear,nearest|align_corners~True,None|prob~0.16
aug_2: RandGaussianSmoothd|keys~image|sigma_x~0.5,1.15|sigma_y~0.5,1.15|sigma_z~0.5,1.15|prob~0.15
aug_3: RandScaleIntensityd|keys~image|factors~0.3|prob~0.5
aug_4: RandShiftIntensityd|keys~image|offsets~0.1|prob~0.5
aug_5: RandGaussianNoised|keys~image|std~0.01|prob~0.15
aug_6: RandFlipd|keys~image,label|spatial_axis~0|prob~0.5
aug_7: RandFlipd|keys~image,label|spatial_axis~1|prob~0.5
aug_8: RandFlipd|keys~image,label|spatial_axis~2|prob~0.5
core:
amp: true
deterministic: false
foreground_crop_margin: 0
infer_num_sw_batch_size: 6
infer_num_tta: 1
infer_overlap_ratio: 0.625
infer_patch_size: 96,96,96
input_channels: 1
intensity_norm: ScaleIntensityRanged|keys~image|a_min~-21.0|a_max~189.0|b_min~0.0|b_max~1.0|clip~True
interpolation: Spacingd|keys~image,label|pixdim~1.0,1.0,1.0|mode~bilinear,nearest|align_corners~True,True
learning_rate: 0.025
learning_rate_milestones: 0.2,0.4,0.6,0.8
num_epochs: 6400
num_epochs_per_validation: 305
num_images_per_batch: 2
num_patches_per_image: 1
num_sw_batch_size: 6
output_classes: 3
overlap_ratio: 0.625
patch_size: 96,96,96
random_seed: 888
32 changes: 32 additions & 0 deletions DiNTS/configs/config_Task04_Hippocampus.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
augmentation_monai:
aug_0: RandRotated|keys~image,label|range_x~0.3|range_y~0.3|range_z~0.3|mode~bilinear,nearest|prob~0.2
aug_1: RandZoomd|keys~image,label|min_zoom~0.8|max_zoom~1.2|mode~trilinear,nearest|align_corners~True,None|prob~0.16
aug_2: RandGaussianSmoothd|keys~image|sigma_x~0.5,1.15|sigma_y~0.5,1.15|sigma_z~0.5,1.15|prob~0.15
aug_3: RandScaleIntensityd|keys~image|factors~0.3|prob~0.5
aug_4: RandShiftIntensityd|keys~image|offsets~0.1|prob~0.5
aug_5: RandGaussianNoised|keys~image|std~0.01|prob~0.15
aug_6: RandFlipd|keys~image,label|spatial_axis~0|prob~0.5
aug_7: RandFlipd|keys~image,label|spatial_axis~1|prob~0.5
aug_8: RandFlipd|keys~image,label|spatial_axis~2|prob~0.5
core:
amp: true
deterministic: false
foreground_crop_margin: 0
infer_num_sw_batch_size: 6
infer_num_tta: 1
infer_overlap_ratio: 0.625
infer_patch_size: 32,32,32
input_channels: 1
intensity_norm: NormalizeIntensityd|keys~image|nonzero~True|channel_wise~True
interpolation: Identityd|keys~image,label
learning_rate: 0.025
learning_rate_milestones: 0.2,0.4,0.6,0.8
num_epochs: 3200
num_epochs_per_validation: 150
num_images_per_batch: 2
num_patches_per_image: 1
num_sw_batch_size: 6
output_classes: 3
overlap_ratio: 0.625
patch_size: 32,32,32
random_seed: 888
32 changes: 32 additions & 0 deletions DiNTS/configs/config_Task05_Prostate.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
augmentation_monai:
aug_0: RandRotated|keys~image,label|range_x~0.3|range_y~0.3|range_z~0.3|mode~bilinear,nearest|prob~0.2
aug_1: RandZoomd|keys~image,label|min_zoom~0.8|max_zoom~1.2|mode~trilinear,nearest|align_corners~True,None|prob~0.16
aug_2: RandGaussianSmoothd|keys~image|sigma_x~0.5,1.15|sigma_y~0.5,1.15|sigma_z~0.5,1.15|prob~0.15
aug_3: RandScaleIntensityd|keys~image|factors~0.3|prob~0.5
aug_4: RandShiftIntensityd|keys~image|offsets~0.1|prob~0.5
aug_5: RandGaussianNoised|keys~image|std~0.01|prob~0.15
aug_6: RandFlipd|keys~image,label|spatial_axis~0|prob~0.5
aug_7: RandFlipd|keys~image,label|spatial_axis~1|prob~0.5
aug_8: RandFlipd|keys~image,label|spatial_axis~2|prob~0.5
core:
amp: true
deterministic: false
foreground_crop_margin: 0
infer_num_sw_batch_size: 6
infer_num_tta: 1
infer_overlap_ratio: 0.625
infer_patch_size: 96,96,32
input_channels: 2
intensity_norm: NormalizeIntensityd|keys~image|nonzero~True|channel_wise~True
interpolation: Spacingd|keys~image,label|pixdim~1.0,1.0,1.0|mode~bilinear,nearest|align_corners~True,True
learning_rate: 0.025
learning_rate_milestones: 0.2,0.4,0.6,0.8
num_epochs: 12800 # 4GPU
num_epochs_per_validation: 625 # 4GPU
num_images_per_batch: 2
num_patches_per_image: 1
num_sw_batch_size: 6
output_classes: 3
overlap_ratio: 0.625
patch_size: 96,96,32
random_seed: 888
32 changes: 32 additions & 0 deletions DiNTS/configs/config_Task06_Lung.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
augmentation_monai:
aug_0: RandRotated|keys~image,label|range_x~0.3|range_y~0.3|range_z~0.3|mode~bilinear,nearest|prob~0.2
aug_1: RandZoomd|keys~image,label|min_zoom~0.8|max_zoom~1.2|mode~trilinear,nearest|align_corners~True,None|prob~0.16
aug_2: RandGaussianSmoothd|keys~image|sigma_x~0.5,1.15|sigma_y~0.5,1.15|sigma_z~0.5,1.15|prob~0.15
aug_3: RandScaleIntensityd|keys~image|factors~0.3|prob~0.5
aug_4: RandShiftIntensityd|keys~image|offsets~0.1|prob~0.5
aug_5: RandGaussianNoised|keys~image|std~0.01|prob~0.15
aug_6: RandFlipd|keys~image,label|spatial_axis~0|prob~0.5
aug_7: RandFlipd|keys~image,label|spatial_axis~1|prob~0.5
aug_8: RandFlipd|keys~image,label|spatial_axis~2|prob~0.5
core:
amp: true
deterministic: false
foreground_crop_margin: 0
infer_num_sw_batch_size: 6
infer_num_tta: 1
infer_overlap_ratio: 0.625
infer_patch_size: 96,96,96
input_channels: 1
intensity_norm: ScaleIntensityRanged|keys~image|a_min~-1000.0|a_max~1000.0|b_min~0.0|b_max~1.0|clip~True
interpolation: Spacingd|keys~image,label|pixdim~1.0,1.0,1.0|mode~bilinear,nearest|align_corners~True,True
learning_rate: 0.025
learning_rate_milestones: 0.2,0.4,0.6,0.8
num_epochs: 12800
num_epochs_per_validation: 625
num_images_per_batch: 2
num_patches_per_image: 1
num_sw_batch_size: 6
output_classes: 2
overlap_ratio: 0.625
patch_size: 96,96,96
random_seed: 888
Loading

0 comments on commit 9e00628

Please sign in to comment.