A three-stage interpretable AI system for breast cancer detection, fusing clinical BI-RADS features with deep learning on CBIS-DDSM mammography.
| Stage | Method | AUC-ROC | Sensitivity | Specificity |
|---|---|---|---|---|
| Stage 1 | Gradient Boosting — 11 clinical features | 0.8678 | 72.1% | 83.2% |
| Stage 2 | EfficientNet-B4 + TTA ×5 | 0.8294 | 87.3% | 63.6% |
| Stage 3 | Late-Fusion (512-dim CNN + clinical) | 0.8825 | 78.6% | 82.0% |
| Stage 1+ | Multi-Dataset GB (CBIS-DDSM + VinDr-Mammo, 18,864 cases) | 0.9925 | — | — |
| Stage 5 | Calibrated Ensemble (ECE = 0.052, Brier = 0.146) | 0.8722 | — | — |
| Sub-class | BENIGN risk stratification | 0.9729 | 97.2% | 78.9% |
- Dual Explainability — SHAP (clinical stage) + GradCAM (image stage) shown simultaneously
- Late-Fusion Architecture — 512-dim CNN embeddings + 11 clinical features → AUC 0.8825
- BENIGN Sub-Class Stratification — predicts biopsy need from benign cases (AUC 0.9729)
- Cross-Dataset Generalisation — zero-shot transfer protocol to VinDr-Mammo
CBIS-DDSM CSV ──► Stage 1: Gradient Boosting ──► AUC 0.8678 + SHAP explanations
│
CBIS-DDSM DICOM ──► Stage 2: EfficientNet-B4 ──► AUC 0.8294 + GradCAM heatmaps
│
Stage 3: Late Fusion ──────────► AUC 0.8825 (best overall)
[11 clinical + 512 CNN + 1 GB_prob = 524-dim → GB meta-learner]
MammoAI/
├── app.py Streamlit web application
├── requirements.txt
│
├── src/
│ ├── cancer_detection.py Stage 1: full ML pipeline + plots
│ ├── save_model.py Train & serialize GB model
│ ├── shap_analysis.py SHAP explainability (Contribution 1)
│ ├── benign_subclass.py BENIGN sub-class analysis (Contribution 3)
│ ├── cross_dataset.py VinDr-Mammo cross-dataset study (Contribution 4)
│ ├── train_multi_dataset.py Stage 1+ multi-dataset training (CBIS + VinDr)
│ └── calibration_ensemble.py Stage 5 calibrated ensemble with uncertainty
│
├── stage2_cnn/
│ ├── config.py All hyperparameters
│ ├── dataset.py DICOM loader + CLAHE preprocessing
│ ├── model.py EfficientNet-B4 architecture
│ ├── train.py Two-phase training + resume
│ ├── evaluate.py TTA evaluation + GradCAM
│ ├── predict.py Single-image inference
│ └── fusion.py Late-fusion pipeline (Contribution 2)
│
├── models/
│ ├── gb_model.pkl Stage 1 Gradient Boosting (CBIS-DDSM)
│ ├── gb_multi_dataset.pkl Stage 1+ GB (CBIS-DDSM + VinDr-Mammo, AUC 0.9925)
│ ├── gb_benign_subclass.pkl BENIGN sub-class stratifier (AUC 0.9729)
│ ├── mammo_ensemble.pkl Stage 5 calibrated ensemble (ECE 0.052)
│ └── ensemble_metrics.json Calibration + disagreement metrics
│
├── results/
│ ├── shap/ SHAP plots (5 figures)
│ ├── benign_subclass/ Sub-class analysis plots
│ ├── cross_dataset/ Domain shift analysis
│ └── stage2_cnn/results/ CNN evaluation + GradCAM + fusion plots
│
├── paper/
│ ├── mammoai_paper.md Full research paper (14 references)
│ ├── mammoai_submission.md Submission-formatted manuscript
│ ├── MammoAI_Manuscript.docx Word export for journal submission
│ ├── Cover_Letter.docx Journal cover letter
│ ├── Conflict_of_Interest.docx CoI statement
│ └── figures/ Publication-ready plots (PNG)
│
└── data/csv/ CBIS-DDSM CSV annotations (lightweight)
NOTE: Raw DICOM images (~152 GB) are NOT committed — download from TCIA
No dataset download needed — 7 ready-made demo mammograms ship with the repo.
git clone https://github.com/aliaht99/MammoAI.git
cd MammoAI
pip install -r requirements.txt
./run.sh # opens the MammoDoctor app at http://localhost:8501Then upload any image from demo_images/ (e.g. 1_CLEAR_MALIGNANT_spiculated_mass.png)
and read off the prediction. demo_images/DEMO_CHEATSHEET.txt lists the expected
result and clinical-form values for each of the 7 scenarios.
Note: the pre-trained clinical + ensemble models are bundled, so Stage 1, Sub-class and the calibrated Ensemble work out of the box. The 74 MB CNN checkpoint is not committed — the app runs fine without it and simply marks Stage 2 / GradCAM as unavailable until you train it (step 7 below).
Two apps are included:
| Command | App | Best for |
|---|---|---|
./run.sh |
mammo_doctor.py |
Full clinician-facing platform (5 tabs, uncertainty, GradCAM, PDF report) |
./run.sh app |
app.py |
Lightweight 3-tab demo |
# 1. Install dependencies
pip install -r requirements.txt
# 2. Download CBIS-DDSM from TCIA (free account required)
# https://doi.org/10.7937/K9/TCIA.2016.7O02S9CY
# 3. Run Stage 1 (no images needed — CSV only)
python src/cancer_detection.py
# 4. Run SHAP explainability
python src/shap_analysis.py
# 5. Run BENIGN sub-class analysis
python src/benign_subclass.py
# 6. Train Stage 2 CNN (requires DICOM images + GPU/MPS + PyTorch)
pip install -r requirements-cnn.txt
cd stage2_cnn && python train.py
# 7. Evaluate Stage 2 with TTA
python evaluate.py
# 8. Run late-fusion (Stage 3)
python fusion.py
# 9. Launch web app
cd .. && ./run.shMammoAI is a research and educational project. It is not a medical device, has not been cleared or approved by any regulator (FDA, MHRA, CE, etc.), and must not be used for clinical diagnosis, screening decisions, or patient care. All outputs are experimental and must never replace a qualified radiologist. Do not upload identifiable patient data. Use is entirely at your own risk under the MIT License.
| Hyperparameter | Value |
|---|---|
| Backbone | EfficientNet-B4 (ImageNet pretrained) |
| Image size | 512 × 512 |
| Batch size | 8 |
| Phase 1 — Warmup | 5 epochs, LR=1e-3, backbone frozen |
| Phase 2 — Fine-tune | up to 25 epochs, LR=1e-4, cosine annealing |
| Early stopping patience | 7 epochs |
| Label smoothing | ε = 0.05 |
| Best checkpoint | Epoch 24, val AUC = 0.8156 |
| TTA passes | 5 (original + H-flip + V-flip + ±10° rotation) |
| Optimal threshold | 0.39 |
| Hardware | Apple M3 MPS |
Resume interrupted training:
cd stage2_cnn && python train.py --resume| Feature | Mean |SHAP| | |---|---| | BI-RADS Assessment | 1.29 | | Morphology Risk | 0.85 | | Mass Margin Risk | 0.33 | | Subtlety | 0.26 | | Calc Type Risk | 0.22 |
# 1. Get free credentialed access at physionet.org
# 2. Complete CITI training + sign data use agreement
# 3. Download CSVs only (~2 MB):
# curl -u YOUR_USERNAME https://physionet.org/files/vindr-mammo/1.0.0/breast-level_annotations.csv \
# -o vindr-mammo/breast-level_annotations.csv
# 4. Run cross-dataset study:
python src/cross_dataset.py --vindr /path/to/vindr-mammo/1.0.0@article{hamza2026mammoai,
author = {Hamza, Ali},
title = {MammoAI: A Multi-Modal Interpretable Framework for Breast Cancer
Detection — Fusing Clinical Features with Deep Learning on CBIS-DDSM},
journal = {Computers in Biology and Medicine},
year = {2026},
note = {Under review},
url = {https://github.com/aliaht99/MammoAI}
}Dataset:
@article{lee2017cbisddsm,
author = {Lee, Rebecca Sawyer and Gimenez, Francisco and Hoogi, Assaf and Rubin, Daniel},
title = {Curated Breast Imaging Subset of DDSM (CBIS-DDSM)},
journal = {The Cancer Imaging Archive},
year = {2017},
doi = {10.7937/K9/TCIA.2016.7O02S9CY}
}MIT — see LICENSE
Ali Hamza — MSc Advanced Engineering Management, Leeds Beckett University
alihamza.aht.99@gmail.com | github.com/aliaht99
- Dataset: TCIA CBIS-DDSM
- EfficientNet: Tan & Le, ICML 2019
- SHAP: Lundberg & Lee, NeurIPS 2017
- GradCAM: Selvaraju et al., ICCV 2017