segsuite 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
segsuite-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Asit Mishra
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ exclude CLAUDE.md
2
+ exclude CHANGELOG.md
3
+ recursive-exclude .claude *
4
+ recursive-exclude tests *
@@ -0,0 +1,240 @@
1
+ Metadata-Version: 2.4
2
+ Name: segsuite
3
+ Version: 0.1.0
4
+ Summary: Novel segmentation metrics and differentiable loss functions for PyTorch
5
+ License-Expression: MIT
6
+ Project-URL: Homepage, https://github.com/asitm55/segsuite
7
+ Project-URL: Repository, https://github.com/asitm55/segsuite
8
+ Project-URL: Bug Tracker, https://github.com/asitm55/segsuite/issues
9
+ Keywords: segmentation,metrics,loss,pytorch,deep-learning,medical-imaging
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.8
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
+ Classifier: Topic :: Scientific/Engineering :: Image Recognition
18
+ Classifier: Intended Audience :: Science/Research
19
+ Requires-Python: >=3.8
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: torch>=1.10
23
+ Requires-Dist: numpy>=1.20
24
+ Requires-Dist: scipy>=1.7
25
+ Requires-Dist: opencv-python>=4.5
26
+ Requires-Dist: albumentations>=1.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=7.0; extra == "dev"
29
+ Requires-Dist: pytest-cov; extra == "dev"
30
+ Requires-Dist: black; extra == "dev"
31
+ Requires-Dist: ruff; extra == "dev"
32
+ Provides-Extra: experiments
33
+ Requires-Dist: pandas; extra == "experiments"
34
+ Requires-Dist: seaborn; extra == "experiments"
35
+ Requires-Dist: tqdm; extra == "experiments"
36
+ Requires-Dist: scikit-learn; extra == "experiments"
37
+ Requires-Dist: matplotlib; extra == "experiments"
38
+ Dynamic: license-file
39
+
40
+ # Segsuite
41
+
42
+ **Semantic Segmentation Metrics & Differentiable Loss Functions**
43
+
44
+ Novel metrics (SABRE, U-Score) and their differentiable PyTorch surrogate losses,
45
+ along with baseline metrics (GAS, DFH, TEDS, MAGE, UGTS) and losses.
46
+
47
+ ---
48
+
49
+ ## Installation
50
+
51
+ ### Option A — uv (recommended, fastest)
52
+ [uv](https://docs.astral.sh/uv/) is a drop-in replacement for pip/venv that resolves and
53
+ installs dependencies significantly faster.
54
+
55
+ ```bash
56
+ # install uv (one-time), see https://docs.astral.sh/uv/getting-started/installation/
57
+ curl -LsSf https://astral.sh/uv/install.sh | sh # macOS/Linux
58
+ powershell -c "irm https://astral.sh/uv/install.ps1 | iex" # Windows
59
+
60
+ git clone https://github.com/yourusername/segsuite
61
+ cd segsuite
62
+ uv venv # creates .venv
63
+ uv pip install -e . # or: uv pip install -e ".[dev]" for tests/lint tooling
64
+ ```
65
+
66
+ Once published to PyPI, end users can skip the clone entirely:
67
+ ```bash
68
+ uv pip install segsuite
69
+ ```
70
+
71
+ ### Option B — pip (editable, for development)
72
+ ```bash
73
+ git clone https://github.com/yourusername/segsuite
74
+ cd segsuite
75
+ pip install -e .
76
+ ```
77
+
78
+ ### Option C — From folder / zip
79
+ ```bash
80
+ pip install /path/to/segsuite/
81
+ ```
82
+
83
+ ### Option D — Publish to PyPI (anyone can install)
84
+ ```bash
85
+ pip install build twine
86
+ python -m build # produces dist/
87
+ twine upload dist/* # upload to PyPI
88
+ # then: pip install segsuite OR uv pip install segsuite
89
+ ```
90
+
91
+ ---
92
+
93
+ ## Quick Start
94
+
95
+ ```python
96
+ import torch
97
+ from segsuite.losses import get_loss, SoftSABRELoss, ULoss
98
+ from segsuite.metrics import sabre, u_score, compute_metrics
99
+
100
+ # ── Training ─────────────────────────────────────────────────────────────────
101
+ criterion = get_loss("sabre") # or "uloss", "teds", "mage", "ugts", "dice" …
102
+
103
+ logits = torch.randn(2, 1, 256, 256, requires_grad=True)
104
+ targets = torch.randint(0, 2, (2, 1, 256, 256)).float()
105
+
106
+ loss = criterion(logits, targets)
107
+ loss.backward()
108
+ print(f"Loss: {loss.item():.4f}")
109
+
110
+ # ── Validation ────────────────────────────────────────────────────────────────
111
+ import numpy as np
112
+ P = (torch.sigmoid(logits) > 0.5).float()
113
+ scores = compute_metrics(P, targets)
114
+ for k, v in scores.items():
115
+ print(f" {k:8s}: {v:.4f}")
116
+ ```
117
+
118
+ ---
119
+
120
+ ## All Losses
121
+
122
+ | String key | Class | Description |
123
+ |--------------|---------------------|----------------------------------------------|
124
+ | `dice` | SoftDiceLoss | Standard soft Dice |
125
+ | `iou` | SoftIoULoss | Standard soft IoU |
126
+ | `boundary` | SoftBoundaryLoss | Distance-map boundary (Kervadec 2019) |
127
+ | `gas` | SoftGASLoss | Gradient alignment surrogate |
128
+ | `dfh` | SoftDFHBaseLoss | Dual-F harmonic + Euler topology gate |
129
+ | `teds` | SoftTEDSv2Loss | Proper TEDS_v2 surrogate ✓ (recommended) |
130
+ | `teds_orig` | SoftTEDSLoss | Original composite TEDS (compat.) |
131
+ | `geo_f1` | SoftGeoF1Loss | Distance-weighted F1 |
132
+ | `mage` | SoftMAGEv2Loss | Multi-scale adaptive geometric evaluation |
133
+ | `ugts` | SoftUGTSv4Loss | Unified geometric-topological score |
134
+ | `sabre` | SoftSABRELoss | **Novel** spatial-adaptive boundary & topo |
135
+ | `uloss` | ULoss | **Novel** universal segmentation loss |
136
+ | `bce` | BCEWithLogitsLoss | Standard BCE |
137
+
138
+ ---
139
+
140
+ ## All Metrics
141
+
142
+ | Function | Description |
143
+ |-----------------|------------------------------------------------|
144
+ | `dice(P, G)` | Dice / F1 coefficient |
145
+ | `iou(P, G)` | Intersection over Union |
146
+ | `gas(P, G)` | Gradient Alignment Score |
147
+ | `dfh(P, G)` | Dual-F Harmonic + Euler gate |
148
+ | `teds(P, G)` | Topological Energy Distance Score |
149
+ | `mage(P, G)` | Multi-scale Adaptive Geometric Evaluation |
150
+ | `ugts(P, G)` | Unified Geometric-Topological Score |
151
+ | `sabre(P, G)` | **Novel** SABRE metric |
152
+ | `u_score(P, G)` | **Novel** Universal Segmentation Score |
153
+ | `compute_metrics(P, G)` | All metrics at once → `dict` |
154
+
155
+ ---
156
+
157
+ ## Model
158
+
159
+ ```python
160
+ from segsuite import UNet, build_model
161
+
162
+ model = build_model("unet", n_channels=3, n_classes=1,
163
+ features=[64, 128, 256, 512],
164
+ norm="batch", up_mode="bilinear", init="he")
165
+ ```
166
+
167
+ ## Datasets
168
+
169
+ ```python
170
+ from segsuite import KvasirDataset, ISICDataset, get_dataset
171
+
172
+ train_ds = get_dataset("kvasir", mode="train", size=(256, 256))
173
+ val_ds = get_dataset("isic", mode="val")
174
+ ```
175
+
176
+ ## Benchmark
177
+
178
+ ```python
179
+ from segsuite import MetricChallenge
180
+ ds = MetricChallenge(length=100, mode='fragmented', size=(128, 128))
181
+ gt, pred = ds[0]
182
+ ```
183
+
184
+ Modes: `perfect`, `oversegmentation`, `undersegmentation`, `holes`,
185
+ `fragmented`, `boundary_jitter`, `alignment_shift`, `missed_object`,
186
+ `empty_gt_correct`, `empty_gt_fp`
187
+
188
+ ---
189
+
190
+ ## Experiments
191
+
192
+ `experiments/` ships two full training/evaluation pipelines from the thesis
193
+ (Kvasir-SEG and ISIC Part 1). They need extra dependencies not required by the
194
+ core library:
195
+
196
+ ```bash
197
+ pip install "segsuite[experiments]" # or: uv pip install "segsuite[experiments]"
198
+ ```
199
+
200
+ Point the dataset root at your local data (`src/data/Kvasir`, `src/data/ISIC_Part_1`
201
+ by default — see `segsuite.dataset` for the expected folder layout), then run:
202
+
203
+ ```bash
204
+ python -m experiments.train_kvasir
205
+ python -m experiments.train_isic
206
+ ```
207
+
208
+ Each script trains against every loss in `CONFIG["losses_to_train"]` and evaluates
209
+ with every metric in `CONFIG["metrics_to_eval"]`, writing results under `Results_*/`.
210
+
211
+ ---
212
+
213
+ ## Project Structure
214
+
215
+ ```
216
+ segsuite/
217
+ ├── segsuite/
218
+ │ ├── __init__.py ← all public exports
219
+ │ ├── losses.py ← loss functions + get_loss()
220
+ │ ├── metrics.py ← metric functions + compute_metrics()
221
+ │ ├── dataset.py ← KvasirDataset, ISICDataset, get_dataset()
222
+ │ ├── benchmark.py ← MetricChallenge synthetic benchmark
223
+ │ └── model.py ← UNet, build_model()
224
+ ├── experiments/ ← training scripts (install via segsuite[experiments])
225
+ ├── tests/ ← not shipped in the wheel or sdist
226
+ └── pyproject.toml
227
+ ```
228
+
229
+ ---
230
+
231
+ ## Citation
232
+
233
+ ```bibtex
234
+ @mastersthesis{mishra2025lyingdice,
235
+ author = {Mishra, Asit},
236
+ title = {Beyond Dice: Novel Metrics for Structural Correctness in Medical Image Segmentation},
237
+ school = {Friedrich-Alexander-Universität Erlangen-Nürnberg},
238
+ year = {2025},
239
+ }
240
+ ```
@@ -0,0 +1,201 @@
1
+ # Segsuite
2
+
3
+ **Semantic Segmentation Metrics & Differentiable Loss Functions**
4
+
5
+ Novel metrics (SABRE, U-Score) and their differentiable PyTorch surrogate losses,
6
+ along with baseline metrics (GAS, DFH, TEDS, MAGE, UGTS) and losses.
7
+
8
+ ---
9
+
10
+ ## Installation
11
+
12
+ ### Option A — uv (recommended, fastest)
13
+ [uv](https://docs.astral.sh/uv/) is a drop-in replacement for pip/venv that resolves and
14
+ installs dependencies significantly faster.
15
+
16
+ ```bash
17
+ # install uv (one-time), see https://docs.astral.sh/uv/getting-started/installation/
18
+ curl -LsSf https://astral.sh/uv/install.sh | sh # macOS/Linux
19
+ powershell -c "irm https://astral.sh/uv/install.ps1 | iex" # Windows
20
+
21
+ git clone https://github.com/yourusername/segsuite
22
+ cd segsuite
23
+ uv venv # creates .venv
24
+ uv pip install -e . # or: uv pip install -e ".[dev]" for tests/lint tooling
25
+ ```
26
+
27
+ Once published to PyPI, end users can skip the clone entirely:
28
+ ```bash
29
+ uv pip install segsuite
30
+ ```
31
+
32
+ ### Option B — pip (editable, for development)
33
+ ```bash
34
+ git clone https://github.com/yourusername/segsuite
35
+ cd segsuite
36
+ pip install -e .
37
+ ```
38
+
39
+ ### Option C — From folder / zip
40
+ ```bash
41
+ pip install /path/to/segsuite/
42
+ ```
43
+
44
+ ### Option D — Publish to PyPI (anyone can install)
45
+ ```bash
46
+ pip install build twine
47
+ python -m build # produces dist/
48
+ twine upload dist/* # upload to PyPI
49
+ # then: pip install segsuite OR uv pip install segsuite
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Quick Start
55
+
56
+ ```python
57
+ import torch
58
+ from segsuite.losses import get_loss, SoftSABRELoss, ULoss
59
+ from segsuite.metrics import sabre, u_score, compute_metrics
60
+
61
+ # ── Training ─────────────────────────────────────────────────────────────────
62
+ criterion = get_loss("sabre") # or "uloss", "teds", "mage", "ugts", "dice" …
63
+
64
+ logits = torch.randn(2, 1, 256, 256, requires_grad=True)
65
+ targets = torch.randint(0, 2, (2, 1, 256, 256)).float()
66
+
67
+ loss = criterion(logits, targets)
68
+ loss.backward()
69
+ print(f"Loss: {loss.item():.4f}")
70
+
71
+ # ── Validation ────────────────────────────────────────────────────────────────
72
+ import numpy as np
73
+ P = (torch.sigmoid(logits) > 0.5).float()
74
+ scores = compute_metrics(P, targets)
75
+ for k, v in scores.items():
76
+ print(f" {k:8s}: {v:.4f}")
77
+ ```
78
+
79
+ ---
80
+
81
+ ## All Losses
82
+
83
+ | String key | Class | Description |
84
+ |--------------|---------------------|----------------------------------------------|
85
+ | `dice` | SoftDiceLoss | Standard soft Dice |
86
+ | `iou` | SoftIoULoss | Standard soft IoU |
87
+ | `boundary` | SoftBoundaryLoss | Distance-map boundary (Kervadec 2019) |
88
+ | `gas` | SoftGASLoss | Gradient alignment surrogate |
89
+ | `dfh` | SoftDFHBaseLoss | Dual-F harmonic + Euler topology gate |
90
+ | `teds` | SoftTEDSv2Loss | Proper TEDS_v2 surrogate ✓ (recommended) |
91
+ | `teds_orig` | SoftTEDSLoss | Original composite TEDS (compat.) |
92
+ | `geo_f1` | SoftGeoF1Loss | Distance-weighted F1 |
93
+ | `mage` | SoftMAGEv2Loss | Multi-scale adaptive geometric evaluation |
94
+ | `ugts` | SoftUGTSv4Loss | Unified geometric-topological score |
95
+ | `sabre` | SoftSABRELoss | **Novel** spatial-adaptive boundary & topo |
96
+ | `uloss` | ULoss | **Novel** universal segmentation loss |
97
+ | `bce` | BCEWithLogitsLoss | Standard BCE |
98
+
99
+ ---
100
+
101
+ ## All Metrics
102
+
103
+ | Function | Description |
104
+ |-----------------|------------------------------------------------|
105
+ | `dice(P, G)` | Dice / F1 coefficient |
106
+ | `iou(P, G)` | Intersection over Union |
107
+ | `gas(P, G)` | Gradient Alignment Score |
108
+ | `dfh(P, G)` | Dual-F Harmonic + Euler gate |
109
+ | `teds(P, G)` | Topological Energy Distance Score |
110
+ | `mage(P, G)` | Multi-scale Adaptive Geometric Evaluation |
111
+ | `ugts(P, G)` | Unified Geometric-Topological Score |
112
+ | `sabre(P, G)` | **Novel** SABRE metric |
113
+ | `u_score(P, G)` | **Novel** Universal Segmentation Score |
114
+ | `compute_metrics(P, G)` | All metrics at once → `dict` |
115
+
116
+ ---
117
+
118
+ ## Model
119
+
120
+ ```python
121
+ from segsuite import UNet, build_model
122
+
123
+ model = build_model("unet", n_channels=3, n_classes=1,
124
+ features=[64, 128, 256, 512],
125
+ norm="batch", up_mode="bilinear", init="he")
126
+ ```
127
+
128
+ ## Datasets
129
+
130
+ ```python
131
+ from segsuite import KvasirDataset, ISICDataset, get_dataset
132
+
133
+ train_ds = get_dataset("kvasir", mode="train", size=(256, 256))
134
+ val_ds = get_dataset("isic", mode="val")
135
+ ```
136
+
137
+ ## Benchmark
138
+
139
+ ```python
140
+ from segsuite import MetricChallenge
141
+ ds = MetricChallenge(length=100, mode='fragmented', size=(128, 128))
142
+ gt, pred = ds[0]
143
+ ```
144
+
145
+ Modes: `perfect`, `oversegmentation`, `undersegmentation`, `holes`,
146
+ `fragmented`, `boundary_jitter`, `alignment_shift`, `missed_object`,
147
+ `empty_gt_correct`, `empty_gt_fp`
148
+
149
+ ---
150
+
151
+ ## Experiments
152
+
153
+ `experiments/` ships two full training/evaluation pipelines from the thesis
154
+ (Kvasir-SEG and ISIC Part 1). They need extra dependencies not required by the
155
+ core library:
156
+
157
+ ```bash
158
+ pip install "segsuite[experiments]" # or: uv pip install "segsuite[experiments]"
159
+ ```
160
+
161
+ Point the dataset root at your local data (`src/data/Kvasir`, `src/data/ISIC_Part_1`
162
+ by default — see `segsuite.dataset` for the expected folder layout), then run:
163
+
164
+ ```bash
165
+ python -m experiments.train_kvasir
166
+ python -m experiments.train_isic
167
+ ```
168
+
169
+ Each script trains against every loss in `CONFIG["losses_to_train"]` and evaluates
170
+ with every metric in `CONFIG["metrics_to_eval"]`, writing results under `Results_*/`.
171
+
172
+ ---
173
+
174
+ ## Project Structure
175
+
176
+ ```
177
+ segsuite/
178
+ ├── segsuite/
179
+ │ ├── __init__.py ← all public exports
180
+ │ ├── losses.py ← loss functions + get_loss()
181
+ │ ├── metrics.py ← metric functions + compute_metrics()
182
+ │ ├── dataset.py ← KvasirDataset, ISICDataset, get_dataset()
183
+ │ ├── benchmark.py ← MetricChallenge synthetic benchmark
184
+ │ └── model.py ← UNet, build_model()
185
+ ├── experiments/ ← training scripts (install via segsuite[experiments])
186
+ ├── tests/ ← not shipped in the wheel or sdist
187
+ └── pyproject.toml
188
+ ```
189
+
190
+ ---
191
+
192
+ ## Citation
193
+
194
+ ```bibtex
195
+ @mastersthesis{mishra2025lyingdice,
196
+ author = {Mishra, Asit},
197
+ title = {Beyond Dice: Novel Metrics for Structural Correctness in Medical Image Segmentation},
198
+ school = {Friedrich-Alexander-Universität Erlangen-Nürnberg},
199
+ year = {2025},
200
+ }
201
+ ```
File without changes