--- license: cc-by-nc-sa-4.0 library_name: nnunetv2 pipeline_tag: image-segmentation tags: - biology - microscopy - cell-segmentation - microridge - nnunet - zebrafish --- # MicroridgeVectorAI — v3 A 2D nnU-Net that segments **actin microridges**, **cell regions** and **cell membranes** in projected single-channel microscopy of epithelial tissue. Companion application: (CellVector, AGPL-3.0). The model runs standalone with nnU-Net v2 alone — CellVector is not required. | | | |---|---| | Model id | `a619b15c-e00f-489b-887c-6386e3836c11` | | Task | 2D semantic segmentation, 4 classes | | Architecture | nnU-Net v2 PlainConvUNet, 8 stages, patch 512x512 | | Trainer / folds | `nnUNetTrainer_100epochs`, fold 0 | | Input | single-channel 2D image, any size | | Snapshot hash | `dbe134f83c52b8ecae6cb62182310205496497ec297406ed8a2c912b60ba8cc9` | | Label policy | `membrane-first-v2`, membrane 3 px, microridge 5 px | Labels: `0` background, `1` cell_region, `2` cell_membrane, `3` microridge. ## Scores Frozen test — 36 tiles from **3 fields the model never saw**. Splits are grouped by source field, so no tile of a training field appears in the test set. | Metric | Value | v2 | |---|---|---| | cell_region Dice | 0.943 | 0.944 | | cell_membrane Dice | **0.707** | 0.471 | | cell_membrane boundary F1 (1 px tolerance) | **0.874** | 0.659 | | microridge Dice | 0.852 | 0.877 | | microridge precision / recall | 0.899 / 0.822 | 0.911 / 0.855 | | microridge skeleton length error | 0.105 | 0.100 | nnU-Net's own fold-0 validation (89 tiles): cell_region 0.964, cell_membrane 0.696, microridge 0.886. v2 was trained on labels in which the microridge class had erased 69.6% of the membrane: classes are mutually exclusive and microridges were stroked last, so a ridge running beside a cell edge overwrote it. v3 reverses that contest. The membrane keeps all of its pixels and the microridge class yields 7.2% of its own, which it can afford at a quarter of the frame. Nothing else changed — same data, same architecture, same 100 epochs. **Reading the membrane number.** Dice on a 3-pixel line covering under 3% of the frame collapses when a prediction is offset by a pixel even where it follows the right path, so it understates a thin structure. The boundary F1 of 0.874, which allows one pixel of tolerance, is the more informative figure; the gap between 0.707 and 0.874 is the residual sub-pixel offset, not missing membrane. ## Limitations - **Cell instances are approximate.** Cells are recovered as connected components separated by the predicted membrane. On a frozen-test tile holding 10 cells this returns 9, against 1 for v2, whose membrane was too broken to separate anything. Expect near-misses where the membrane is faint, not exact instance segmentation. - **The ground truth was not human-reviewed.** Labels were imported from published raster masks and corrected only for import artifacts, not by an expert. Treat this model as a proposal generator to be corrected, which is how the companion application uses it. - **Trained on 13 fields.** Train and validation loss diverge (-0.782 vs -0.636), which is what a small number of independent acquisitions looks like. More fields will help more than more epochs. - **One fold, not an ensemble.** Only fold 0 was trained. - Validated on zebrafish periderm-style epithelial microridge imagery. Behaviour on other tissue, magnification or modality is unknown. ## Training data Wide-field frames cut into 477 tiles of at most 512x512 from 19 fields, keeping only regions whose raster truth is trustworthy. Uneven illumination leaves part of such a frame too dark for the upstream segmentation to resolve anything, and that failure is silent — the skeleton mask is empty while the cell mask still looks complete. Blocks were kept only where skeleton density cleared both an absolute floor and a share of the frame's own 90th percentile, **and** at least 95% of the block was attributed to a cell. 68.3% of the field pixels survived. Labels were rasterized from vector geometry with a 3 px membrane and a 5 px microridge stroke. ## Files ```text registry.json provenance record, metrics, checksums nnUNet_results/Dataset503_MicroridgeMembraneFirst/ └─ nnUNetTrainer_100epochs__nnUNetPlans__2d/ ├─ dataset.json channel names and label map ├─ plans.json preprocessing and architecture └─ fold_0/checkpoint_final.pth weights ``` Those three files under the trainer folder are the complete inference set. The directory names encode the configuration — nnU-Net parses `Dataset_/____` — so do not rename them. The checkpoint is shipped unmodified so the `checkpoint_sha256` in `registry.json` verifies. About half of it is optimizer state; stripping to `network_weights`, `init_args`, `trainer_name` and `inference_allowed_mirroring_axes` halves the size but invalidates that checksum. ## Usage ```bash pip install nnunetv2 huggingface_hub hf download leobk/MicroridgeVectorAI --local-dir microridge-model ``` ```python import torch, numpy as np, tifffile from nnunetv2.inference.predict_from_raw_data import nnUNetPredictor MODEL = ("microridge-model/nnUNet_results/Dataset503_MicroridgeMembraneFirst" "/nnUNetTrainer_100epochs__nnUNetPlans__2d") predictor = nnUNetPredictor(device=torch.device("cuda")) predictor.initialize_from_trained_model_folder( MODEL, use_folds=(0,), checkpoint_name="checkpoint_final.pth" ) image = tifffile.imread("frame.tif").astype("float32") segmentation = predictor.predict_single_npy_array( image[None, None], {"spacing": (999.0, 1.0, 1.0)}, None, None, False ) ``` No nnU-Net environment variables are needed for this path. Roughly 13 s for a 512x512 tile on an RTX 4080 SUPER. ### Reimplementing the pipeline The network takes `(1, 1, H, W)` and returns 4 logit channels, and exports to TorchScript. If you drive it yourself, reproduce all of: - **Normalization** — z-score using *each image's own* mean and standard deviation (`use_mask_for_norm=False`). No dataset statistics; `foreground_intensity_properties_per_channel` in `plans.json` is for CT normalization and unused here. - **Sliding window** — 512x512 patches, step 0.5, Gaussian-weighted overlap. - **Test-time augmentation** — mirroring over axes `(0, 1)`. - **Output** — argmax over the 4 channels. Skipping the normalization or the Gaussian window degrades results noticeably and without any error. ## Licensing note These weights are released under **CC BY-NC-SA 4.0**: attribution required, **non-commercial use only**, derivatives under the same terms. Note that this differs from the companion application's code licence (AGPL-3.0) — the code and the weights are covered separately. The weights were trained on third-party imagery; if that source data carries its own terms, they may constrain redistribution of this model independently of this label.