Skip to content

Add detection example #751

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 102 commits into from
Jun 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
0820875
add detection example
Can-Zhao Jan 24, 2022
82e590f
detection example
Can-Zhao Jan 24, 2022
6bcf69b
Merge branch 'Project-MONAI:master' into detection
Can-Zhao Jan 24, 2022
c2580ed
reformat detection enample
Can-Zhao Jan 24, 2022
d3ad3f0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 24, 2022
2d6a00f
add evaluation
Can-Zhao Jan 31, 2022
e9c4722
Merge branch 'Project-MONAI:main' into detection
Can-Zhao Jun 6, 2022
f294d6e
add detection example
Can-Zhao Jun 10, 2022
80cf2eb
readme
Can-Zhao Jun 10, 2022
1e34ecf
add comments
Can-Zhao Jun 10, 2022
9187d14
add links
Can-Zhao Jun 10, 2022
85d0a66
add folders
Can-Zhao Jun 10, 2022
5bbea89
add folders
Can-Zhao Jun 10, 2022
b13825e
add folders
Can-Zhao Jun 10, 2022
4322b21
add folders
Can-Zhao Jun 10, 2022
f7c5eb1
jit save
Can-Zhao Jun 10, 2022
c72f35a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 10, 2022
594229c
typo
Can-Zhao Jun 10, 2022
c952697
Merge branch 'luna' of github.com:Can-Zhao/tutorials into luna
Can-Zhao Jun 10, 2022
6ed6459
typo
Can-Zhao Jun 10, 2022
31adea4
typo
Can-Zhao Jun 10, 2022
af312d5
typo
Can-Zhao Jun 10, 2022
0f8f4c9
correct post transform
Can-Zhao Jun 10, 2022
aae4e73
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 10, 2022
7a935ab
typo
Can-Zhao Jun 10, 2022
c454c81
Merge branch 'luna' of github.com:Can-Zhao/tutorials into luna
Can-Zhao Jun 10, 2022
112a888
add link
Can-Zhao Jun 10, 2022
e40b11f
shebang
Can-Zhao Jun 10, 2022
0f7341d
shebang
Can-Zhao Jun 10, 2022
6fc93b9
remove useless files
Can-Zhao Jun 10, 2022
690634b
mv data split to google drive
Can-Zhao Jun 14, 2022
ec8d91a
generte env files
Can-Zhao Jun 14, 2022
66bc0df
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 14, 2022
b298c16
typos
Can-Zhao Jun 14, 2022
e6ef5ca
typos
Can-Zhao Jun 14, 2022
3122bbf
typos
Can-Zhao Jun 14, 2022
5f29bb9
typos
Can-Zhao Jun 14, 2022
ec967e4
readme
Can-Zhao Jun 14, 2022
a89d80b
remove official evaluation script
Can-Zhao Jun 14, 2022
d184bd5
Merge branch 'main' into luna
Can-Zhao Jun 14, 2022
e5e2277
copyright
Can-Zhao Jun 14, 2022
b190afd
copyright
Can-Zhao Jun 14, 2022
fd525b3
Merge branch 'luna' of github.com:Can-Zhao/tutorials into luna
Can-Zhao Jun 14, 2022
ab1c407
copyright
Can-Zhao Jun 14, 2022
c3857bf
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 14, 2022
a1a74cd
nndet
Can-Zhao Jun 14, 2022
66a8d52
Merge branch 'luna' of github.com:Can-Zhao/tutorials into luna
Can-Zhao Jun 14, 2022
ae8d4ce
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 14, 2022
0dc8cad
rm unused config
Can-Zhao Jun 14, 2022
11fee38
Merge branch 'luna' of github.com:Can-Zhao/tutorials into luna
Can-Zhao Jun 14, 2022
e7548da
add curve
Can-Zhao Jun 14, 2022
3295bb5
add curve
Can-Zhao Jun 14, 2022
368e2e1
update fig
Can-Zhao Jun 14, 2022
960b0cc
update fig
Can-Zhao Jun 14, 2022
be9609e
update fig
Can-Zhao Jun 14, 2022
10c750d
update fig
Can-Zhao Jun 14, 2022
e1ce24a
update readme
Can-Zhao Jun 14, 2022
647f4a1
update readme
Can-Zhao Jun 14, 2022
9bf3489
update readme
Can-Zhao Jun 14, 2022
aa5b5fb
add comments in training
Can-Zhao Jun 14, 2022
e141f92
shebang
Can-Zhao Jun 14, 2022
2334e3e
fix a bug in training
Can-Zhao Jun 16, 2022
411e2b2
Merge branch 'Project-MONAI:main' into luna
Can-Zhao Jun 16, 2022
0806416
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 16, 2022
042b9ef
change download link
Can-Zhao Jun 16, 2022
ff9b85f
add result
Can-Zhao Jun 21, 2022
0802449
add result
Can-Zhao Jun 21, 2022
00d4c95
add result
Can-Zhao Jun 21, 2022
6e3b5a3
add result
Can-Zhao Jun 21, 2022
6da2c16
update train curve
Can-Zhao Jun 21, 2022
4f925b2
update result curve
Can-Zhao Jun 21, 2022
b88f0e7
add result table
Can-Zhao Jun 22, 2022
e424b84
update result table
Can-Zhao Jun 22, 2022
5c5dbc2
update result table
Can-Zhao Jun 22, 2022
c638487
update result table
Can-Zhao Jun 22, 2022
33b591d
update result table
Can-Zhao Jun 22, 2022
04244e6
update result table
Can-Zhao Jun 22, 2022
d06b18f
update result table
Can-Zhao Jun 22, 2022
7b7683f
update readme
Can-Zhao Jun 22, 2022
241eda0
update readme
Can-Zhao Jun 22, 2022
6f00d6f
update readme
Can-Zhao Jun 23, 2022
97963a7
Merge branch 'Project-MONAI:main' into luna
Can-Zhao Jun 23, 2022
88b7310
add acknowledge
Can-Zhao Jun 23, 2022
b622686
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 23, 2022
1c4237c
update readme
Can-Zhao Jun 23, 2022
966c899
Merge branch 'luna' of github.com:Can-Zhao/tutorials into luna
Can-Zhao Jun 23, 2022
294b2de
update readme
Can-Zhao Jun 23, 2022
7fbdb60
update readme
Can-Zhao Jun 23, 2022
cc61486
update readme
Can-Zhao Jun 23, 2022
c1f4c61
update readme
Can-Zhao Jun 23, 2022
209365b
update readme
Can-Zhao Jun 23, 2022
b6a9027
update readme
Can-Zhao Jun 23, 2022
f592fd8
update readme
Can-Zhao Jun 23, 2022
86a1e5c
update readme
Can-Zhao Jun 23, 2022
c4ef515
update readme
Can-Zhao Jun 23, 2022
e02f516
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 23, 2022
6e1154d
update readme
Can-Zhao Jun 23, 2022
31a5556
update readme
Can-Zhao Jun 23, 2022
a502cb9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 23, 2022
0f270a5
update readme
Can-Zhao Jun 23, 2022
acc686b
Merge branch 'luna' of github.com:Can-Zhao/tutorials into luna
Can-Zhao Jun 23, 2022
ad4ef43
update readme
Can-Zhao Jun 23, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions detection/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Detection Example
This folder contains an example to run train and validate a 3D detection RetinaNet model.
The workflow of MONAI detection module is shown in the following figure.
<p align="center">
<img src="https://github.com/Project-MONAI/MONAI/blob/dev/docs/images/detection.png" alt="detection scheme")
</p>

