Skip to main content

Breast ultrasound benign-malignant diagnosis with segmentation-assisted multi-task learning.

Project description

JwzTumor

PyPI version PyPI downloads Python License

Breast ultrasound benign-malignant diagnosis with segmentation-assisted multi-task learning.

Overview

JwzTumor implements LABDG-Pre + DGBC-MTLNet + MPTC-Head, a multi-task system for breast tumor diagnosis from ultrasound images:

  • LABDG-Pre: Lesion-aware boundary-preserving domain-generalized preprocessing
  • DGBC-MTLNet: Domain-generalized boundary-context collaborative multi-task network (CNN-Mamba hybrid)
  • MPTC-Head: Morphology-prompted topology-consistent classification head (4-stream)

The system outputs: classification probability, segmentation mask, edge map, SDM, uncertainty map, and explainability visualizations.

Project Structure

jwz-tumor/
  pyproject.toml
  configs/          # 8 YAML configs
  dataset/          # BUSBRA + BUSI data
  web/              # React + Vite + TypeScript frontend source
  scripts/          # Frontend packaging and maintenance scripts
  src/JwzTumor/
    cli/            # CLI entrypoints, including jwzt server
    data/           # Datasets, preprocessing, augmentation, cache, audit, collate
    models/         # LABDG-Pre, DGBCEncoder, MPP, decoder, MPTC-Head
    losses/         # 7 loss modules + factory
    training/       # Stage trainer, scheduler, callbacks
    inference/      # Predictor, TTA, postprocessing, visualization
    evaluation/     # Classification + segmentation metrics
    server/         # FastAPI inference server, /api/report, packaged static UI
      report/       # Rule/LLM/hybrid report generation
      ui/           # Built frontend files served by jwzt server --with-ui
    utils/          # Config, seed, logging, I/O, registry
  tests/            # Python tests

Datasets

BUSBRA (Training)

  • Images: bus_{id}-{side}.png, Masks: mask_{id}-{side}.png
  • Labels: bus_data.csv (Pathology: benign/malignant)
  • CV: 5-fold-cv.csv or 10-fold-cv.csv
  • Case-level splitting (no leak)

BUSI (Testing)

  • Directory-based: benign/, malignant/
  • Skip: normal-不使用/
  • Multi-mask: OR union in original size before resize
  • RGB images converted to grayscale

Installation

# Install from PyPI
pip install JwzTumor

# Using uv
uv pip install -e .

# Development
uv pip install -e ".[dev]"

Quick Start

# Show version
jwzt version

# Export config template
jwzt get --name train_full --output configs/my_config.yaml

# Train
jwzt train --config configs/train_full.yaml --experiment-name exp001 --fold 1

# Stage-specific training
jwzt train --config configs/train_pretrain_pre.yaml --stage pretrain_pre --fold 1
jwzt train --config configs/train_pretrain_seg.yaml --stage pretrain_seg --fold 1
jwzt train --config configs/train_cls_head.yaml --stage train_cls --fold 1
jwzt train --config configs/train_finetune.yaml --stage finetune_all --fold 1

# Predict
jwzt pred --config configs/infer_busi.yaml --model checkpoints/best_auc.ckpt --data dataset/Dataset_BUSI_with_GT --output outputs/busi_predictions

# Evaluate
jwzt eval --config configs/eval_busi.yaml --pred outputs/busi_predictions --data dataset/Dataset_BUSI_with_GT

# Audit dataset
jwzt audit-data --data-root dataset --output outputs/dataset_audit_summary.json

# Debug training
jwzt train --config configs/train_debug.yaml --experiment-name debug_run

Clinical Workbench UI

The project now includes a clinical auxiliary diagnosis workbench for breast ultrasound cases:

  • frontend source lives in web/
  • packaged static UI lives in src/JwzTumor/server/ui/
  • backend report generation lives in src/JwzTumor/server/report/
  • report API endpoint is POST /api/report

The frontend supports:

  • single-image and dual-image diagnosis modes
  • patient metadata and structured ultrasound field entry
  • asynchronous inference progress
  • editable structured report rendering
  • browser-local draft/history persistence
  • JSON export and PDF export

Frontend Development

Install frontend dependencies:

cd web
npm install

Configure the API target with either .env or shell environment variables:

cp .env.example .env

.env example:

VITE_JWZT_API_BASE_URL=http://127.0.0.1:8000

Terminal temporary variable example:

cd web
VITE_JWZT_API_BASE_URL=https://your-api.example.com npm run dev -- --host 0.0.0.0 --port 5173

Start the standalone frontend dev server:

cd web
npm run dev -- --host 0.0.0.0 --port 5173

The frontend resolves the backend address in this order:

  1. runtime config.js injected by the hosting server
  2. VITE_JWZT_API_BASE_URL
  3. fallback http://127.0.0.1:8000

Inference Server

Install server dependencies:

pip install -e ".[server]"

Start the inference API:

jwzt server \
  --model checkpoints/best_auc.ckpt \
  --config configs/infer_busi.yaml \
  --host 0.0.0.0 \
  --port 8000

Useful CLI environment variables are also supported, so system variables and one-shot terminal variables work without editing code:

