Lung Nodule Segmentation — SegResNet (3D, WIDE)

Voxel-level segmentation of pulmonary nodules in 3D chest CT volumes, cropped to the lung region. Wide-capacity SegResNet (init_filters = 32, ~83 M params) retrained on the unified split.

This is the "wide SegResNet" architecture from the paper, directly comparable to the other two-stage nodule models (segresnet_small, dynunet) — all of which share the same train / val / test split.

Peaked at val Dice 0.5711 (per-case mean) at epoch 489 / 1000.

Model details

  • Architecture: MONAI SegResNet, 3D residual U-Net
  • Trainable parameters: 82,637,282
  • Input: (1, 256, 256, 256) CT crop, intensity-normalised to [0, 1], resampled from a per-series lung bbox (padding = 20 vox)
  • Output: (2, 256, 256, 256) softmax logits — class 0 = background, class 1 = nodule
  • Framework: PyTorch + MONAI

Data

Trained on the unified split (patient-grouped, dataset-stratified):

Source Role
NLST train + val + test
NSCLC-Radiomics train + val + test
LIDC-IDRI train + val + test

Split sizes: 1 683 train / 297 val / 325 test (held out).

Note on bboxes. This model was originally trained with a regenerated bbox JSON (tighter lung crops) that differs from the bboxes_unified.json bundled with the small and DynUNet variants. Reproducing from the bundled bboxes gives small variance from the released checkpoint but does not materially affect training.

Validation & test metrics

Test split (325 series, ~5.5 × 10⁹ voxels, micro-averaged):

Metric Value
mIoU 0.7482
Accuracy 0.9996
Precision 0.5766
Recall 0.7818
Dice / F1 (micro) 0.6637

Per-case Dice distribution: mean 0.5706, median 0.6304, p25 0.4069, p75 0.7834.

Comparison to the other two-stage nodule models on the same test set

Model mIoU Precision Recall Dice (micro) Per-case Dice mean
nodule-segresnet-3d-small 0.7391 0.539 0.812 0.6478 0.5240
nodule-dynunet-3d 0.7594 0.624 0.757 0.6838 0.5560
this model (wide) 0.7482 0.577 0.782 0.6637 0.5706

On voxel-level metrics (mIoU / Dice_micro), DynUNet wins; on per-case Dice mean (equal weight per patient regardless of nodule size), this wide-SegResNet variant wins. Which is "best" depends on the metric: large-nodule cases dominate the micro-averaged numbers, while per-case-averaged metrics weigh each patient equally.

How to load & run inference

import yaml, torch
from monai.networks.nets import SegResNet

cfg = yaml.safe_load(open("config.yaml"))["model"]
model = SegResNet(
    spatial_dims = cfg["spatial_dims"],
    in_channels  = cfg["in_channels"],
    out_channels = cfg["out_channels"],      # 2
    init_filters = cfg["init_filters"],      # 32 (wide)
    blocks_down  = tuple(cfg["blocks_down"]),
    blocks_up    = tuple(cfg["blocks_up"]),
    dropout_prob = cfg["dropout_prob"],
)
state = torch.load("model.pth", map_location="cpu", weights_only=True)
model.load_state_dict(state)
model.eval()

with torch.no_grad():
    # Input: (B, 1, 256, 256, 256), lung-bbox-cropped CT resampled to 256³
    x = torch.randn(1, 1, 256, 256, 256)
    logits = model(x)                             # (B, 2, D, H, W)
    pred_class = logits.argmax(dim=1)             # (B, D, H, W) in {0, 1}
    nodule_mask = (pred_class == 1).to(torch.uint8)

This model expects lung-bbox-cropped input. A separate 2D ROI model is needed to produce that bbox — see the accompanying ROI checkpoints (szabopeter/roi-segresnet-2d or szabopeter/roi-swinunetr-2d), or use the demo's inference.py which chains them for you.

Training recipe

  • Loss: Focal Tversky + weighted CE (α=0.3, β=0.7, γ=2.0, λ_CE=0.3, ce_nodule_weight = 100)
  • Optimizer: Adam (lr=1e-5, wd=1e-5)
  • Scheduler: CosineAnnealingLR (T_max=1000, η_min=1e-6)
  • Batch size: 2
  • Epochs: 1000 | best checkpoint at epoch 489 / 1000
  • Mixed precision: bf16
  • Seed: 42
  • Hardware: 1 × NVIDIA H100 94 GB
  • Wall-clock: ≈ 12 days

Full config is included in this repo as config.yaml.

Companion models

License & intended use

Apache 2.0. Training data was public but subject to dataset-specific terms (NLST, NSCLC-Radiomics, LIDC-IDRI).

Not a medical device. Research use only.

Citation

Paper in preparation.

Downloads last month
5
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support