Skip to main content

Novel segmentation metrics and differentiable loss functions for PyTorch

Project description

Segsuite

Semantic Segmentation Metrics & Differentiable Loss Functions

Novel metrics (SABRE, U-Score) and their differentiable PyTorch surrogate losses, along with baseline metrics (GAS, DFH, TEDS, MAGE, UGTS) and losses.


Installation

Option A — uv (recommended, fastest)

uv is a drop-in replacement for pip/venv that resolves and installs dependencies significantly faster.

# install uv (one-time), see https://docs.astral.sh/uv/getting-started/installation/
curl -LsSf https://astral.sh/uv/install.sh | sh        # macOS/Linux
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"   # Windows

git clone https://github.com/yourusername/segsuite
cd segsuite
uv venv                       # creates .venv
uv pip install -e .           # or: uv pip install -e ".[dev]" for tests/lint tooling

Once published to PyPI, end users can skip the clone entirely:

uv pip install segsuite

Option B — pip (editable, for development)

git clone https://github.com/yourusername/segsuite
cd segsuite
pip install -e .

Option C — From folder / zip

pip install /path/to/segsuite/

Option D — Publish to PyPI (anyone can install)

pip install build twine
python -m build           # produces dist/
twine upload dist/*       # upload to PyPI
# then: pip install segsuite   OR   uv pip install segsuite

Quick Start

import torch
from segsuite.losses import get_loss, SoftSABRELoss, ULoss
from segsuite.metrics import sabre, u_score, compute_metrics

# ── Training ─────────────────────────────────────────────────────────────────
criterion = get_loss("sabre")   # or "uloss", "teds", "mage", "ugts", "dice" …

logits  = torch.randn(2, 1, 256, 256, requires_grad=True)
targets = torch.randint(0, 2, (2, 1, 256, 256)).float()

loss = criterion(logits, targets)
loss.backward()
print(f"Loss: {loss.item():.4f}")

# ── Validation ────────────────────────────────────────────────────────────────
import numpy as np
P = (torch.sigmoid(logits) > 0.5).float()
scores = compute_metrics(P, targets)
for k, v in scores.items():
    print(f"  {k:8s}: {v:.4f}")

All Losses

String key Class Description
dice SoftDiceLoss Standard soft Dice
iou SoftIoULoss Standard soft IoU
boundary SoftBoundaryLoss Distance-map boundary (Kervadec 2019)
gas SoftGASLoss Gradient alignment surrogate
dfh SoftDFHBaseLoss Dual-F harmonic + Euler topology gate
teds SoftTEDSv2Loss Proper TEDS_v2 surrogate ✓ (recommended)
teds_orig SoftTEDSLoss Original composite TEDS (compat.)
geo_f1 SoftGeoF1Loss Distance-weighted F1
mage SoftMAGEv2Loss Multi-scale adaptive geometric evaluation
ugts SoftUGTSv4Loss Unified geometric-topological score
sabre SoftSABRELoss Novel spatial-adaptive boundary & topo
uloss ULoss Novel universal segmentation loss
bce BCEWithLogitsLoss Standard BCE

All Metrics

Function Description
dice(P, G) Dice / F1 coefficient
iou(P, G) Intersection over Union
gas(P, G) Gradient Alignment Score
dfh(P, G) Dual-F Harmonic + Euler gate
teds(P, G) Topological Energy Distance Score
mage(P, G) Multi-scale Adaptive Geometric Evaluation
ugts(P, G) Unified Geometric-Topological Score
sabre(P, G) Novel SABRE metric
u_score(P, G) Novel Universal Segmentation Score
compute_metrics(P, G) All metrics at once → dict

Model

from segsuite import UNet, build_model

model = build_model("unet", n_channels=3, n_classes=1,
                     features=[64, 128, 256, 512],
                     norm="batch", up_mode="bilinear", init="he")

Datasets

from segsuite import KvasirDataset, ISICDataset, get_dataset

train_ds = get_dataset("kvasir", mode="train", size=(256, 256))
val_ds   = get_dataset("isic",   mode="val")

Benchmark

from segsuite import MetricChallenge
ds = MetricChallenge(length=100, mode='fragmented', size=(128, 128))
gt, pred = ds[0]

Modes: perfect, oversegmentation, undersegmentation, holes, fragmented, boundary_jitter, alignment_shift, missed_object, empty_gt_correct, empty_gt_fp


Experiments

experiments/ ships two full training/evaluation pipelines from the thesis (Kvasir-SEG and ISIC Part 1). They need extra dependencies not required by the core library:

pip install "segsuite[experiments]"       # or: uv pip install "segsuite[experiments]"

Point the dataset root at your local data (src/data/Kvasir, src/data/ISIC_Part_1 by default — see segsuite.dataset for the expected folder layout), then run:

python -m experiments.train_kvasir
python -m experiments.train_isic

Each script trains against every loss in CONFIG["losses_to_train"] and evaluates with every metric in CONFIG["metrics_to_eval"], writing results under Results_*/.


Project Structure

segsuite/
├── segsuite/
│   ├── __init__.py     ← all public exports
│   ├── losses.py       ← loss functions + get_loss()
│   ├── metrics.py      ← metric functions + compute_metrics()
│   ├── dataset.py      ← KvasirDataset, ISICDataset, get_dataset()
│   ├── benchmark.py    ← MetricChallenge synthetic benchmark
│   └── model.py        ← UNet, build_model()
├── experiments/         ← training scripts (install via segsuite[experiments])
├── tests/               ← not shipped in the wheel or sdist
└── pyproject.toml

Citation

@mastersthesis{mishra2025lyingdice,
  author = {Mishra, Asit},
  title  = {Beyond Dice: Novel Metrics for Structural Correctness in Medical Image Segmentation},
  school = {Friedrich-Alexander-Universität Erlangen-Nürnberg},
  year   = {2025},
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

segsuite-0.1.0.tar.gz (38.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

segsuite-0.1.0-py3-none-any.whl (45.3 kB view details)

Uploaded Python 3

File details

Details for the file segsuite-0.1.0.tar.gz.

File metadata

  • Download URL: segsuite-0.1.0.tar.gz
  • Upload date:
  • Size: 38.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for segsuite-0.1.0.tar.gz
Algorithm Hash digest
SHA256 bdec7a49a3475062abb5f225dc308049384f014b43fead20925fa334a9c50222
MD5 b5e6a5a88a89d95e5e7825df3a9dafd8
BLAKE2b-256 0ebba32bb097a55920479c3c9ca8725a4aefc81ccf276d9ebc8f94a898d86d37

See more details on using hashes here.

File details

Details for the file segsuite-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: segsuite-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 45.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for segsuite-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3b4aaf8dc5381e17c991dd015d917de03e007246a3e96c0e7ebff886107b2c52
MD5 9aa1d8dd2ebb2591d342bcf7cfa89f72
BLAKE2b-256 8cbaebf70a055e2a8fe2f52f792d800b6a312d745bdd08976bbb226b8146e30d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page