export JWZT_MODEL=checkpoints/best_auc.ckpt
export JWZT_CONFIG=configs/infer_busi.yaml
export JWZT_HOST=0.0.0.0
export JWZT_PORT=8000

Or:

JWZT_MODEL=checkpoints/best_auc.ckpt JWZT_PORT=8000 jwzt server

UI Hosting Modes

Same-Port Hosting

Serve the packaged UI from the same FastAPI service and port:

jwzt server \
  --model checkpoints/best_auc.ckpt \
  --config configs/infer_busi.yaml \
  --with-ui \
  --host 0.0.0.0 \
  --port 8000

This serves:

  • API: http://127.0.0.1:8000/api/...
  • UI: http://127.0.0.1:8000/

Separate UI Port

Serve the API and UI on different ports:

jwzt server \
  --model checkpoints/best_auc.ckpt \
  --config configs/infer_busi.yaml \
  --with-ui \
  --host 0.0.0.0 \
  --port 8000 \
  --ui-host 0.0.0.0 \
  --ui-port 8080 \
  --ui-api-base-url http://127.0.0.1:8000

Equivalent environment variables:

export JWZT_UI_HOST=0.0.0.0
export JWZT_UI_PORT=8080
export JWZT_UI_API_BASE_URL=http://127.0.0.1:8000

If you already have an external built frontend directory, you can override the packaged UI:

jwzt server \
  --model checkpoints/best_auc.ckpt \
  --config configs/infer_busi.yaml \
  --with-ui \
  --ui-dir /absolute/path/to/web/dist

Runtime config.js

When the UI is served by jwzt server, the backend injects a runtime config.js file at /config.js:

window.__JWZT_CONFIG__ = { apiBaseUrl: "http://127.0.0.1:8000" };

This lets the same built frontend work in:

  • local standalone development
  • same-port packaged serving
  • separate-port packaged serving
  • reverse-proxy or public-domain deployments

Report API

Clinical report generation is exposed by:

POST /api/report

Supported report_mode values:

  • rule: deterministic local rule template
  • llm: editable sections generated by the configured LLM
  • hybrid: rule template with LLM refinement and rule fallback on failure

The frontend uses /api/report first and falls back to a local rule composer if report generation fails.

OpenAI-Compatible LLM Configuration

/api/report can use any OpenAI-Compatible chat completions provider. Configure it with environment variables:

export JWZT_REPORT_LLM_BASE_URL=https://your-openai-compatible.example.com/v1
export JWZT_REPORT_LLM_API_KEY=sk-...
export JWZT_REPORT_LLM_MODEL=gpt-4.1-mini

Optional tuning variables:

export JWZT_REPORT_LLM_TIMEOUT=60
export JWZT_REPORT_LLM_MAX_RETRIES=2
export JWZT_REPORT_LLM_TEMPERATURE=0.2

If these variables are absent, the report service stays in rule-only fallback mode for editable sections.

Rebuild Packaged UI

After changing the frontend, rebuild and copy the static bundle into the Python package:

./scripts/build_web_ui.sh

Training Strategy

Four-stage training:

  1. pretrain_pre: Train LABDG-Pre only (coarse localization, structure maps)
  2. pretrain_seg: Train DGBC-MTLNet segmentation (encoder + decoder)
  3. train_cls: Train MPTC-Head only (freeze encoder + preprocessing)
  4. finetune_all: End-to-end fine-tuning with all losses

Metrics

Classification: AUC, Accuracy, Sensitivity, Specificity, Precision, F1 Segmentation: Dice, IoU, HD95, Boundary-F1

Stargazers over time

Stargazers over time

License

Apache-2.0

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

jwztumor-1.0.10.tar.gz (429.1 kB view details)

Uploaded Source

Built Distribution

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

jwztumor-1.0.10-py3-none-any.whl (448.4 kB view details)

Uploaded Python 3

File details

Details for the file jwztumor-1.0.10.tar.gz.

File metadata

  • Download URL: jwztumor-1.0.10.tar.gz
  • Upload date:
  • Size: 429.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for jwztumor-1.0.10.tar.gz
Algorithm Hash digest
SHA256 141b580aec260501603521751f5940da7998dbad10b84cd4d7ee2ae9239719d4
MD5 56c9d1b0145acc6d49fb8ac2fd5a92e1
BLAKE2b-256 8269853b95a575bd4176cf8cfebef6134f4854c580582594ec9fc1c707e1c4cb

See more details on using hashes here.

File details

Details for the file jwztumor-1.0.10-py3-none-any.whl.

File metadata

  • Download URL: jwztumor-1.0.10-py3-none-any.whl
  • Upload date:
  • Size: 448.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for jwztumor-1.0.10-py3-none-any.whl
Algorithm Hash digest
SHA256 d356ea326558b878a211b84b05fccea5d017482533b14347d9ab1818c874c0a1
MD5 3e2bd2d1f3b0f5a169b3bdb0d64e7498
BLAKE2b-256 d0d3bbf09e6c3ded9cb954d017b7ff4b81b2ddc6b33fe8938003755e9fef7de7

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