Transfer Learning-based blood smear classification using EfficientNetB3, Flask, and Grad-CAM
leukemia-detection/
├── backend/
│ ├── app.py ← Flask API (predict, health endpoints)
│ └── requirements.txt ← Python dependencies
├── frontend/
│ └── index.html ← Main UI page
├── model/
│ └── leukemia_model.keras ← Place your trained model here
├── static/
│ ├── css/style.css ← Dark medical theme stylesheet
│ └── js/app.js ← Frontend JS (upload, predict, render)
└── README.md
- Python 3.10+
- pip
cd backend
pip install -r requirements.txtNote: If you don't have a GPU, replace
tensorflowwithtensorflow-cpuin requirements.txt.
Copy your trained Keras model to:
model/leukemia_model.keras
If no model is present, the app runs in Demo Mode — predictions are simulated based on image statistics. This lets you test the full UI and API pipeline without a trained model.
To train a model: Use the provided leukemia_detection.py training script. After training, the best model is automatically saved as leukemia_model.keras. Move it to the model/ folder.
cd backend
python app.pyAPI will be available at http://localhost:5000
Open frontend/index.html in any modern browser, or serve it with a simple HTTP server for proper relative paths:
# From the project root:
python -m http.server 8080
# Then open: http://localhost:8080/frontend/index.htmlAccepts a multipart form upload with key image.
Request:
curl -X POST http://localhost:5000/predict \
-F "image=@blood_smear.jpg"Response:
{
"prediction": "Leukemia",
"confidence": 0.9712,
"roc_curve": "<base64-encoded PNG>",
"gradcam": "<base64-encoded PNG>",
"demo_mode": false
}{
"status": "ok",
"tf_available": true,
"model_loaded": true
}This project is designed for the ALL (Acute Lymphoblastic Leukemia) Image Database available on Kaggle:
Expected folder structure:
dataset/
Normal/
img001.jpg
img002.jpg
...
Leukemia/
img001.jpg
img002.jpg
...
- Push the
backend/folder to a GitHub repository. - Go to render.com → New Web Service → connect your repo.
- Set:
- Build Command:
pip install -r requirements.txt - Start Command:
gunicorn app:app --bind 0.0.0.0:$PORT - Environment: Python 3.10
- Build Command:
- Upload your model file as a Render persistent disk (or use a cloud bucket URL).
- Update
API_BASEinstatic/js/app.jsto your Render URL. - Deploy
frontend/to Vercel or Netlify as a static site.
- Push project to GitHub.
- New Railway project → Deploy from repo.
- Set
PORTenvironment variable to5000. - Railway auto-detects Python and installs requirements.
# Dockerfile (place in backend/)
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["gunicorn", "app:app", "--bind", "0.0.0.0:5000", "--workers", "2"]docker build -t hematoscan-api ./backend
docker run -p 5000:5000 hematoscan-api| Variable | Default | Description |
|---|---|---|
PORT |
5000 |
Port the Flask server listens on |
FLASK_DEBUG |
false |
Enable debug mode (true/false) |
Input (224×224×3)
↓
EfficientNetB3 (pretrained ImageNet, top 30 layers fine-tuned)
↓
GlobalAveragePooling2D
↓
BatchNormalization
↓
Dense(256, ReLU) → Dropout(0.5)
↓
Dense(64, ReLU) → Dropout(0.3)
↓
Dense(1, Sigmoid) ← Binary output: Normal (0) / Leukemia (1)
| Metric | Target |
|---|---|
| Accuracy | ≥ 95% |
| Recall | ≥ 96% |
| Precision | ≥ 93% |
| ROC-AUC | 0.88–0.95 |
This tool is intended for research and educational purposes only. It is not certified for clinical use and should not replace diagnosis by a licensed haematologist or pathologist.