Instructions to use Lien-Feng/Lightweight-2-5D-LUNA16 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- ultralytics
How to use Lien-Feng/Lightweight-2-5D-LUNA16 with ultralytics:
# Couldn't find a valid YOLO version tag. # Replace XX with the correct version. from ultralytics import YOLOvXX model = YOLOvXX.from_pretrained("Lien-Feng/Lightweight-2-5D-LUNA16") source = 'http://images.cocodataset.org/val2017/000000039769.jpg' model.predict(source=source, save=True) - Notebooks
- Google Colab
- Kaggle
Lightweight 2.5D pulmonary nodule detection on LUNA16
Reference implementation for "Inter-Slice Representation Outweighs Bounding-Box Supervision Extent in Lightweight 2.5D Pulmonary Nodule Detection: A Whole-Volume Benchmark on LUNA16" (MDPI Diagnostics, under revision).
The study compares two training-time design choices for a capacity-constrained detector - the inter-slice input representation and the spatial extent of bounding-box supervision - under the official LUNA16 evaluation protocol with whole-volume inference.
Headline findings. The inter-slice representation dominates: adjacent-slice 2.5D stacking exceeds a 2D central-slice baseline by +0.130 CPM, with an advantage in all ten official folds, while thin-slab maximum-intensity projection is worse than a plain 2D slice. Reducing the bounding-box supervision extent confers no benefit, and across the (r, w_min) design grid performance tracks the fraction of training boxes clamped at the minimum box size more closely than it tracks either factor alone. Replacing the adjacent-slice channels with copies of the centre slice costs 71 % of the detection confidence for nodules only the 2.5D detector finds, against 6 % for nodules both detectors find, which locates the advantage specifically in through-plane context.
The evaluation protocol is treated as an experimental factor. Scoring these
same checkpoints over only the 1,176 slices that contain an annotated nodule
centre - 0.52 % of the volume data - instead of all 227,225 slices reverses the
supervision result (-0.0209 to +0.0027), attenuates the representation result
fourfold (+0.1297 to +0.0348) and raises every CPM by 0.17-0.31. Nothing else
changes: same weights, same folds, same aggregation, same evaluator. Reproduce it
with python scripts/15_restricted_protocol.py; the outputs are
results/table_protocol_effect.csv and results/table_protocol_contrasts.csv.
What is in this repository
| Path | Contents |
|---|---|
weights/<config>/fold<k>/best.pt |
Ultralytics checkpoints, one per official LUNA16 subset |
luna_rev/ |
the library: data generation, training, full-volume inference, official evaluation, attribution |
scripts/ |
the end-to-end pipeline, in run order (01-07, 10, 12-15) |
examples/predict_scan.py |
run a scan and emit a LUNA16-format candidate CSV |
tests/test_evaluate.py |
correctness tests, including the reference verification |
examples/evaluate_submission.py |
score any candidate CSV with the official evaluator |
results/ |
every table and figure reported in the manuscript |
PROTOCOL.md |
the evaluation protocol, stated precisely enough to reproduce |
Evaluation protocol
- Official LUNA16 10-fold cross-validation - fold k tests on
subset<k>; the validation split used for checkpoint selection is a different held-out subset, so no evaluation scan influences model selection. - Official evaluation semantics - candidate matching by the centre-distance
criterion, one candidate per nodule, and irrelevant findings from
annotations_excluded.csvignored rather than counted as false positives. The implementation reproduces the counters published in the officialCADAnalysis.txtreference output exactly (TP 1120 / FP 548420 / ignored 1294 / double detections 231 on the bundled sample submission). That reference predates thediameter < 0 -> 10 mmfallback the script now applies, so reproducing it usesexcluded_policy="legacy_abs"; the reported results use the current fallback ("official"). SeePROTOCOL.md. - Full-volume inference - every axial slice of all 888 scans is scanned, so false positives per scan means what the FROC axis says it means.
- CPM is the mean sensitivity at 0.125, 0.25, 0.5, 1, 2, 4 and 8 FP/scan, with scan-level bootstrap confidence intervals over 888 scans.
Results
| label | cpm | ci_low | ci_high | candidates_per_scan |
|---|---|---|---|---|
| Exp1: 2D central slice, loose | 0.6498 | 0.6181 | 0.6778 | 111.2 |
| Exp2: thin-slab MIP, loose | 0.5965 | 0.5703 | 0.6239 | 93.1 |
| Exp3: adjacent-slice 2.5D, loose | 0.7795 | 0.7517 | 0.8005 | 80.2 |
| Exp4: adjacent-slice 2.5D, strict r=0.6 | 0.7586 | 0.7332 | 0.7821 | 83 |
Usage
from ultralytics import YOLO
# fold 0 was trained on subsets 2-9 and is therefore valid for subset0 scans
model = YOLO("weights/Exp4_2p5D_Strict/fold0/best.pt")
results = model.predict("slice.png", imgsz=512, conf=0.01)
Whole-scan inference, producing a LUNA16 submission CSV:
python examples/predict_scan.py --scan /path/to/series.mhd \
--weights weights/Exp4_2p5D_Strict/fold0/best.pt --out candidates.csv
Scoring any candidate CSV with the official evaluator:
python examples/evaluate_submission.py --candidates candidates.csv
Verifying that the evaluator reproduces the official reference output (needs no imaging data):
python examples/evaluate_submission.py --self-test
python tests/test_evaluate.py
Input construction
Volumes are windowed to [-1000, 400] HU and rescaled to 8-bit. Three slice representations are supported:
2d- the central slice, replicated across the three channels;mip- maximum-intensity projection over the slab {z-1, z, z+1};naive- adjacent-slice stacking, channels (S_z-1, S_z, S_z+1).
Training boxes come from the annotated diameter through the spherical-chord
model described in PROTOCOL.md, scaled by the supervision-extent ratio
r_sample and floored at w_min pixels.
Configurations
{
"Exp1_2D_Loose": {
"label": "Exp1: 2D central slice, loose",
"model": "yolo11n.pt",
"representation": "2d",
"r_sample": 1.0,
"w_min_px": 6.0,
"negatives": "all888",
"seed": 42
},
"Exp2_MIP_Loose": {
"label": "Exp2: thin-slab MIP, loose",
"model": "yolo11n.pt",
"representation": "mip",
"r_sample": 1.0,
"w_min_px": 6.0,
"negatives": "all888",
"seed": 42
},
"Exp3_2p5D_Loose": {
"label": "Exp3: adjacent-slice 2.5D, loose",
"model": "yolo11n.pt",
"representation": "naive",
"r_sample": 1.0,
"w_min_px": 6.0,
"negatives": "all888",
"seed": 42
},
"Exp4_2p5D_Strict": {
"label": "Exp4: adjacent-slice 2.5D, strict r=0.6",
"model": "yolo11n.pt",
"representation": "naive",
"r_sample": 0.6,
"w_min_px": 6.0,
"negatives": "all888",
"seed": 42
},
"Rsweep_r0.4": {
"label": "2.5D strict r=0.4",
"model": "yolo11n.pt",
"representation": "naive",
"r_sample": 0.4,
"w_min_px": 6.0,
"negatives": "all888",
"seed": 42
},
"Rsweep_r0.5": {
"label": "2.5D strict r=0.5",
"model": "yolo11n.pt",
"representation": "naive",
"r_sample": 0.5,
"w_min_px": 6.0,
"negatives": "all888",
"seed": 42
},
"Rsweep_r0.7": {
"label": "2.5D strict r=0.7",
"model": "yolo11n.pt",
"representation": "naive",
"r_sample": 0.7,
"w_min_px": 6.0,
"negatives": "all888",
"seed": 42
},
"Rsweep_r0.8": {
"label": "2.5D strict r=0.8",
"model": "yolo11n.pt",
"representation": "naive",
"r_sample": 0.8,
"w_min_px": 6.0,
"negatives": "all888",
"seed": 42
},
"Wsweep_w4": {
"label": "2.5D strict r=0.6, w_min=4 px",
"model": "yolo11n.pt",
"representation": "naive",
"r_sample": 0.6,
"w_min_px": 4.0,
"negatives": "all888",
"seed": 42
},
"Wsweep_w8": {
"label": "2.5D strict r=0.6, w_min=8 px",
"model": "yolo11n.pt",
"representation": "naive",
"r_sample": 0.6,
"w_min_px": 8.0,
"negatives": "all888",
"seed": 42
},
"NegAbl_Exp3_posonly": {
"label": "Exp3 without nodule-free scans",
"model": "yolo11n.pt",
"representation": "naive",
"r_sample": 1.0,
"w_min_px": 6.0,
"negatives": "positive_scans_only",
"seed": 42
},
"NegAbl_Exp4_posonly": {
"label": "Exp4 without nodule-free scans",
"model": "yolo11n.pt",
"representation": "naive",
"r_sample": 0.6,
"w_min_px": 6.0,
"negatives": "positive_scans_only",
"seed": 42
},
"NegMatch_Exp3_posonly12": {
"label": "Exp3, nodule-bearing scans only, negatives count-matched",
"model": "yolo11n.pt",
"representation": "naive",
"r_sample": 1.0,
"w_min_px": 6.0,
"negatives": "positive_scans_only",
"seed": 42
},
"Seed1337_Exp3_2p5D_Loose": {
"label": "Exp3 (seed 1337)",
"model": "yolo11n.pt",
"representation": "naive",
"r_sample": 1.0,
"w_min_px": 6.0,
"negatives": "all888",
"seed": 1337
},
"Seed2026_Exp3_2p5D_Loose": {
"label": "Exp3 (seed 2026)",
"model": "yolo11n.pt",
"representation": "naive",
"r_sample": 1.0,
"w_min_px": 6.0,
"negatives": "all888",
"seed": 2026
},
"Seed1337_Exp4_2p5D_Strict": {
"label": "Exp4 (seed 1337)",
"model": "yolo11n.pt",
"representation": "naive",
"r_sample": 0.6,
"w_min_px": 6.0,
"negatives": "all888",
"seed": 1337
},
"Seed2026_Exp4_2p5D_Strict": {
"label": "Exp4 (seed 2026)",
"model": "yolo11n.pt",
"representation": "naive",
"r_sample": 0.6,
"w_min_px": 6.0,
"negatives": "all888",
"seed": 2026
},
"Y26_Exp3_2p5D_Loose": {
"label": "YOLO26n, 2.5D loose",
"model": "yolo26n.pt",
"representation": "naive",
"r_sample": 1.0,
"w_min_px": 6.0,
"negatives": "all888",
"seed": 42
},
"Y26_Exp4_2p5D_Strict": {
"label": "YOLO26n, 2.5D strict r=0.6",
"model": "yolo26n.pt",
"representation": "naive",
"r_sample": 0.6,
"w_min_px": 6.0,
"negatives": "all888",
"seed": 42
}
}
Intended use and limitations
Research use only. This is a candidate detector, not a diagnostic device: it localises nodule candidates and does not characterise malignancy. It is trained and evaluated on a single public cohort (LUNA16 / LIDC-IDRI) and has not been validated on external, multi-centre, or prospectively acquired data. Performance on scanners, reconstruction kernels, slice thicknesses or populations unlike LUNA16 is unknown. It must not be used for clinical decision-making.
Citation
Chou, L.-F.; Peng, B.-R.; Wei, C.-S.; Huang, Y.-M. Inter-Slice Representation Outweighs Bounding-Box Supervision Extent in Lightweight 2.5D Pulmonary Nodule Detection: A Whole-Volume Benchmark on LUNA16. Diagnostics (under revision).
Data: LUNA16 (https://luna16.grand-challenge.org/), derived from LIDC-IDRI via The Cancer Imaging Archive. Users must comply with the LUNA16/LIDC-IDRI terms.
- Downloads last month
- -