|
69 | 69 | "import tempfile\n",
|
70 | 70 | "from monai.bundle.config_parser import ConfigParser\n",
|
71 | 71 | "from monai.apps.nnunet import nnUNetV2Runner\n",
|
72 |
| - "\n", |
| 72 | + "import random\n", |
73 | 73 | "from monai.bundle.nnunet import convert_nnunet_to_monai_bundle\n",
|
| 74 | + "import json\n", |
| 75 | + "from pathlib import Path\n", |
74 | 76 | "\n",
|
75 | 77 | "print_config()"
|
76 | 78 | ]
|
|
86 | 88 | "If not specified a temporary directory will be used."
|
87 | 89 | ]
|
88 | 90 | },
|
| 91 | + { |
| 92 | + "cell_type": "code", |
| 93 | + "execution_count": null, |
| 94 | + "metadata": {}, |
| 95 | + "outputs": [], |
| 96 | + "source": [ |
| 97 | + "os.environ[\"MONAI_DATA_DIRECTORY\"] = \"/home/maia-user/Documents/GitHub/tutorials/bundle/MONAI/Data\"" |
| 98 | + ] |
| 99 | + }, |
89 | 100 | {
|
90 | 101 | "cell_type": "code",
|
91 | 102 | "execution_count": null,
|
|
109 | 120 | ]
|
110 | 121 | },
|
111 | 122 | {
|
112 |
| - "cell_type": "markdown", |
| 123 | + "cell_type": "code", |
| 124 | + "execution_count": null, |
| 125 | + "metadata": {}, |
| 126 | + "outputs": [], |
| 127 | + "source": [ |
| 128 | + "dataroot = os.path.join(root_dir, \"Task09_Spleen/\")\n", |
| 129 | + "\n", |
| 130 | + "test_dir = os.path.join(dataroot, \"imagesTs/\")\n", |
| 131 | + "train_dir = os.path.join(dataroot, \"imagesTr/\")\n", |
| 132 | + "label_dir = os.path.join(dataroot, \"labelsTr/\")" |
| 133 | + ] |
| 134 | + }, |
| 135 | + { |
| 136 | + "cell_type": "code", |
| 137 | + "execution_count": null, |
| 138 | + "metadata": {}, |
| 139 | + "outputs": [], |
| 140 | + "source": [ |
| 141 | + "datalist_json = {\"testing\": [], \"training\": []}" |
| 142 | + ] |
| 143 | + }, |
| 144 | + { |
| 145 | + "cell_type": "code", |
| 146 | + "execution_count": null, |
| 147 | + "metadata": {}, |
| 148 | + "outputs": [], |
| 149 | + "source": [ |
| 150 | + "datalist_json[\"testing\"] = [\n", |
| 151 | + " {\"image\": \"./imagesTs/\" + file} for file in os.listdir(test_dir) if (\".nii.gz\" in file) and (\"._\" not in file)\n", |
| 152 | + "]" |
| 153 | + ] |
| 154 | + }, |
| 155 | + { |
| 156 | + "cell_type": "code", |
| 157 | + "execution_count": null, |
| 158 | + "metadata": {}, |
| 159 | + "outputs": [], |
| 160 | + "source": [ |
| 161 | + "datalist_json[\"training\"] = [\n", |
| 162 | + " {\"image\": \"./imagesTr/\" + file, \"label\": \"./labelsTr/\" + file, \"fold\": 0}\n", |
| 163 | + " for file in os.listdir(train_dir)\n", |
| 164 | + " if (\".nii.gz\" in file) and (\"._\" not in file)\n", |
| 165 | + "] # Initialize as single fold" |
| 166 | + ] |
| 167 | + }, |
| 168 | + { |
| 169 | + "cell_type": "code", |
| 170 | + "execution_count": null, |
| 171 | + "metadata": {}, |
| 172 | + "outputs": [], |
| 173 | + "source": [ |
| 174 | + "random.seed(42)\n", |
| 175 | + "random.shuffle(datalist_json[\"training\"])" |
| 176 | + ] |
| 177 | + }, |
| 178 | + { |
| 179 | + "cell_type": "code", |
| 180 | + "execution_count": null, |
| 181 | + "metadata": {}, |
| 182 | + "outputs": [], |
| 183 | + "source": [ |
| 184 | + "num_folds = 5\n", |
| 185 | + "fold_size = len(datalist_json[\"training\"]) // num_folds\n", |
| 186 | + "for i in range(num_folds):\n", |
| 187 | + " for j in range(fold_size):\n", |
| 188 | + " datalist_json[\"training\"][i * fold_size + j][\"fold\"] = i" |
| 189 | + ] |
| 190 | + }, |
| 191 | + { |
| 192 | + "cell_type": "code", |
| 193 | + "execution_count": null, |
113 | 194 | "metadata": {},
|
| 195 | + "outputs": [], |
114 | 196 | "source": [
|
115 |
| - "At the end of the notebook, remember to copy the generated `msd_task09_spleen_folds.json` file to the `<root_dir>/Task09_Spleen` directory." |
| 197 | + "datalist_file = Path(root_dir).joinpath(\"Task09_Spleen\",\"Task09_Spleen_folds.json\")\n", |
| 198 | + "with open(datalist_file, \"w\", encoding=\"utf-8\") as f:\n", |
| 199 | + " json.dump(datalist_json, f, ensure_ascii=False, indent=4)\n", |
| 200 | + "print(f\"Datalist is saved to {datalist_file}\")" |
116 | 201 | ]
|
117 | 202 | },
|
118 | 203 | {
|
|
144 | 229 | "data_src_cfg = os.path.join(nnunet_root_dir, \"data_src_cfg.yaml\")\n",
|
145 | 230 | "data_src = {\n",
|
146 | 231 | " \"modality\": \"CT\",\n",
|
| 232 | + " \"dataset_name_or_id\": \"09\",\n", |
147 | 233 | " \"datalist\": os.path.join(root_dir, \"Task09_Spleen/msd_task09_spleen_folds.json\"),\n",
|
148 | 234 | " \"dataroot\": os.path.join(root_dir, \"Task09_Spleen\"),\n",
|
149 | 235 | "}\n",
|
|
165 | 251 | {
|
166 | 252 | "cell_type": "code",
|
167 | 253 | "execution_count": null,
|
168 |
| - "metadata": { |
169 |
| - "scrolled": true |
170 |
| - }, |
| 254 | + "metadata": {}, |
171 | 255 | "outputs": [],
|
172 | 256 | "source": [
|
173 |
| - "runner.plan_and_process(npfp=2, n_proc=[2, 2, 2])" |
| 257 | + "runner.convert_dataset()" |
174 | 258 | ]
|
175 | 259 | },
|
176 | 260 | {
|
|
179 | 263 | "metadata": {},
|
180 | 264 | "outputs": [],
|
181 | 265 | "source": [
|
182 |
| - "runner.train(configs=\"3d_fullres\")" |
| 266 | + "runner.plan_and_process(npfp=2, n_proc=[2, 2, 2])" |
183 | 267 | ]
|
184 | 268 | },
|
185 | 269 | {
|
186 | 270 | "cell_type": "code",
|
187 | 271 | "execution_count": null,
|
188 |
| - "metadata": { |
189 |
| - "scrolled": true |
190 |
| - }, |
| 272 | + "metadata": {}, |
191 | 273 | "outputs": [],
|
192 | 274 | "source": [
|
193 |
| - "runner.run(run_train=True, run_find_best_configuration=False, run_predict_ensemble_postprocessing=False)" |
| 275 | + "runner.train_single_model(config=\"3d_fullres\", fold=0)" |
194 | 276 | ]
|
195 | 277 | },
|
196 | 278 | {
|
|
217 | 299 | "source": [
|
218 | 300 | "%%bash\n",
|
219 | 301 | "\n",
|
220 |
| - "rm nnUNetBundle/configs/inference.json\n", |
| 302 | + "\n", |
221 | 303 | "python -m monai.bundle init_bundle nnUNetBundle\n",
|
222 | 304 | "\n",
|
| 305 | + "rm nnUNetBundle/configs/inference.json\n", |
223 | 306 | "mkdir -p nnUNetBundle/src\n",
|
224 | 307 | "touch nnUNetBundle/src/__init__.py\n",
|
225 | 308 | "which tree && tree nnUNetBundle || true"
|
|
348 | 431 | "outputs": [],
|
349 | 432 | "source": [
|
350 | 433 | "nnunet_config = {\n",
|
351 |
| - " \"dataset_name_or_id\": \"001\",\n", |
352 |
| - " \"nnunet_trainer\": \"nnUNetTrainer_1epoch\",\n", |
| 434 | + " \"dataset_name_or_id\": \"009\",\n", |
| 435 | + " \"nnunet_trainer\": \"nnUNetTrainer_10epochs\",\n", |
353 | 436 | "}\n",
|
354 | 437 | "\n",
|
355 | 438 | "bundle_root = \"nnUNetBundle\"\n",
|
|
392 | 475 | "source": [
|
393 | 476 | "%%bash\n",
|
394 | 477 | "\n",
|
| 478 | + "\n", |
| 479 | + "BUNDLE_ROOT=nnUNetBundle\n", |
| 480 | + "MONAI_DATA_DIRECTORY=/home/maia-user/Documents/GitHub/tutorials/bundle/MONAI/Data\n", |
| 481 | + "\n", |
395 | 482 | "python -m monai.bundle run \\\n",
|
396 |
| - " --config-file nnUNetBundle/configs/inference.yaml \\\n", |
397 |
| - " --bundle-root nnUNetBundle \\\n", |
| 483 | + " --config-file $BUNDLE_ROOT/configs/inference.yaml \\\n", |
| 484 | + " --bundle-root $BUNDLE_ROOT \\\n", |
398 | 485 | " --data_list_file $MONAI_DATA_DIRECTORY/Task09_Spleen/msd_task09_spleen_folds.json \\\n",
|
399 |
| - " --output-dir nnUNetBundle/pred_output \\\n", |
400 |
| - " --data_dir /home/maia-user/Tutorials/MONAI/data/Task09_Spleen \\\n", |
401 |
| - " --logging-file nnUNetBundle/configs/logging.conf" |
| 486 | + " --output-dir $BUNDLE_ROOT/pred_output \\\n", |
| 487 | + " --data_dir $MONAI_DATA_DIRECTORY/Task09_Spleen \\\n", |
| 488 | + " --logging-file$BUNDLE_ROOT/configs/logging.conf" |
402 | 489 | ]
|
403 | 490 | },
|
404 | 491 | {
|
|
410 | 497 | "In some cases, you may want to train the nnUNet model from the MONAI Bundle (i.e., without using the nnUNetV2Runner).\n",
|
411 | 498 | "This is usually the case when the specific training logic is designed to be used with the MONAI Bundle, such as the Active Learning in MONAI Label or Federated Learning in NVFLare using the MONAI Algo implementation.\n",
|
412 | 499 | "\n",
|
| 500 | + "For more details on how to create the nnUNet MONAI Bundle and test all the different components, you can follow the instructions in the [nnUNet MONAI Bundle Notebook](./nnUNet_Bundle.ipynb)\n", |
| 501 | + "\n", |
413 | 502 | "This can be done by following the steps below:"
|
414 | 503 | ]
|
415 | 504 | },
|
|
432 | 521 | " - $import pathlib\n",
|
433 | 522 | "\n",
|
434 | 523 | "\n",
|
435 |
| - "pymaia_config_dict: \"$json.load(open(@pymaia_config_file))\"\n", |
436 | 524 | "bundle_root: .\n",
|
437 | 525 | "ckpt_dir: \"$@bundle_root + '/models'\"\n",
|
438 | 526 | "num_classes: 2\n",
|
|
760 | 848 | "kernelspec": {
|
761 | 849 | "display_name": "MONAI",
|
762 | 850 | "language": "python",
|
763 |
| - "name": "monai" |
| 851 | + "name": "python3" |
764 | 852 | },
|
765 | 853 | "language_info": {
|
766 | 854 | "codemirror_mode": {
|
|
0 commit comments