Skip to content

Commit 497fd58

Browse files
Add detection example (#751)
* add detection example * detection example * reformat detection enample * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * add evaluation * add detection example Signed-off-by: Can Zhao <[email protected]> * readme Signed-off-by: Can Zhao <[email protected]> * add comments Signed-off-by: Can Zhao <[email protected]> * add links Signed-off-by: Can Zhao <[email protected]> * add folders Signed-off-by: Can Zhao <[email protected]> * add folders Signed-off-by: Can Zhao <[email protected]> * add folders Signed-off-by: Can Zhao <[email protected]> * add folders Signed-off-by: Can Zhao <[email protected]> * jit save Signed-off-by: Can Zhao <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * typo Signed-off-by: Can Zhao <[email protected]> * typo Signed-off-by: Can Zhao <[email protected]> * typo Signed-off-by: Can Zhao <[email protected]> * typo Signed-off-by: Can Zhao <[email protected]> * correct post transform Signed-off-by: Can Zhao <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * typo Signed-off-by: Can Zhao <[email protected]> * add link Signed-off-by: Can Zhao <[email protected]> * shebang Signed-off-by: Can Zhao <[email protected]> * shebang Signed-off-by: Can Zhao <[email protected]> * remove useless files Signed-off-by: Can Zhao <[email protected]> * mv data split to google drive Signed-off-by: Can Zhao <[email protected]> * generte env files Signed-off-by: Can Zhao <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * typos Signed-off-by: Can Zhao <[email protected]> * typos Signed-off-by: Can Zhao <[email protected]> * typos Signed-off-by: Can Zhao <[email protected]> * readme Signed-off-by: Can Zhao <[email protected]> * remove official evaluation script Signed-off-by: Can Zhao <[email protected]> * copyright Signed-off-by: Can Zhao <[email protected]> * copyright Signed-off-by: Can Zhao <[email protected]> * copyright Signed-off-by: Can Zhao <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * nndet Signed-off-by: Can Zhao <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * rm unused config Signed-off-by: Can Zhao <[email protected]> * add curve Signed-off-by: Can Zhao <[email protected]> * add curve Signed-off-by: Can Zhao <[email protected]> * update fig Signed-off-by: Can Zhao <[email protected]> * update fig Signed-off-by: Can Zhao <[email protected]> * update fig Signed-off-by: Can Zhao <[email protected]> * update fig Signed-off-by: Can Zhao <[email protected]> * update readme Signed-off-by: Can Zhao <[email protected]> * update readme Signed-off-by: Can Zhao <[email protected]> * update readme Signed-off-by: Can Zhao <[email protected]> * add comments in training Signed-off-by: Can Zhao <[email protected]> * shebang Signed-off-by: Can Zhao <[email protected]> * fix a bug in training Signed-off-by: Can Zhao <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * change download link Signed-off-by: Can Zhao <[email protected]> * add result Signed-off-by: Can Zhao <[email protected]> * add result Signed-off-by: Can Zhao <[email protected]> * add result Signed-off-by: Can Zhao <[email protected]> * add result Signed-off-by: Can Zhao <[email protected]> * update train curve Signed-off-by: Can Zhao <[email protected]> * update result curve Signed-off-by: Can Zhao <[email protected]> * add result table Signed-off-by: Can Zhao <[email protected]> * update result table Signed-off-by: Can Zhao <[email protected]> * update result table Signed-off-by: Can Zhao <[email protected]> * update result table Signed-off-by: Can Zhao <[email protected]> * update result table Signed-off-by: Can Zhao <[email protected]> * update result table Signed-off-by: Can Zhao <[email protected]> * update result table Signed-off-by: Can Zhao <[email protected]> * update readme Signed-off-by: Can Zhao <[email protected]> * update readme Signed-off-by: Can Zhao <[email protected]> * update readme Signed-off-by: Can Zhao <[email protected]> * add acknowledge Signed-off-by: Can Zhao <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * update readme Signed-off-by: Can Zhao <[email protected]> * update readme Signed-off-by: Can Zhao <[email protected]> * update readme Signed-off-by: Can Zhao <[email protected]> * update readme Signed-off-by: Can Zhao <[email protected]> * update readme Signed-off-by: Can Zhao <[email protected]> * update readme Signed-off-by: Can Zhao <[email protected]> * update readme Signed-off-by: Can Zhao <[email protected]> * update readme Signed-off-by: Can Zhao <[email protected]> * update readme Signed-off-by: Can Zhao <[email protected]> * update readme Signed-off-by: Can Zhao <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * update readme Signed-off-by: Can Zhao <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * update readme Signed-off-by: Can Zhao <[email protected]> * update readme Signed-off-by: Can Zhao <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 3848027 commit 497fd58

12 files changed

+1483
-0
lines changed

detection/README.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# Detection Example
2+
This folder contains an example to run train and validate a 3D detection RetinaNet model.
3+
The workflow of MONAI detection module is shown in the following figure.
4+
<p align="center">
5+
<img src="https://github.com/Project-MONAI/MONAI/blob/dev/docs/images/detection.png" alt="detection scheme")
6+
</p>
7+
8+
MONAI detection implementation is based on the following papers:
9+
10+
**RetinaNet:** Lin, Tsung-Yi, et al. "Focal loss for dense object detection." ICCV 2017. https://arxiv.org/abs/1708.02002
11+
12+
**Implementation details:** Baumgartner, Michael, et al. "nnDetection: A self-configuring method for medical object detection." MICCAI 2021. https://arxiv.org/pdf/2106.00817.pdf
13+
14+
**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
15+
16+
### 1. Data
17+
18+
The dataset we are experimenting in this example is LUNA16 (https://luna16.grand-challenge.org/Home/).
19+
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.
20+
21+
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!
22+
23+
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).
24+
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.
25+
In these files, the values of "box" are the ground truth boxes in world coordinate.
26+
27+
### 2. Questions and bugs
28+
29+
- 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.
30+
- For bugs relating to MONAI functionality, please create an issue on the [main repository](https://github.com/Project-MONAI/MONAI/issues).
31+
- For bugs relating to the running of a tutorial, please create an issue in [this repository](https://github.com/Project-MONAI/Tutorials/issues).
32+
33+
### 3. Run the example
34+
#### [Prepare Your Data](./luna16_prepare_images.py)
35+
36+
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).
37+
38+
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.
39+
40+
Finally, resample the images by running
41+
```bash
42+
python3 luna16_prepare_env_files.py
43+
python3 luna16_prepare_images.py -c ./config/config_train_luna16_16g.json
44+
```
45+
46+
The original images are with mhd/raw format, the resampled images will be with Nifti format.
47+
48+
#### [3D Detection Training](./luna16_training.py)
49+
50+
The LUNA16 dataset was splitted into 10-fold to run cross-fold training and inference.
51+
52+
Taking fold 0 as an example, run:
53+
```bash
54+
python3 luna16_training.py \
55+
-e ./config/environment_luna16_fold0.json \
56+
-c ./config/config_train_luna16_16g.json
57+
```
58+
59+
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.
60+
If you have a different GPU memory size, please change "batch_size", "patch_size", and "val_patch_size" to fit the GPU you use.
61+
62+
For fold i, please run
63+
```bash
64+
python3 luna16_training.py \
65+
-e ./config/environment_luna16_fold${i}.json \
66+
-c ./config/config_train_luna16_16g.json
67+
```
68+
69+
For each fold, 95% of the training data is used for training, while the rest 5% is used for validation and model selection.
70+
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.
71+
<p align="center">
72+
<img src="luna16_tfevent.png" alt="detection train curve")
73+
</p>
74+
75+
With a single DGX1V 16G GPU, it took around 55 hours to train 300 epochs for each data fold.
76+
77+
#### [3D Detection Inference](./luna16_testing.py)
78+
79+
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.
80+
81+
For fold i, please run
82+
```bash
83+
python3 luna16_testing.py \
84+
-e ./config/environment_luna16_fold${i}.json \
85+
-c ./config/config_train_luna16_16g.json
86+
```
87+
88+
#### [LUNA16 Detection Evaluation](./run_luna16_offical_eval.sh)
89+
Please download the official LUNA16 evaluation scripts from https://luna16.grand-challenge.org/Evaluation/,
90+
and save it as ./evaluation_luna16
91+
92+
./evaluation_luna16/noduleCADEvaluationLUNA16.py will be the main python script to generate evaluation scores.
93+
94+
To run evaluation, please first make sure the 10 resulted json files result_luna16_fold{i}.json are in ./result folder.
95+
Then run:
96+
```bash
97+
./run_luna16_offical_eval.sh
98+
```
99+
100+
This bash script first combines the 10 result json files from 10 folds into one csv file,
101+
then runs the official LUNA16 evaluation scripts saved in ./evaluation_luna16.
102+
103+
The evaluation scores will be stored in ./result/eval_luna16_scores
104+
105+
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.
106+
107+
| Methods | 1/8 | 1/4 | 1/2 | 1 | 2 | 4 | 8 |
108+
| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
109+
| [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 |
110+
| [nnDetection (2021)](https://arxiv.org/pdf/2106.00817.pdf) | 0.812 | **0.885** | 0.927 | 0.950 | 0.969 | 0.979 | 0.985 |
111+
| MONAI detection | 0.835 | **0.885** | **0.931** | **0.957** | **0.974** | **0.983** | **0.988** |
112+
113+
**Table 1**. The FROC sensitivity values at the predefined false positive per scan thresholds of the LUNA16 challenge.
114+
115+
This MONAI example uses similar training and inference workflows and same hyper-parameters as [nnDetection](https://github.com/MIC-DKFZ/nnDetection) LUNA16.
116+
117+
The major differences are:
118+
1) we use a different learning rate scheduler,
119+
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,
120+
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).
121+
122+
123+
There are other differences that may have minor impact on the performance:
124+
1) we use RetinaNet, while nnDetection uses [RetinaUnet](http://proceedings.mlr.press/v116/jaeger20a/jaeger20a.pdf),
125+
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.
126+
127+
128+
### Acknowledgement
129+
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.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"gt_box_mode": "cccwhd",
3+
"lr": 1e-2,
4+
"spacing": [0.703125, 0.703125, 1.25],
5+
"batch_size": 4,
6+
"patch_size": [192,192,80],
7+
"val_patch_size": [512,512,208],
8+
"fg_labels": [0],
9+
"n_input_channels": 1,
10+
"spatial_dims": 3,
11+
"score_thresh": 0.02,
12+
"nms_thresh": 0.22,
13+
"returned_layers": [1,2],
14+
"conv1_t_stride": [2,2,1],
15+
"base_anchor_shapes": [[6,8,4],[8,6,5],[10,10,6]],
16+
"balanced_sampler_pos_fraction": 0.3
17+
}

0 commit comments

Comments
 (0)