File size: 3,291 Bytes
57b08ce
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28493d7
57b08ce
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
---
license: apache-2.0
tags:
- medical-imaging
- segmentation
- image-segmentation
- ct
- lung
- monai
- pytorch
library_name: pytorch
pipeline_tag: image-segmentation
---

# Lung ROI Segmentation — SegResNet (2D)

Per-slice 2D lung foreground (thoracic parenchyma) segmentation for
chest CT. Used as the ROI stage of a two-stage coarse-to-fine
pulmonary-nodule segmentation pipeline: its outputs are stacked into a
3D lung bounding box that the downstream nodule model crops to.

## Model details

- **Architecture**: [MONAI SegResNet](https://docs.monai.io/en/stable/networks.html#segresnet), 2D residual U-Net
- **Trainable parameters**: 6,904,081
- **Input**: `(1, 256, 256)` axial CT slice, intensity-normalised to `[0, 1]`
- **Output**: `(1, 256, 256)` sigmoid map; foreground = lung tissue
- **Framework**: PyTorch + MONAI

## Data

Trained on the `unified` split (patient-grouped, dataset-stratified)
of a unified corpus assembled from three public sources:

- NLST
- NSCLC-Radiomics
- LIDC-IDRI

Slices per split: **365 014 train / 64 097 val / — test held out**.

## Validation metrics

Evaluated on 64 097 val slices (≈ 4.2 × 10⁹ pixels), micro-averaged at
0.5 threshold on sigmoid output.

| Metric      | Value  |
|-------------|-------:|
| mIoU        | 0.9803 |
| Accuracy    | 0.9953 |
| Precision   | 0.9797 |
| Recall      | 0.9857 |
| Dice (F1)   | 0.9827 |

## How to load & run inference

```python
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"],
    init_filters = cfg["init_filters"],
    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():
    x = torch.randn(1, 1, 256, 256)         # (B, C, H, W) — replace with your CT slice
    prob = torch.sigmoid(model(x))
    lung_mask = (prob > 0.5).to(torch.uint8)
```

## Training recipe

- **Loss**: `DiceLoss(sigmoid=True, squared_pred=True)`
- **Optimizer**: Adam (lr = 1e-3, weight decay = 1e-5)
- **Scheduler**: CosineAnnealingLR (T_max = 100, η_min = 1e-6)
- **Batch size**: 16
- **Samples/epoch**: 20 000 (random subsample of ~365 k train slices)
- **Epochs budget**: 100  |  **best checkpoint at epoch 7 / 100**
- **Mixed precision**: bf16
- **Seed**: 42
- **Hardware**: 1 × NVIDIA H100 94 GB

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

## Reproducing training

Training code lives in an accompanying reproduction demo (published
separately). Once available, reproduce with:

```bash
export DATA_ROOT=/path/to/unified          # dir containing ct_2d/ and roi_sem_seg_2d/
python train.py --config config.yaml
```

## License & intended use

Model weights released under Apache 2.0. Training data was public but
covered by dataset-specific terms (NLST, NSCLC-Radiomics, LIDC-IDRI) —
users must comply with those separately when using the model on
comparable data.

**Not a medical device.** Not intended for clinical use. Research only.

## Citation

Paper in preparation.