Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

QuadCare

One AI system that screens four diseases and returns plain-language clinical advice

Python PyTorch License Domain

Reference implementation for Smarter Health for Everyone with an AI System That Detects Four Diseases and Gives Easy-to-Understand Clinical Advice — Frontiers in Computer Science and Artificial Intelligence 4(4), 116-137, 2025.


The problem

Four separate screening models mean four training runs, four sets of weights to ship, and four small datasets each learning low-level image features from scratch. In a low-resource deployment it also means four models competing for the same few gigabytes of RAM.

But there is a subtler problem that most multi-task medical models get wrong: they merge the tasks into one flat label space. Tuberculosis and melanoma are not alternatives to each other, and a softmax that puts them in competition is modelling a choice no clinician ever makes.

Approach

Shared encoder, separate heads, separate calibration.

The encoder is a residual network with squeeze-and-excitation blocks, trained across all four tasks. Each individual dataset is small; the shared representation sees all of them, and low-level features - tissue boundaries, texture irregularity, asymmetry - are largely task-independent.

What is deliberately not shared:

Component Shared? Why
Encoder Yes Low-level features transfer across all four tasks
Task head No Each task has its own class list and its own decision
Class space No Diseases are not mutually exclusive alternatives
Temperature No Joint training leaves each task differently calibrated

Per-task temperature scaling. A jointly trained network is not equally calibrated on every task, and a screening threshold applied to an uncalibrated probability means nothing. Each head owns a learned temperature, fitted on validation data with the encoder frozen.

The advice layer is where the clinical value actually lands. A health worker handed pharyngitis: 0.87 still has to decide what to do. src/advice.py maps a calibrated result to an urgency band and a short, readable instruction.

Design notes

  • Urgency is not confidence. A confident negative and a confident positive carry different urgency, and a borderline result on a serious task outranks a confident result on a mild one. The mapping is explicit in TASK_RULES, not derived from the probability alone.
  • Below 55% confidence, nothing is asserted. The advice layer returns an INDETERMINATE band that says plainly that the test could not decide - and says so without implying either reassurance or alarm.
  • triage_batch() sorts by urgency. The point of screening at scale is deciding who gets seen first.
  • Reading level is kept deliberately low. Short sentences, no abbreviations, no Latin. Patients and non-specialist staff read this text.
  • Every message carries a disclaimer. This is a screening output, not a diagnosis, and the text says so every single time.

Architecture

Input (3, 224, 224)
   │
   ├─ Shared encoder ────────────────────────── 512ch
   │    Residual stages ×4, each with SE blocks
   │    64 -> 128 -> 256 -> 512
   │
   ├─ Global average pool
   │
   ├───────────┬───────────┬───────────┬──────────┐
   chest_xray  brain_mri   skin_lesion throat_photo
   head        head        head        head
   2 classes   4 classes   2 classes   2 classes
   + temp T1   + temp T2   + temp T3   + temp T4
   │           │           │           │
   └───────────┴─────┬─────┴───────────┘
                     │
              Advice layer
              urgency band + plain-language instruction
   11.8M parameters total, one encoder

Installation

git clone https://github.com/abedur/quadcare.git
cd quadcare
python -m venv .venv && source .venv/bin/activate    # Windows: .venv\Scripts\activate
pip install -r requirements.txt

Requires Python 3.10+ and PyTorch 2.1+. A GPU is recommended for training but not required — every module in this repository runs on CPU.

Data

No clinical imagery is redistributed here. Place a dataset in this layout:

data/
  train/<class_name>/*.png
  val/<class_name>/*.png
  test/<class_name>/*.png

Class order is derived by sorting directory names and is stored in the checkpoint, so evaluation cannot silently run against a different label order — src/evaluate.py raises rather than reporting corrupted metrics.

Usage

Verify the model builds and the shapes are right:

python src/model.py

Train:

python -m src.train --config configs/default.yaml --data-root data/

Evaluate a checkpoint on the held-out test split:

python -m src.evaluate --checkpoint runs/latest/best.pth --data-root data/

Override any config value from the command line:

python -m src.train --epochs 40 --batch-size 16 --lr 1e-4 --output runs/exp2

Run all four heads on one image when the modality is unknown:

from src.model import QuadCare
model = QuadCare()
for task, logits in model.forward_all(images).items():
    print(task, logits.shape)

Generate patient-facing advice from a calibrated result:

from src.advice import build_advice
advice = build_advice("chest_xray", "tuberculosis", 0.93)
print(advice.render())

Results

Reported results for this method are in the published paper cited below. This repository contains the implementation and the evaluation harness that produces those metrics; it does not ship precomputed numbers, so that anything reported from it is reproducible from a run you can inspect.

src/evaluate.py writes a metrics.json containing accuracy, macro precision / recall / F1, weighted F1, Cohen's kappa, AUROC, the full confusion matrix, and per-class figures. Pass --positive-class <name> to add sensitivity, specificity, PPV and NPV.

Repository layout

quadcare/
├── src/
│   ├── model.py        shared encoder and per-task heads
│   ├── dataset.py      dataset, transforms, class weighting
│   ├── train.py        training loop, early stopping, checkpointing
│   ├── evaluate.py     held-out evaluation and metric export
│   └── utils.py        seeding, metrics, latency and parameter accounting
│   └── advice.py       urgency banding and plain-language advice
├── configs/
│   └── default.yaml    the configuration used for the reported runs
├── tests/              shape and invariant checks
└── requirements.txt

Citation

@article{rahman2025quadcare,
  title   = {Smarter Health for Everyone with an AI System That Detects Four Diseases and Gives Easy-to-Understand Clinical Advice},
  author  = {M. A. Hossain and M. A. Rahman and M. S. Hossain and K. C. Shekhor},
  journal = {Frontiers in Computer Science and Artificial Intelligence 4(4)},
  year    = {2025}
}

Author

Md Abedur Rahman — Second author on this work. GitHub · ORCID · LinkedIn

License

MIT — see LICENSE.

Released for research and educational use. This is not a medical device and has not been evaluated by any regulatory body. It must not be used to make clinical decisions about real patients.

About

QuadCare - One AI system that screens four diseases and returns plain-language clinical advice

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages