DIAGNOSTIC CONSOLE /HuBMAP · VASCULATURE /STATUS: DOCUMENTED pipeline dataset results repo ↗
🩸 Kaggle · HuBMAP 2023 · Instance Segmentation

Hacking the
Human Vasculature

An applied research project on microvascular instance segmentation in PAS-stained human kidney histology.

One question, followed all the way through: which method actually finds these vessels, and does it hold up on slides it has never seen? Clinical motivation, two model families, a reproducible pipeline, and honest conclusions. Best public score AP@0.6 = 0.3317, with every number traced to a primary source.

Host
HuBMAP
NIH · IU
Task
Instance
Segmentation
Metric
AP @ IoU 0.6
Prize Pool
$50K
Teams
1,021
Modality
PAS
Kidney WSI
01 / ABSTRACT

Mapping the body's addressing system

The function of human organs depends on the spatial organization of ~37 trillion cells. To map them, the Vasculature Common Coordinate Framework (VCCF) uses blood vasculature — down to individual capillaries — as a coordinate system. Gaps in our knowledge of microvasculature become gaps in the VCCF.

HuBMAP 2023 asked participants to automatically segment microvascular structures (blood vessels) in Periodic acid-Schiff stained whole-slide images of healthy human kidney — a step toward a Human Reference Atlas.

To study that task honestly, the project is built on a configuration-driven training apparatus. It rasterizes polygonal annotations into semantic or instance masks, applies a reproducible Albumentations pipeline, trains a UNet++ / MobileNetV2 network under PyTorch Lightning with class-balanced cross-entropy, and encodes predictions in the competition's COCO-RLE, zlib, base64 format.

The aim was a maintainable, template-generated system that keeps runs comparable and reproducible, so the experiments in the notebooks can actually be trusted.

02 / CLINICAL CONTEXT

Why microvessels matter

Reliable, automated delineation of vessels from stained tissue turns raw slide data into structured, machine-readable vascular maps — a prerequisite for studying how cell-to-cell relationships affect health.

specimen · overlay Kidney tile with blood-vessel mask overlay
512×512 PAS-stained kidney tile with its blood-vessel mask overlaid — rendered by this project's notebooks.
renal architecture

Kidney tissue contains glomeruli (capillary balls that begin the nephron) and dense networks of peritubular capillaries and vasa recta. The target class is blood_vessel; glomerulus regions are excluded (overlaps count as false positives) and ambiguous structures are marked unsure.

the objective

Segment instances of microvascular structures so researchers can fill the microvasculature gaps in the VCCF and, ultimately, the Human Reference Atlas.

03 / DATASET

14 slides, three regimes

Tiles extracted from 14 Whole-Slide Images, organized into three datasets of decreasing annotation quality. No competition data or model weights are committed to this repository.

DatasetWSIsAnnotationsPurpose
Dataset 1subset of 5Expert-reviewed polygonsPrimary signal · all test tiles originate here
Dataset 2same 5Sparse, not expert-reviewedExtra / noisy supervision
Dataset 3+9 moreUnannotatedSemi- / self-supervised opportunities
total tiles
7,033

tile_meta.csv

annotated
1,633

polygons.jsonl

tile size
512²

TIFF · ~650 in test

eda · distribution Tile count per dataset
Tiles per dataset.
eda · donors Donor sex and race distribution
Donor sex / race across annotated WSIs — aggregate statistics only.
04 / EVALUATION

Average Precision at IoU ≥ 0.6

Scored exactly as the OpenImages Instance Segmentation Challenge, but with a single class. A predicted mask matches ground truth when their Intersection-over-Union crosses a single threshold of 0.6 — not a COCO-style average over thresholds.

// mask overlap and average precision
$$ \mathrm{IoU}(A,B)=\frac{\lvert A\cap B\rvert}{\lvert A\cup B\rvert}, \qquad \mathrm{AP}=\sum_{n}\left(R_n-R_{n-1}\right)P_n $$

Predictions are ranked by descending confidence; a true positive matches an unclaimed ground-truth vessel at $\mathrm{IoU}\ge 0.6$, while predictions inside glomerulus regions are false positives.

05 / SYSTEM DESIGN

Template → config → build

Nothing is hard-coded. Dataset semantics, augmentation and trainer behaviour are declared in YAML that is generated from Python "image" templates, wired through environment variables, then loaded and merged by a builder at runtime.