MONAI detection implementation is based on the following papers:

**RetinaNet:** Lin, Tsung-Yi, et al. "Focal loss for dense object detection." ICCV 2017. https://arxiv.org/abs/1708.02002

**Implementation details:** Baumgartner, Michael, et al. "nnDetection: A self-configuring method for medical object detection." MICCAI 2021. https://arxiv.org/pdf/2106.00817.pdf

**ATSS Matcher:** Zhang, Shifeng, et al. "Bridging the gap between anchor-based and anchor-free detection via adaptive training sample selection." CVPR 2020. https://openaccess.thecvf.com/content_CVPR_2020/papers/Zhang_Bridging_the_Gap_Between_Anchor-Based_and_Anchor-Free_Detection_via_Adaptive_CVPR_2020_paper.pdf

### 1. Data

The dataset we are experimenting in this example is LUNA16 (https://luna16.grand-challenge.org/Home/).
LUNA16 is a public dataset of CT lung nodule detection. Using raw CT scans, the goal is to identify locations of possible nodules, and to assign a probability for being a nodule to each location.

Disclaimer: We are not the host of the data. Please make sure to read the requirements and usage policies of the data and give credit to the authors of the dataset!

We follow the official 10-fold data splitting from LUNA16 challenge and generate data split json files using the script from [nnDetection](https://github.com/MIC-DKFZ/nnDetection/blob/main/projects/Task016_Luna/scripts/prepare.py).
The resulted json files can be downloaded from https://github.com/Project-MONAI/MONAI-extra-test-data/releases/download/0.8.1/LUNA16_datasplit-20220615T233840Z-001.zip.
In these files, the values of "box" are the ground truth boxes in world coordinate.

### 2. Questions and bugs

- For questions relating to the use of MONAI, please us our [Discussions tab](https://github.com/Project-MONAI/MONAI/discussions) on the main repository of MONAI.
- For bugs relating to MONAI functionality, please create an issue on the [main repository](https://github.com/Project-MONAI/MONAI/issues).
- For bugs relating to the running of a tutorial, please create an issue in [this repository](https://github.com/Project-MONAI/Tutorials/issues).

### 3. Run the example
#### [Prepare Your Data](./luna16_prepare_images.py)

The raw CT images in LUNA16 have various of voxel sizes. The first step is to resample them to the same voxel size, which is defined in the value of "spacing" in [./config/config_train_luna16_16g.json](./config/config_train_luna16_16g.json).

Then, please open [luna16_prepare_env_files.py](luna16_prepare_env_files.py), change the value of "raw_data_base_dir" to the directory where you store the downloaded images, the value of "downloaded_datasplit_dir" to where you downloaded the data split json files, and the value of "resampled_data_base_dir" to the target directory where you will save the resampled images.

Finally, resample the images by running
```bash
python3 luna16_prepare_env_files.py
python3 luna16_prepare_images.py -c ./config/config_train_luna16_16g.json
```

The original images are with mhd/raw format, the resampled images will be with Nifti format.

#### [3D Detection Training](./luna16_training.py)

The LUNA16 dataset was splitted into 10-fold to run cross-fold training and inference.

Taking fold 0 as an example, run:
```bash
python3 luna16_training.py \
-e ./config/environment_luna16_fold0.json \
-c ./config/config_train_luna16_16g.json
```

This python script uses batch size and patch size defined in [./config/config_train_luna16_16g.json](./config/config_train_luna16_16g.json), which works for a 16G GPU.
If you have a different GPU memory size, please change "batch_size", "patch_size", and "val_patch_size" to fit the GPU you use.

For fold i, please run
```bash
python3 luna16_training.py \
-e ./config/environment_luna16_fold${i}.json \
-c ./config/config_train_luna16_16g.json
```

For each fold, 95% of the training data is used for training, while the rest 5% is used for validation and model selection.
The training and validation curves for 300 epochs of 10 folds are shown as below. The upper row shows the training losses for box regression and classification. The bottom row shows the validation mAP and mAR for IoU ranging from 0.1 to 0.5.
<p align="center">
<img src="luna16_tfevent.png" alt="detection train curve")
</p>

With a single DGX1V 16G GPU, it took around 55 hours to train 300 epochs for each data fold.

#### [3D Detection Inference](./luna16_testing.py)

If you have a different GPU memory size than 16G, please maximize "val_patch_size" in [./config/config_train_luna16_16g.json](./config/config_train_luna16_16g.json) to fit the GPU you use.

For fold i, please run
```bash
python3 luna16_testing.py \
-e ./config/environment_luna16_fold${i}.json \
-c ./config/config_train_luna16_16g.json
```

#### [LUNA16 Detection Evaluation](./run_luna16_offical_eval.sh)
Please download the official LUNA16 evaluation scripts from https://luna16.grand-challenge.org/Evaluation/,
and save it as ./evaluation_luna16

./evaluation_luna16/noduleCADEvaluationLUNA16.py will be the main python script to generate evaluation scores.

To run evaluation, please first make sure the 10 resulted json files result_luna16_fold{i}.json are in ./result folder.
Then run:
```bash
./run_luna16_offical_eval.sh
```

This bash script first combines the 10 result json files from 10 folds into one csv file,
then runs the official LUNA16 evaluation scripts saved in ./evaluation_luna16.

The evaluation scores will be stored in ./result/eval_luna16_scores

We got FROC result as shown in the table below. It is comparable with the result in [nnDetection](https://arxiv.org/pdf/2106.00817.pdf) Table 2.

| Methods | 1/8 | 1/4 | 1/2 | 1 | 2 | 4 | 8 |
| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| [Liu et al. (2019)](https://arxiv.org/pdf/1906.03467.pdf) | **0.848** | 0.876 | 0.905 | 0.933 | 0.943 | 0.957 | 0.970 |
| [nnDetection (2021)](https://arxiv.org/pdf/2106.00817.pdf) | 0.812 | **0.885** | 0.927 | 0.950 | 0.969 | 0.979 | 0.985 |
| MONAI detection | 0.835 | **0.885** | **0.931** | **0.957** | **0.974** | **0.983** | **0.988** |

**Table 1**. The FROC sensitivity values at the predefined false positive per scan thresholds of the LUNA16 challenge.

This MONAI example uses similar training and inference workflows and same hyper-parameters as [nnDetection](https://github.com/MIC-DKFZ/nnDetection) LUNA16.

The major differences are:
1) we use a different learning rate scheduler,
2) during training, we run validation with 5% of the training data and select the best model for inference, while nnDetection directly uses the model from the last epoch for inference,
3) when input image is too large to fit in the GPU memory, inference is performed on patches. We do sliding window aggregation on the predicted class logits and box regression, while nnDetection uses a different aggregation stategy from [Jaeger et al.](http://proceedings.mlr.press/v116/jaeger20a/jaeger20a.pdf).


There are other differences that may have minor impact on the performance:
1) we use RetinaNet, while nnDetection uses [RetinaUnet](http://proceedings.mlr.press/v116/jaeger20a/jaeger20a.pdf),
2) we directly apply the trained model to the images/patches during inference, while nnDetection applies the model to the images/patches flipped in three axes and average the flipped-back results.


### Acknowledgement
We greatly appreciate Michael Baumgartner, one of the main contributor of [nnDetection](https://github.com/MIC-DKFZ/nnDetection) project, for his vital cooperation and help in ensuring the successful completion of this MONAI detection module.
17 changes: 17 additions & 0 deletions detection/config/config_train_luna16_16g.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"gt_box_mode": "cccwhd",
"lr": 1e-2,
"spacing": [0.703125, 0.703125, 1.25],
"batch_size": 4,
"patch_size": [192,192,80],
"val_patch_size": [512,512,208],
"fg_labels": [0],
"n_input_channels": 1,
"spatial_dims": 3,
"score_thresh": 0.02,
"nms_thresh": 0.22,
"returned_layers": [1,2],
"conv1_t_stride": [2,2,1],
"base_anchor_shapes": [[6,8,4],[8,6,5],[10,10,6]],
"balanced_sampler_pos_fraction": 0.3
}
Loading