Lucchi++ (Semantic Segmentation) ================================== .. include:: _intro.rst This tutorial reproduces binary mitochondria segmentation on the Lucchi++ EM benchmark using ``tutorials/mito_lucchi++.yaml``. The task is treated as **semantic segmentation** — predict the mitochondria foreground mask with an encoder-decoder network. Evaluation is the Jaccard / IoU score. The dataset was released by Lucchi et al. and is isotropic at 5 nm across all three axes, so the recipe uses a fully-3D MedNeXt with isotropic 112³ patches. Goal ---- The pipeline pins the following setup: - **Input** ``[112, 112, 112]`` patches, isotropic 5 × 5 × 5 nm. - **Model** MedNeXt-S, kernel size 3, 3D, no deep supervision. - **Pipeline** ``pipeline_profile: binary`` (single foreground channel). - **Dataloader** cached profile, batch size 8, ``aug_strong`` augmentation profile. - **Optimization** ``warmup_cosine_lr`` profile, AdamW @ ``lr=1e-3``, ``weight_decay=0.01``, 150 epochs × 1000 steps, ``precision=16-mixed``, gradient clip 1.0. - **Inference** sliding window 112³ with 50 % overlap, bump blending, ``sw_batch_size=8``, TTA enabled with all-axis flips. - **Metric** ``jaccard``. Each of these is encoded directly in ``tutorials/mito_lucchi++.yaml``; do not change them in passing. 1 - Get the data ^^^^^^^^^^^^^^^^ Lucchi++ is the relabeled version of the original Lucchi 2012 dataset released by Casser et al.; download from the EPFL CVLab page or your local mirror. After unpacking you should have HDF5 volumes: .. code-block:: text datasets/lucchi++/ train_im.h5 train_mito.h5 test_im.h5 test_mito.h5 The config reads from ``datasets/lucchi++/`` relative to the repo root. Edit the ``train.data.train`` and ``test.data.test`` blocks in ``tutorials/mito_lucchi++.yaml`` if you stage data elsewhere. For the upstream description see the `EPFL CVLab page `_. 2 - Run training ^^^^^^^^^^^^^^^^ .. code-block:: bash conda activate pytc python scripts/main.py --config tutorials/mito_lucchi++.yaml The config sets ``system.profile: all-gpu-cpu``, so PyTC fans out across every visible GPU. Override at the CLI if needed: .. code-block:: bash python scripts/main.py --config tutorials/mito_lucchi++.yaml \ system.num_gpus=4 data.dataloader.batch_size=4 Training schedule: - **Epoch-based**: 150 epochs × 1000 steps = 150 k optimizer steps. - ``warmup_cosine_lr`` profile: linear warmup, then cosine decay. - ``checkpoint.monitor=train_loss_total_epoch`` (no held-out validation split — Lucchi++ is small and the public test split is used for final reporting). - Image previews logged every 10 epochs to TensorBoard. Outputs land in ``outputs/mito_lucchi++//`` (the ``save_path`` baked into ``train.monitor.checkpoint``). Monitor with TensorBoard: .. code-block:: bash just tensorboard mito_lucchi++ 3 - Inference, decoding, evaluation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Run the combined ``test`` mode against the trained checkpoint: .. code-block:: bash python scripts/main.py --config tutorials/mito_lucchi++.yaml \ --mode test \ --checkpoint outputs/mito_lucchi++//checkpoints/last.ckpt What happens, in order: 1. **Inference**. Sliding window 112³ with 50 % overlap, bump blending, ``sw_batch_size=8``. TTA is on by default (``flip_axes: all``), so Lucchi++ is predicted with 8× flip augmentations averaged. Saves the raw foreground probability as ``test_im_prediction.h5`` in ``outputs/mito_lucchi++//results_step=/``. 2. **Decoding**. The ``binary`` pipeline profile keeps the probability map without further post-processing (foreground mask is thresholded inside evaluation). 3. **Evaluation**. Jaccard / IoU against ``datasets/lucchi++/test_mito.h5``; the result is written next to the prediction. To disable TTA (faster but slightly weaker), override: .. code-block:: bash python scripts/main.py --config tutorials/mito_lucchi++.yaml \ --mode test --checkpoint \ inference.test_time_augmentation.enabled=false 4 - Reference behavior ^^^^^^^^^^^^^^^^^^^^^^^^ A few sanity-check signals: - **Training loss** drops sharply through the warmup (~5 epochs), then descends slowly through cosine decay. With MedNeXt-S on 112³ isotropic patches the loss usually plateaus after epoch ~80. - **Inference** is fast on Lucchi++ (165 × 1024 × 768 test volume) with TTA: tens of seconds on an A100/H100, low single-digit minutes on an L40S. - **Jaccard / IoU** lands in the same ballpark as the published benchmarks for this dataset; the dominant lever beyond training duration is whether TTA is enabled. For a multi-task variant that adds a signed distance transform head, see the sibling configs under ``tutorials/`` (``mito_betaseg.yaml`` and ``mito_betaseg_banis_v{0,1,2}.yaml`` use this style on a different dataset).