flowchart LR
    A["polygons.jsonl
+ 512x512 tiles"] --> B["HuBMAPDataset
parse + rasterize"] B --> C["cv2.fillPoly
+ optional borders"] C --> D["AugmentPipeline
Albumentations"] D --> E["HuBMAPDataModule
80/20 split"] E --> F["HuBMAPLightningModule
UNet++ / MobileNetV2"] F --> G["Class-balanced
Cross-Entropy"] F --> H["torchmetrics
IoU · F1 · Acc"] G --> I["HuBMAPTrainer
callbacks + logging"] H --> I I --> J["Submission
argmax masks"] J --> K["COCO-RLE
zlib · base64"] K --> L["submission.csv"]
06 / METHODOLOGY

Inside the pipeline

Mask rasterizationA config head switches between a single semantic mask and per-vessel instance masks. An optional border class (via cv2.polylines) helps separate touching vessels.
AugmentationResize 512 → H/V flip → Affine ±15° → Perspective → ImageNet Normalize → ToTensorV2. Spatial transforms and debug preview are config-toggled.
Modelsmp.UnetPlusPlus with a MobileNetV2 encoder (depth 5), 3 classes: background / blood_vessel / border.
LossCross-Entropy with per-batch balanced class weights from scikit-learn — for the heavy background-vs-vessel imbalance.
OptimizationAdam + ReduceLROnPlateau (patience 5, monitors val_loss). Checkpoints top-5, EarlyStopping, TF32 matmul, seeded.
TrackingWeights & Biases (wandb.watch) plus TensorBoard, logging IoU / F1 / accuracy each epoch.
// class-balanced cross-entropy · used in HuBMAPLightningModule
$$ w_c=\frac{N}{C\cdot n_c}, \qquad \mathcal{L}_{\mathrm{CE}}=-\frac{1}{N}\sum_{i=1}^{N} w_{y_i}\,\log\frac{e^{z_{i,y_i}}}{\sum_{c=1}^{C}e^{z_{i,c}}} $$
// segmentation overlap metrics · Jaccard / Dice
$$ \mathrm{IoU}=\frac{\lvert A\cap B\rvert}{\lvert A\cup B\rvert}, \qquad F_1=\mathrm{Dice}=\frac{2\lvert A\cap B\rvert}{\lvert A\rvert+\lvert B\rvert} $$
07 / RESULTS & EXPERIMENTS

Two model families, graded on the board

full provenance

Every number here traces to a primary artifact — the official Kaggle submission export, the saved Ultralytics results.csv logs, or the notebooks' own executed outputs. The leaderboard metric is AP at a single IoU = 0.6, single class. Local YOLO numbers are Mask mAP@50 / 50-95 on an 80/20 split, a more forgiving measurement, which is the whole point of the generalization analysis below.

best public AP @ 0.6
0.3317

selected · Mask R-CNN line

YOLOv8x local · vessel
0.690

Mask mAP@50 · blood_vessel

graded submissions
11

06-20 → 07-07 · 2 selected

Submission (2023)Public AP @ 0.6SelectedMost likely source
06-250.168 → 0.209early Mask R-CNN drafts
06-26 16:150.3317✅ bestMask R-CNN (torchvision)
06-26 20:230.2737YOLOv8x-seg
07-070.2737YOLO submission notebook
yolov8x-seg · training run YOLOv8x-seg training and validation curves
YOLOv8x-seg over 20 epochs — losses fall, Box/Mask precision·recall·mAP climb. Best Mask mAP@50 = 0.597 (all classes), 0.690 on the scored blood_vessel class.
what worked

YOLOv8x-seg + SGD + close_mosaic was the best, most stable line (0.60 Mask mAP@50 locally); SGD beat Adam 0.60 vs 0.45. COCO transfer learning converged Mask R-CNN in 10 epochs (val loss 1.19 → 0.95). The offline submission plumbing (building pycocotools/ultralytics from attached datasets, COCO-RLE to zlib to base64) was verified end-to-end.

the generalization gap

Local blood_vessel Mask mAP@50 was 0.690, but the hidden-test board was ~0.27. The cause is in the data code: the train/val split is an unshuffled index slice that ignores WSI boundaries, so tiles from one slide leak across the split. A group-aware per-WSI split is the first fix any next iteration should make.