Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
329 commits
Select commit Hold shift + click to select a range
807ad43
Refactored `benchmark.py` to enhance dataset handling with `sliding_w…
ATATC Dec 29, 2025
18cd9f5
Removed `UNetSlidingTrainer` and replaced its usage with `UNetTrainer…
ATATC Dec 29, 2025
7b278e7
Removed `SlidingPredictor` and associated sliding window functionalit…
ATATC Dec 29, 2025
ac0c280
Merge branch '192' into 133
ATATC Dec 29, 2025
f11970f
Adjusted validation dataset path to account for sliding window prepro…
ATATC Dec 29, 2025
a416029
Refactored shape handling in sliding window function to improve dimen…
ATATC Dec 29, 2025
97393e6
Merge branch '192' into 133
ATATC Dec 29, 2025
10b0d6c
Refactored `do_sliding_window` to streamline padding logic with `Pad2…
ATATC Dec 29, 2025
f5e080c
Refactored `do_sliding_window` to streamline padding logic with `Pad2…
ATATC Dec 29, 2025
f16338b
Updated `do_sliding_window` to compute `shape` from `window_shape` an…
ATATC Dec 29, 2025
32ce2aa
Merge branch '192' into 133
ATATC Dec 29, 2025
b19e0a8
Adjusted `do_sliding_window` to use `stride` instead of `shape`, refi…
ATATC Dec 29, 2025
d0a4b46
Merge branch '192' into 133
ATATC Dec 29, 2025
3cb334e
Replaced division-based index calculation with `log10` for consistent…
ATATC Dec 29, 2025
580507f
Merge branch '192' into 133
ATATC Dec 29, 2025
ac96c53
Removed `device` argument from `torch.load` in `load` method for comp…
ATATC Dec 29, 2025
6e1c781
Merge branch '192' into 133
ATATC Dec 29, 2025
9273419
Integrated progress tracking with `rich` in sliding window operations…
ATATC Dec 29, 2025
4bf9a0d
Added `fast_save` and `fast_load` utilities, integrated tensor preloa…
ATATC Dec 29, 2025
ea2c428
Increased batch size and updated sliding window shape for validation …
ATATC Dec 29, 2025
1f8b805
Merge remote-tracking branch 'origin/192' into 133
ATATC Dec 29, 2025
d2830fe
Added the SlidingTrainer class to support sliding window training and…
perctrix Dec 29, 2025
ca6812d
Padded label to match reconstructed shape in SlidingTrainer validatio…
perctrix Dec 29, 2025
c500052
Refactored `validate_case` method in segmentation preset, replacing i…
ATATC Dec 30, 2025
6d3b971
Refactored `validate_case` method in segmentation preset, replacing i…
ATATC Dec 30, 2025
fef17c3
Added `PadTo` class for flexible padding to minimum shape in 2D/3D te…
ATATC Dec 30, 2025
95cf936
Updated dataset pipeline in `benchmark.py` to integrate `PadTo` trans…
ATATC Dec 30, 2025
93bdea9
Refactored dataset pipeline in `benchmark.py` to use `MONAITransform`…
ATATC Dec 30, 2025
d3933d7
Updated `PadTo` transform in `benchmark.py` to disable batching. (#133)
ATATC Dec 30, 2025
089abdd
Reduced validation loader batch size to 1 in `benchmark.py` to align …
ATATC Dec 30, 2025
d25a2fd
Integrated `slide_dataset` and `SupervisedSWDataset` into validation …
ATATC Dec 30, 2025
f02761f
Implemented SlidingTrainer validate and validate_case with full_label…
perctrix Dec 31, 2025
4da2aea
Cleaned up unused `supervised` block in sliding window logic and repl…
ATATC Dec 31, 2025
2462d76
Added `set_validation_datasets` method in `SlidingTrainer` to manage …
ATATC Dec 31, 2025
d1bdf2d
Refactored SlidingTrainer to use dataset methods instead of hardcoded…
perctrix Jan 2, 2026
4dce8a8
Refactored `SupervisedSWDataset` to inherit from `SupervisedDataset`,…
ATATC Jan 3, 2026
5e712cb
Replaced direct access to `_images` with `images()` method in segment…
ATATC Jan 3, 2026
8e05421
Merge branch '192' into 133
ATATC Jan 3, 2026
764b2a0
Switched `UNetTrainer` base class from `SegmentationTrainer` to `Slid…
ATATC Jan 3, 2026
bfa62c7
Encapsulated validation dataset access in `SlidingTrainer` using gett…
ATATC Jan 3, 2026
087662c
Merge branch '192' into 133
ATATC Jan 3, 2026
3633622
Updated validation dataset handling in `benchmark.py` to rename `val`…
ATATC Jan 3, 2026
ab6c968
Refactored worst-case tracking in segmentation validation to use `val…
ATATC Jan 5, 2026
e8b805c
Updated `fast_load` and `fast_save` to use `safetensors` for serializ…
ATATC Jan 5, 2026
e31d66d
Merge branch '192' into 133
ATATC Jan 5, 2026
a039de9
Merge branch 'main' into 133
ATATC Jan 5, 2026
2f31ae9
Refactored `benchmark.py` into a module structure, introduced `UnitTe…
ATATC Jan 6, 2026
0fd013e
Added titles to `visualize3d` calls in `data.py` for improved context…
ATATC Jan 6, 2026
050224c
Fixed stride inconsistency between `do_sliding_window` and `revert_sl…
perctrix Jan 6, 2026
63fa43f
Added layout exposure. (#197)
ATATC Jan 6, 2026
0592a21
Standardized variable naming in `fold` method.
ATATC Jan 6, 2026
2b8534f
Disabled gradient computation in preprocessing modules. (#197)
ATATC Jan 6, 2026
b541640
Added sliding window dataset grouping and full case reconstruction. (…
ATATC Jan 6, 2026
46723ab
Refactored `load_full` method to `case`, updating its return type and…
ATATC Jan 6, 2026
6d4de7d
Refactored training and validation progress handling and updated `val…
ATATC Jan 6, 2026
3ea22a2
Merge remote-tracking branch 'origin/197' into 133
ATATC Jan 6, 2026
9687cea
Refactored tensor shape initialization and indexing in sliding window…
ATATC Jan 6, 2026
c1fafda
Integrated padding restoration into sliding window operations and upd…
ATATC Jan 6, 2026
dced18a
Updated `do_sliding_window` and `revert_sliding_window` usage in `dat…
ATATC Jan 6, 2026
d8d4a7a
Merge branch '197' into 133
ATATC Jan 6, 2026
4d3fe81
Refactored training framework by introducing `UNetSlidingTrainer`, sp…
ATATC Jan 6, 2026
9349ae8
Expanded benchmarking utility to support `Training` and `SlidingTrain…
ATATC Jan 6, 2026
bfa0f60
Fixed incorrect variable assignment in `__main__.py` for benchmark te…
ATATC Jan 6, 2026
791faea
Conditional label directory creation in `_slide` and added paddings d…
ATATC Jan 6, 2026
45e0843
Removed redundant `layout` suffix from sliding window file paths in `…
ATATC Jan 6, 2026
af3d146
Adjusted padding initialization in `sliding_window` to use `window_sh…
ATATC Jan 6, 2026
1bfaa1a
Fixed file name parsing logic in `sliding_window` to exclude extensio…
ATATC Jan 6, 2026
f2de71d
Replaced `itertools.product` with `functools.reduce` and `operator.mu…
ATATC Jan 6, 2026
669b4dd
Validated and fixed group initialization logic in `sliding_window` to…
ATATC Jan 6, 2026
561a5d9
Refactored `device` setter in `layer.py` and added `transform` setter…
ATATC Jan 6, 2026
e555838
Added `MONAITransform` with `PadTo` in training pipeline to enhance d…
ATATC Jan 6, 2026
a5953ad
Added `transform` setter in `dataset.py` to enable configurable trans…
ATATC Jan 6, 2026
2899996
Updated `PadTo` in `MONAITransform` to disable batch padding in train…
ATATC Jan 6, 2026
0735a6c
Updated `PadTo` in `MONAITransform` to disable batch padding in train…
ATATC Jan 6, 2026
c84f84f
Updated `TrainingTest` and `SlidingTrainingTest` to use `Segmentation…
ATATC Jan 6, 2026
7334c20
Refactored `device` handling in `InspectionAnnotations` and `ROIDatas…
ATATC Jan 6, 2026
c9aa2f2
Removed unnecessary file extension from `torch.load` path in `sliding…
ATATC Jan 6, 2026
55f452d
Added `set_frontend` calls to `SegmentationTrainer` initialization in…
ATATC Jan 6, 2026
086da70
Updated `torch.load` call in `sliding_window` to include `weights_onl…
ATATC Jan 6, 2026
3cacfee
Refactored `device` handling in sliding window pipeline to ensure com…
ATATC Jan 6, 2026
53bd6ca
Updated `TrainingTest` note to specify sliding window usage in traini…
ATATC Jan 6, 2026
db773dc
Refactored label padding logic in segmentation pipeline to streamline…
ATATC Jan 6, 2026
c5e22b9
Updated progress update message in validation loop to include case in…
ATATC Jan 6, 2026
b248150
Refactored sliding window assembly logic to replace loop-based tensor…
ATATC Jan 6, 2026
943c9e2
Refactored `device` handling in `InspectionAnnotations` and `ROIDatas…
ATATC Jan 6, 2026
d4dad6f
Added validation dataset management to `SlidingTrainer` and integrate…
ATATC Jan 6, 2026
edf3475
Updated validation dataset path in `SimpleDataset` initialization to …
ATATC Jan 6, 2026
619930b
Added `RandomROIDatasetTest` to `benchmark` and integrated it into th…
ATATC Jan 6, 2026
ff81dfe
Refactored 3D visualization calls in `benchmark/data.py` to improve c…
ATATC Jan 6, 2026
408508e
Added overlap parameter to sliding validation dataset setup in `Slidi…
ATATC Jan 7, 2026
16fe090
Added overlap parameter to sliding validation dataset setup in `Slidi…
ATATC Jan 7, 2026
0a0c159
Refactored sliding window logic to replace padding structures with sh…
ATATC Jan 7, 2026
9eb2c18
Updated `validate` method in `segmentation.py` to use `_validation_da…
ATATC Jan 7, 2026
2b8ab7e
Removed redundant `rmdir` calls in dataset preloading setup.
ATATC Jan 7, 2026
ec4ab6f
Fixed incorrect `makedirs` call for `labels_path` during dataset prel…
ATATC Jan 7, 2026
232ef6f
Preloaded dataset during setup in `benchmark/data.py` to optimize dat…
ATATC Jan 7, 2026
5e4cb7d
Improved exception handling in `prototype.py` by adding nested cleanu…
ATATC Jan 8, 2026
cf99ded
Added `clean_up` method to training tests to remove experiment folder…
ATATC Jan 8, 2026
0462e40
Removed unused imports and redundant validation dataset setup; added …
ATATC Jan 8, 2026
f0d75a4
Refactored sliding window logic and dataset handling in `segmentation…
ATATC Jan 8, 2026
ec28a09
Refactored sliding window dataset API by splitting `case` into `case_…
ATATC Jan 8, 2026
7cd8ffb
Ensured tensor is contiguous before saving in `fast_save` to prevent …
ATATC Jan 8, 2026
bd7973a
Refactored dataset and ROI handling by introducing `load_image` and `…
ATATC Jan 8, 2026
e1b66ce
Refactored `BinarizedDataset` to streamline initialization and added …
ATATC Jan 8, 2026
c1b5d6e
Refactored ROI cropping methods to unify image and label handling via…
ATATC Jan 8, 2026
17d0b84
Refactored validation dataset handling in `SlidingTrainer` by introdu…
ATATC Jan 8, 2026
bdc73c3
Updated MPS device availability check to use `torch.mps.is_available(…
ATATC Jan 8, 2026
64c5995
Added `empty_cache` function to clear memory for CPU, CUDA, and MPS d…
ATATC Jan 8, 2026
0d7a42d
Integrated `empty_cache` function into training and validation workfl…
ATATC Jan 8, 2026
3607f13
Ensured tensor detach calls in `sanity_check` and `foreground_heatmap…
ATATC Jan 8, 2026
949d3c3
Removed redundant `empty_cache` calls in segmentation workflows; ensu…
ATATC Jan 8, 2026
a4d7e36
Moved `empty_cache` call in validation loop to improve memory managem…
ATATC Jan 8, 2026
4d85543
Refactored checkpoint handling by introducing `WithCheckpoint` class;…
ATATC Jan 8, 2026
0083f3d
Relocated `empty_cache` call within validation loop to optimize memor…
ATATC Jan 8, 2026
e861421
Ensured tensor `detach` calls in segmentation workflows to prevent un…
ATATC Jan 8, 2026
fd5bd22
Added epoch information to progress descriptions in validation loop f…
ATATC Jan 8, 2026
69c16f8
Refactored segmentation validation loop to streamline batch processin…
ATATC Jan 8, 2026
f437e52
Wrapped `model_complexity_info` and model call in `torch.no_grad` wit…
ATATC Jan 8, 2026
add72b2
Removed redundant `detach` call in `sanity_check` output processing t…
ATATC Jan 8, 2026
db1e0b6
Removed redundant `detach` calls across segmentation workflows and in…
ATATC Jan 8, 2026
9f84c88
Replaced `ROIDataset` with `RandomROIDataset` in training workflow to…
ATATC Jan 9, 2026
1404d80
Integrate a profiler in `Trainer` (#202)
ATATC Jan 9, 2026
43c5bb7
Refactored `sliding_window` reconstruction logic to simplify tensor r…
ATATC Jan 9, 2026
9ee78ca
Fixed incorrect tensor dimension indexing in `Preprocess` forward met…
ATATC Jan 9, 2026
7776197
Added logging to `record_profiler_linebreak` and removed redundant pr…
ATATC Jan 9, 2026
a712b29
Added support for loading and caching inspection annotations in slidi…
ATATC Jan 9, 2026
d0cfef0
Refactored segmentation case validation to simplify profiling and log…
ATATC Jan 10, 2026
ee98172
Optimized segmentation workflow by removing redundant `.to(self._devi…
ATATC Jan 10, 2026
72e8745
Added support for compiling loss function with `torch.compile` in tra…
ATATC Jan 10, 2026
7a13eb1
Refactored segmentation workflow: streamlined validation dataset hand…
ATATC Jan 10, 2026
f0340fe
Removed redundant creation of `validation` folder in segmentation wor…
ATATC Jan 10, 2026
35bfafe
Enabled non-blocking data transfers to `device` in training and valid…
ATATC Jan 10, 2026
943f40a
Enabled non-blocking data transfers to `device` in dataset getters fo…
ATATC Jan 10, 2026
6c2b99a
Improved memory efficiency in segmentation workflow by removing metri…
ATATC Jan 11, 2026
2731461
Added `ResizeTrainingTest` and updated benchmark entry point to inclu…
ATATC Jan 11, 2026
7db8118
Refined Dice coefficient computation to improve handling of backgroun…
ATATC Jan 11, 2026
edc5d33
Simplified validation loop by using `enumerate` to eliminate redundan…
ATATC Jan 11, 2026
3932f99
Refactored sliding validation workflow: added full-resolution validat…
ATATC Jan 11, 2026
20c3238
Removed `save_preview` method from segmentation preset as it was unus…
ATATC Jan 11, 2026
6900c10
Adjusted `soft_dice_coefficient` smooth parameter default from `1e-5`…
ATATC Jan 12, 2026
85027e3
Updated default `lambda_bce` and `smooth` values in `DiceBCELossWithL…
ATATC Jan 12, 2026
8fc6d6e
Removed unused `_TemplateDataset` class and added `Predictor` import …
ATATC Jan 12, 2026
51ac27b
Refactored training workflow: removed redundant `_epoch_metrics`, con…
ATATC Jan 12, 2026
b690feb
Updated `record_all` method to prefix validation metrics with `val` f…
ATATC Jan 12, 2026
82aae67
Updated nnUNet style transform
perctrix Jan 13, 2026
03a3f73
Removed `transforms.py`, including nnUNet-style data augmentation fun…
ATATC Jan 14, 2026
5a70cff
Refactored transform handling by adding `_move_transform_to_device` h…
ATATC Jan 14, 2026
740de7e
Refactored transform attributes by removing unnecessary underscores f…
ATATC Jan 14, 2026
783bfac
Refactored transform handling by replacing `_move_transform_to_device…
ATATC Jan 14, 2026
efea3f0
Updated `ROIDataset` to use `transform` attribute from `annotations.d…
ATATC Jan 14, 2026
f63c1fc
Added `PolyLRScheduler` for polynomial learning rate decay and update…
ATATC Jan 14, 2026
07262d2
Updated segmentation preset to use `PolyLRScheduler` and `SGD` optimi…
ATATC Jan 15, 2026
3b617f7
Refactored checkpoint saving/loading by consolidating optimizer, sche…
ATATC Jan 15, 2026
4530479
Enabled `pin_memory` for DataLoaders in training workflow to improve …
ATATC Jan 15, 2026
9b9443b
Added support for continued training with `_continue` flag to streaml…
ATATC Jan 15, 2026
d61fe8d
Improved state saving by serializing `tracker` with `asdict` for bett…
ATATC Jan 15, 2026
7999bbc
Removed redundant `device` argument from `load_file` in `load_checkpo…
ATATC Jan 15, 2026
0ac6b7f
Refactored checkpoint loading to remove "_orig_mod." prefix when comp…
ATATC Jan 15, 2026
19df01a
Implemented class-balanced foreground sampling in RandomROIDataset to…
perctrix Jan 15, 2026
f1b84e3
Enhanced `visualize3d` function by adding support for custom colormap…
ATATC Jan 15, 2026
4cd691a
Ensured `convert_logits_to_ids` output is cast to `int` in segmentati…
ATATC Jan 15, 2026
2134c98
Cast `label` to `int` before saving preview in segmentation preset fo…
ATATC Jan 15, 2026
5b9a581
Added support for dataset preloading to improve data loading performa…
ATATC Jan 15, 2026
8c772ca
Refactored dataset preloading paths to improve directory structure an…
ATATC Jan 15, 2026
43baf2e
Improved error message in `visualization.py` to include `image.dtype`…
ATATC Jan 15, 2026
8fe68c9
Enhanced `visualize3d` to support label-specific colormaps and added …
ATATC Jan 15, 2026
e6b7c5e
Added `is_label` flag to `_save_preview` and `visualize2d` for better…
ATATC Jan 15, 2026
97d4185
Updated `visualize3d` calls to use `is_label` flag for consistent han…
ATATC Jan 15, 2026
2386ac1
Simplified colormap assignment logic in `visualization.py` by merging…
ATATC Jan 15, 2026
68c1494
Refactored backend assignment logic in `visualization.py` to simplify…
ATATC Jan 15, 2026
3fe19ce
Expanded `__LABEL_COLORMAP` in `visualization.py` with additional col…
ATATC Jan 15, 2026
20d9d13
Refactored dataset preloading logic to streamline `load` and `__getit…
ATATC Jan 15, 2026
d5d5ce8
Reordered `__LABEL_COLORMAP` in `visualization.py` to improve logical…
ATATC Jan 15, 2026
9178215
Added index bounds check in `__getitem__` methods to prevent out-of-r…
ATATC Jan 16, 2026
7a8f083
Removed redundant profiling and cache-clearing calls in validation lo…
ATATC Jan 16, 2026
82f7770
Added dataset preloading step in `training.py` to optimize ROI datase…
ATATC Jan 16, 2026
e800ead
Aligned RandomROIDataset with nnUNet foreground sampling strategy.
perctrix Jan 19, 2026
64e4a21
Added `do_transform` parameter to `preload` method for optional data …
ATATC Jan 20, 2026
049786e
Replaced `ROIDataset` with `RandomROIDataset` in `training.py` for ra…
ATATC Jan 20, 2026
4c1128e
Fixed the dtype handling in the load_image function to ensure that lo…
perctrix Jan 20, 2026
163f141
Revert "Fixed the dtype handling in the load_image function to ensure…
ATATC Jan 20, 2026
48d89d7
Test 1.
ATATC Jan 20, 2026
dc5b978
Added progress-based visualization previews for `RandomROIDataset` wi…
ATATC Jan 22, 2026
d3d6579
Fixed integer type casting for `label` and `label_roi` in dataset vis…
ATATC Jan 22, 2026
32df347
Renamed `labelROIs` to `imageROIs` in dataset visualization for clari…
ATATC Jan 24, 2026
478510f
Added `clamp` parameter to `roi_shape` method to allow optional uncla…
ATATC Jan 24, 2026
ccd0503
Updated `roi` and `crop_roi` methods to integrate `clamp` parameter, …
ATATC Jan 25, 2026
ef76194
Standardized string quotes in `sliding_window.py` for consistency.
ATATC Jan 25, 2026
dea2b1d
Extended `InspectionAnnotation` to include `class_bboxes`, optimized …
ATATC Jan 25, 2026
37887ea
Refactored `random_roi` method in `inspection.py` to improve readabil…
ATATC Jan 25, 2026
aa0d77a
Added `min_factor` parameter to `RandomROIDataset` for configurable R…
ATATC Jan 25, 2026
1991558
Enhanced `InspectionAnnotation` with `class_locations` for storing vo…
ATATC Jan 25, 2026
96c6c6f
Simplified `random_roi` logic by replacing `np.random.choice` with `c…
ATATC Jan 25, 2026
e35a91f
Refined `random_roi` padding logic to handle smaller annotations, ens…
ATATC Jan 25, 2026
4fc4c36
Simplified `oversample_foreground` logic by refining condition to use…
ATATC Jan 25, 2026
1ebef3b
Integrated `training_transforms` and `validation_transforms` into dat…
ATATC Jan 25, 2026
edc22a7
Refactored inspection annotation parsing by introducing `_str_indices…
ATATC Jan 25, 2026
23d10c6
Enhanced `BasicUNet` with customizable feature map sizes; integrated …
ATATC Jan 25, 2026
3cfe41d
Refactored `construct_new` method in `inspection.py` to initialize `i…
ATATC Jan 26, 2026
3e4d50e
Added `batch` parameter to `soft_dice_coefficient` in `metrics.py` fo…
ATATC Jan 27, 2026
f183da0
Fixed redundant summation of `label` in `soft_dice_coefficient` withi…
ATATC Jan 27, 2026
7fae32b
Reapply "Fixed the dtype handling in the load_image function to ensur…
ATATC Jan 27, 2026
14b5f09
Added `DiceCELossWithLogits` class to `loss.py` for combined Cross En…
ATATC Jan 27, 2026
76934d3
Updated `UNetTrainer` to use `DiceCELossWithLogits` and adjusted `Bas…
ATATC Jan 27, 2026
cc62d60
Refined `DiceCELoss` and `DiceBCELoss` implementations: adjusted sigm…
ATATC Jan 27, 2026
49a1f43
Optimized index padding in `dataset.py` by caching precomputed digit …
ATATC Jan 27, 2026
59ef853
Switched from `BasicUNet` to `DynUNet` in `UNetTrainer` for enhanced …
ATATC Jan 27, 2026
1abc2c5
Refactored training workflow: removed redundant `_epoch_metrics`, con…
ATATC Jan 27, 2026
8bfbf5f
Adjusted `DiceCELoss` class to respect `include_background` setting i…
ATATC Jan 27, 2026
84fb036
Updated `DiceCELoss` to support validation mode with no-grad logic; r…
ATATC Jan 27, 2026
0637634
Refactored loss functions: consolidated `DiceCELoss` and `DiceBCELoss…
ATATC Jan 28, 2026
84cb078
Simplified `dice_similarity_coefficient_binary` call by removing unus…
ATATC Jan 28, 2026
79d7baa
Refactored `convert_logits_to_ids` for clarity, simplified `RandomROI…
ATATC Jan 28, 2026
a7b5948
Preloaded validation dataset during `set_up` for improved efficiency;…
ATATC Jan 28, 2026
3d2fe7e
Enhanced metric computation in `DiceCELoss` and `DiceBCELoss`: added …
ATATC Jan 29, 2026
cc72548
Refactored checkpoint handling: replaced `load_file`/`save_file` with…
ATATC Jan 29, 2026
65d34d8
Added `global_previous_index` parameter to `show_metrics` for improve…
ATATC Jan 29, 2026
74d296c
Updated segmentation criterion logic: switched to `DiceCELossWithLogi…
ATATC Jan 29, 2026
2f27192
Refined segmentation criterion: adjusted threshold to `num_classes < …
ATATC Jan 29, 2026
ff394b5
Improved `show_metrics` logic: added validation to enforce negative `…
ATATC Jan 29, 2026
24623df
Fixed `show_metrics` logic: resolved incorrect condition for `global_…
ATATC Jan 29, 2026
e1c2870
Clipped gradients in segmentation preset to prevent exploding gradien…
ATATC Jan 30, 2026
8a16a1f
Added debug image saving at epoch 80 in benchmark UNetTrainer to diag…
perctrix Jan 31, 2026
bf2902e
Revert "Added debug image saving at epoch 80 in benchmark UNetTrainer…
ATATC Feb 1, 2026
4dbcd63
Added `is_label` parameter to `SimpleDataset` to support label-specif…
ATATC Feb 2, 2026
071ccac
Merge remote-tracking branch 'origin/133' into 133
ATATC Feb 2, 2026
bfc7584
Added deep supervision support in segmentation training, including ne…
ATATC Feb 2, 2026
7daa284
Refined loss initialization in segmentation preset to ensure device a…
ATATC Feb 3, 2026
e6f9238
Added `arbitrary_num_cases` argument to `RandomROIDataset` for custom…
ATATC Feb 4, 2026
c75711a
Simplified mask extraction in deep supervision by replacing loop with…
ATATC Feb 4, 2026
f32a778
Added `__getattr__` override in segmentation preset for accessing `lo…
ATATC Feb 4, 2026
b3cb3d4
Refined bbox creation logic by updating dimensional condition in `bbo…
ATATC Feb 4, 2026
a00f4a8
Propagated `_roi_shape` attribute in `copy` to ensure ROI consistency…
ATATC Feb 4, 2026
ff8b8c3
Removed `_foreground_heatmap` caching logic to simplify `foreground_h…
ATATC Feb 4, 2026
c2fd79b
Removed redundant `model.compile()` call from `save_model` to streaml…
ATATC Feb 4, 2026
08fdef9
Cleared unused variables and added `empty_cache()` call to optimize m…
ATATC Feb 4, 2026
1f383fb
Added `class_counts` to `InspectionAnnotation` for tracking class-wis…
ATATC Feb 4, 2026
86de09c
Refined `bbox_from_indices` to use `num_dim` for dimensional checks, …
ATATC Feb 4, 2026
776e4bb
Simplified annotation creation and ROI class sampling by removing red…
ATATC Feb 4, 2026
126d704
Replaced `.sum().item()` with `len()` for class count computation in …
ATATC Feb 7, 2026
4d4da97
Enabled deep supervision in `UNetTrainer` with configurable scales fo…
ATATC Feb 12, 2026
a269fd4
Enabled deep supervision in `DynUNet` and updated dataloader configur…
ATATC Feb 12, 2026
a0d89df
Added background handling in class sampling and adjusted coordinate s…
ATATC Feb 13, 2026
0df922a
Reordered cross-entropy computation to include background handling lo…
ATATC Feb 13, 2026
dbccb49
Reordered softmax application in `_forward` to align with background …
ATATC Feb 13, 2026
6f5b9c2
Adjusted ROI sampling logic in `RandomROIDataset`, refined parameter …
ATATC Feb 13, 2026
abe2ada
Extended `Normalize` module with "zscore" method and added `CTNormali…
ATATC Feb 14, 2026
f22baa6
Use this for debug.
ATATC Feb 14, 2026
965c06a
Refined output activation logic in `save_preview` and prediction hand…
ATATC Feb 15, 2026
c065bf7
Abstracted class ID statistics logging into `print_stats_of_class_ids…
ATATC Feb 15, 2026
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
37 changes: 37 additions & 0 deletions benchmark/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from argparse import ArgumentParser
from os.path import exists

from benchmark.data import DataTest, SlidingWindowTest, RandomROIDatasetTest
from benchmark.training import TrainingTest, ResizeTrainingTest, SlidingTrainingTest
from mipcandy import auto_device, download_dataset, Frontend, NotionFrontend, WandBFrontend

BENCHMARK_DATASET: str = "AbdomenCT-1K-ss1"

if __name__ == "__main__":
tests = {
"SlidingWindow": SlidingWindowTest,
"RandomROI": RandomROIDatasetTest,
"Training": TrainingTest,
"ResizeTraining": ResizeTrainingTest,
"SlidingTraining": SlidingTrainingTest
}
parser = ArgumentParser(prog="MIP Candy Benchmark", description="MIP Candy Benchmark",
epilog="GitHub: https://github.com/ProjectNeura/MIPCandy")
parser.add_argument("test", choices=tests.keys())
parser.add_argument("-i", "--input-folder")
parser.add_argument("-o", "--output-folder")
parser.add_argument("--num-epochs", type=int, default=100)
parser.add_argument("--device", default=None)
parser.add_argument("--front-end", choices=(None, "n", "w"), default=None)
args = parser.parse_args()
DataTest.dataset = BENCHMARK_DATASET
test = tests[args.test](
args.input_folder, args.output_folder, args.num_epochs, args.device if args.device else auto_device(), {
None: Frontend, "n": NotionFrontend, "w": WandBFrontend
}[args.front_end]
)
if not exists(f"{args.input_folder}/{BENCHMARK_DATASET}"):
download_dataset(f"nnunet_datasets/{BENCHMARK_DATASET}", f"{args.input_folder}/{BENCHMARK_DATASET}")
stat, err = test.run()
if not stat:
raise err
69 changes: 69 additions & 0 deletions benchmark/data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from os import makedirs
from time import time
from typing import override, Literal

from rich.progress import Progress

from benchmark.prototype import UnitTest
from mipcandy import NNUNetDataset, do_sliding_window, visualize3d, revert_sliding_window, JointTransform, inspect, \
RandomROIDataset


class DataTest(UnitTest):
dataset: str = "AbdomenCT-1K-ss1"
transform: JointTransform | None = None

@override
def set_up(self) -> None:
self["dataset"] = NNUNetDataset(f"{self.input_folder}/{DataTest.dataset}", transform=self.transform,
device=self.device)
self["dataset"].preload(f"{self.input_folder}/{DataTest.dataset}/preloaded")


class FoldedDataTest(DataTest):
fold: Literal[0, 1, 2, 3, 4, "all"] = 0

@override
def set_up(self) -> None:
super().set_up()
self["train_dataset"], self["val_dataset"] = self["dataset"].fold(fold=self.fold)


class SlidingWindowTest(DataTest):
@override
def execute(self) -> None:
image, _ = self["dataset"][0]
print(image.shape)
visualize3d(image, title="raw")
t0 = time()
windows, layout, pad = do_sliding_window(image, (128, 128, 128))
print(f"took {time() - t0:.2f}s")
print(windows[0].shape, layout)
t0 = time()
recon = revert_sliding_window(windows, layout, pad)
print(f"took {time() - t0:.2f}s")
print(recon.shape)
visualize3d(recon, title="reconstructed")


class RandomROIDatasetTest(DataTest):
@override
def execute(self) -> None:
annotations = inspect(self["dataset"])
dataset = RandomROIDataset(annotations, 2)
print(dataset.roi_shape())
o = f"{self.output_folder}/RandomROIPreviews"
makedirs(o, exist_ok=True)
makedirs(f"{o}/images", exist_ok=True)
makedirs(f"{o}/labels", exist_ok=True)
makedirs(f"{o}/imageROIs", exist_ok=True)
makedirs(f"{o}/labelROIs", exist_ok=True)
with Progress() as progress:
task = progress.add_task("Generating Previews...", total=len(dataset))
for idx, (image_roi, label_roi) in enumerate(dataset):
image, label = self["dataset"][idx]
visualize3d(image, title="image raw", screenshot_as=f"{o}/images/{idx}.png")
visualize3d(label.int(), title="label raw", is_label=True, screenshot_as=f"{o}/labels/{idx}.png")
visualize3d(image_roi, title="image roi", screenshot_as=f"{o}/imageROIs/{idx}.png")
visualize3d(label_roi.int(), title="label roi", is_label=True, screenshot_as=f"{o}/labelROIs/{idx}.png")
progress.update(task, advance=1)
41 changes: 41 additions & 0 deletions benchmark/prototype.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from os import PathLike
from typing import Any

from mipcandy import Device, Frontend


class UnitTest(object):
def __init__(self, input_folder: str | PathLike[str], output_folder: str | PathLike[str], num_epochs: int,
device: Device, frontend: type[Frontend]) -> None:
self.input_folder: str = input_folder
self.output_folder: str = output_folder
self.num_epochs: int = num_epochs
self.device: Device = device
self.frontend: type[Frontend] = frontend

def set_up(self) -> None:
pass

def execute(self) -> None:
pass

def clean_up(self) -> None:
pass

def run(self) -> tuple[bool, Exception | None]:
try:
self.set_up()
self.execute()
except Exception as e:
try:
self.clean_up()
except Exception as e2:
print(f"Failed to clean up after exception: {e2}")
return False, e
return True, None

def __setitem__(self, key: str, value: Any) -> None:
setattr(self, "_x_" + key, value)

def __getitem__(self, item: str) -> Any:
return getattr(self, "_x_" + item)
118 changes: 118 additions & 0 deletions benchmark/training.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
from os import removedirs
from os.path import exists
from typing import override

from monai.transforms import Resized
from torch.utils.data import DataLoader

from benchmark.data import DataTest, FoldedDataTest
from benchmark.unet import UNetTrainer, UNetSlidingTrainer
from mipcandy import SegmentationTrainer, slide_dataset, Shape, SupervisedSWDataset, JointTransform, inspect, \
load_inspection_annotations, RandomROIDataset


class TrainingTest(DataTest):
trainer: type[SegmentationTrainer] = UNetTrainer
resize: Shape = (128, 128, 128)
num_classes: int = 5
_continue: str | None = None # internal flag for continued training

def set_up_datasets(self) -> None:
super().set_up()
path = f"{self.output_folder}/training_test.json"
self["dataset"].device(device="cpu")
if exists(path):
annotations = load_inspection_annotations(path, self["dataset"])
else:
annotations = inspect(self["dataset"])
annotations.save(path)
dataset = RandomROIDataset(annotations, 2, num_patches_per_case=2)
dataset.roi_shape(roi_shape=(128, 128, 128))
self["train_dataset"], self["val_dataset"] = dataset.fold(fold=0)

@override
def set_up(self) -> None:
self.set_up_datasets()
train, val = self["train_dataset"], self["val_dataset"]
val.preload(f"{self.output_folder}/valPreloaded")
# train.set_transform(JointTransform(image_only=Normalize(domain=(0, 1), strict=True)))
# val.set_transform(JointTransform(image_only=Normalize(domain=(0, 1), strict=True)))
train_dataloader = DataLoader(train, batch_size=2, shuffle=True, pin_memory=True, prefetch_factor=2,
num_workers=2, persistent_workers=True)
val_dataloader = DataLoader(val, batch_size=1, shuffle=False, pin_memory=True)
trainer = self.trainer(self.output_folder, train_dataloader, val_dataloader, device=self.device)
trainer.num_classes = self.num_classes
trainer.set_frontend(self.frontend)
self["trainer"] = trainer

@override
def execute(self) -> None:
if not self._continue:
return self["trainer"].train(self.num_epochs, note=f"Training test {self.resize}", compile_model=False,
val_score_prediction=False)
self["trainer"].recover_from(self._continue)
return self["trainer"].continue_training(self.num_epochs)

@override
def clean_up(self) -> None:
removedirs(self["trainer"].experiment_folder())


class ResizeTrainingTest(FoldedDataTest):
trainer: type[SegmentationTrainer] = UNetTrainer
resize: Shape = (256, 256, 256)
num_classes: int = 5

@override
def set_up(self) -> None:
self.transform = JointTransform(transform=Resized(("image", "label"), self.resize))
super().set_up()
train_dataloader = DataLoader(self["train_dataset"], batch_size=2, shuffle=True)
val_dataloader = DataLoader(self["val_dataset"], batch_size=1, shuffle=False)
trainer = self.trainer(self.output_folder, train_dataloader, val_dataloader, recoverable=False,
profiler=True, device=self.device)
trainer.num_classes = self.num_classes
trainer.set_frontend(self.frontend)
self["trainer"] = trainer

@override
def execute(self) -> None:
self["trainer"].train(self.num_epochs, note=f"Resize Training test {self.resize}")

@override
def clean_up(self) -> None:
removedirs(self["trainer"].experiment_folder())


class SlidingTrainingTest(TrainingTest, FoldedDataTest):
trainer: type[SegmentationTrainer] = UNetSlidingTrainer
window_shape: Shape = (128, 128, 128)
overlap: float = .5

@override
def set_up(self) -> None:
self.set_up_datasets()
train, val = self["train_dataset"], self["val_dataset"]
FoldedDataTest.set_up(self)
full_val = self["val_dataset"]
path = f"{self.output_folder}/val_slided"
if not exists(path):
slide_dataset(full_val, path, self.window_shape, overlap=self.overlap)
slided_val = SupervisedSWDataset(path)
train_dataloader = DataLoader(train, batch_size=2, shuffle=True)
val_dataloader = DataLoader(val, batch_size=1, shuffle=False)
trainer = self.trainer(self.output_folder, train_dataloader, val_dataloader, recoverable=False,
profiler=True, device=self.device)
trainer.set_datasets(full_val, slided_val)
trainer.num_classes = self.num_classes
trainer.overlap = self.overlap
trainer.set_frontend(self.frontend)
self["trainer"] = trainer

@override
def execute(self) -> None:
self["trainer"].train(self.num_epochs, note="Training test with sliding window")

@override
def clean_up(self) -> None:
removedirs(self["trainer"].experiment_folder())
Loading