Skip to content

Repository files navigation

RetinaGuard

Diabetic Retinopathy Screening & Patient Management Platform

Copyright (c) 2024 Gaurav Singh Thakur, Niharika Raghunandan — All Rights Reserved. See LICENSE for usage restrictions.


Overview

I built RetinaGuard as a two-sided clinical web platform for automated diabetic retinopathy (DR) severity screening, longitudinal patient monitoring, and doctor–patient management. Patients upload retinal fundus images and track their eye health history; clinicians get a complete dashboard with high-risk alerts, severity trends across visits, and inline annotation tools. The five-level DR grading follows the International Clinical Diabetic Retinopathy Severity Scale.

The screening engine is an EfficientNet-B4 with Grad-CAM diagnostic focus mapping — when real weights are loaded it produces a colour overlay that highlights which retinal regions drove each severity grade, which I designed for clinical explainability rather than pure accuracy.


Features

Feature Description
5-Level DR Grading Classifies retinal images as No DR / Mild / Moderate / Severe / Proliferative
Diagnostic Focus Map Grad-CAM heatmap overlay identifying which retinal regions drive each severity grade
Patient Portal Secure login, profile, scan upload, full history, clinical advice per result
Doctor Portal Patient list, high-risk alerts, severity trend charts, inline notes per scan
Longitudinal Tracking Severity trend charts across all visits for every patient
Doctor–Patient Assignment Doctors are linked to specific patients; admins see all
Screening Confidence Confidence percentage and per-grade probability distribution for each result
Role-Based Access Three roles: patient, doctor, admin with separate views and permissions
Simulation Mode Full app runs without trained weights — placeholder results for demonstration
Public Landing Page Marketing-grade front page with feature overview and grading reference

Model

I used EfficientNet-B4 as the backbone, pretrained on ImageNet and fine-tuned end-to-end for five-class DR grading.

Architecture & Training

Component Detail
Backbone EfficientNet-B4 (transfer learning)
Input resolution 512 × 512 px
Preprocessing CLAHE contrast enhancement + augmentation pipeline
Explainability Gradient-weighted Class Activation Mapping (Grad-CAM)
Optimiser AdamW
Scheduler CosineAnnealingLR
Stopping Early stopping (patience 12) — best checkpoint by validation QWK
Training stopped at Epoch 39
Dataset APTOS 2019 (Kaggle Blindness Detection)

All hyperparameters live in ml/config.py. The full training script is ml/train.py and the Colab/Kaggle notebooks are in notebooks/.

Trained weights are distributed via the Releases page rather than committed to git (to keep the repo lightweight). Download retinoguard_best.pth and place it at backend/weights/retinoguard_best.pth — the app switches from Simulation Mode to real inference automatically on next restart.

If no checkpoint is present, the app runs in Simulation Mode (deterministic placeholder results) so the full UI is still usable. Simulated output carries no diagnostic validity.


Results

I trained on APTOS 2019 and evaluated on a stratified held-out test set of 367 fundus images the model never saw during training.

Overall

Metric Value
Accuracy 0.8174
Quadratic Weighted Kappa 0.8866
Macro AUC (one-vs-rest) 0.9389
Weighted F1 0.8128

I picked the best checkpoint by validation QWK — the metric the DR-grading community actually uses. My validation and test QWK land almost on top of each other (0.8832 vs 0.8866), which tells me the model is genuinely learning the disease rather than memorizing the training set. Training early-stopped at epoch 39.

Per-class performance

Grade Precision Recall F1 AUC Support
No DR 0.962 0.983 0.973 0.998 181
Mild DR 0.645 0.540 0.588 0.934 37
Moderate DR 0.741 0.800 0.769 0.940 100
Severe DR 0.389 0.368 0.378 0.896 19
Proliferative DR 0.600 0.500 0.545 0.927 30

The model is strongest on No DR and Moderate DR. Severe DR is the weakest class, but it only has 19 test samples — I'm leaving the number visible rather than hiding it. The honest story is more useful than a cherry-picked one.

Confusion matrix

Confusion matrix Confusion matrix (row-normalized)

ROC curves (one-vs-rest)

One-vs-rest ROC curves

The full write-up — methodology, exact train/val/test split, and how to reproduce everything — is in docs/RESULTS.md.


Technology Stack

Backend

Component Technology
Web framework Flask 3.0
Database ORM Flask-SQLAlchemy + SQLite
Authentication Flask-Login + Werkzeug password hashing
Image serving Flask static/upload routes

Frontend

Component Technology
UI framework Bootstrap 5.3
Icons Bootstrap Icons 1.11
Charts Chart.js 4.4
Fonts Inter (Google Fonts)

Project Structure

RetinaGuard/
│
├── ml/                          # Screening engine
│   ├── config.py                # All hyperparameters and class definitions
│   ├── model.py                 # EfficientNet-B4 architecture & loader
│   ├── preprocessing.py         # CLAHE + train/val transform pipelines
│   ├── predict.py               # Inference engine + Grad-CAM overlay
│   ├── train.py                 # Full training script with early stopping
│   └── evaluate.py              # Held-out evaluation & metrics export
│
├── backend/                     # Flask application
│   ├── app.py                   # Application factory (blueprint registration)
│   ├── config.py                # Flask config classes (dev / prod)
│   ├── database.py              # SQLAlchemy + LoginManager instances
│   ├── models/
│   │   ├── user.py              # Patient/Doctor/Admin user model
│   │   └── scan.py              # Scan result & report model
│   └── routes/
│       ├── auth.py              # Login, register, logout, landing page
│       ├── patients.py          # Patient profile view & edit
│       ├── scans.py             # Upload, inference, history, delete
│       ├── dashboard.py         # Patient dashboard stats & trend API
│       └── doctor.py            # Doctor portal — patient list, detail, notes
│
├── frontend/
│   ├── templates/               # Jinja2 HTML templates
│   └── static/
│       ├── css/style.css
│       └── js/
│           ├── main.js
│           ├── scan.js
│           └── charts.js
│
├── notebooks/                   # Training notebooks (Colab & Kaggle)
│
├── docs/
│   ├── RESULTS.md               # Full evaluation write-up
│   └── results/                 # Confusion matrices, ROC curves, metrics JSON
│
├── tests/                       # Pytest suite
│   ├── conftest.py
│   ├── test_auth.py
│   ├── test_scans.py
│   └── test_predict.py
│
├── uploads/                     # Runtime image store — gitignored
├── backend/weights/             # Model checkpoint — gitignored
│   └── retinoguard_best.pth     # Download from Releases and place here
│
├── .env.example                 # Environment variable template
├── run.py                       # Application entry point
├── setup_db.py                  # Database initialisation & demo seed
├── requirements.txt             # Web app dependencies
├── requirements-ml.txt          # ML training dependencies
└── LICENSE

Installation & Setup

Prerequisites

  • Python 3.10 or higher
  • pip
  • (Optional) CUDA-compatible GPU for faster inference

Step 1 — Clone

git clone https://github.com/Gaurav-0704/RetinaGuard.git
cd RetinaGuard

Step 2 — Install dependencies

pip install -r requirements.txt

PyTorch note: installation varies by platform and CUDA version. Visit pytorch.org for the right command.

Step 3 — Configure environment

cp .env.example .env

At minimum, set a SECRET_KEY before running in any shared environment:

python -c "import secrets; print(secrets.token_hex(32))"

Add the output to your .env file. If SECRET_KEY is not set, the app generates an ephemeral key and logs a warning — sessions won't survive restarts, which is fine for local dev but not for deployment.

Step 4 — Initialise the database

# Create tables only
python setup_db.py

# Create tables + demo accounts (recommended for first run)
python setup_db.py --demo

Demo accounts:

Role Email Password
Patient demo@retinoguard.com demo1234
Doctor admin@retinoguard.com admin1234

The database (retinoguard.db) is created automatically in the project root. run.py also calls db.create_all() on startup, so the app is safe to launch without running setup_db.py first — you just won't have demo data.

Step 5 — (Optional) Add trained weights

Download retinoguard_best.pth from the Releases page and place it at:

backend/weights/retinoguard_best.pth

The app detects the file at startup and switches to live inference automatically.

Step 6 — Run

python run.py

Open http://127.0.0.1:5000 in your browser.


Running the Tests

pip install pytest
pytest tests/ -v

The test suite runs against an in-memory SQLite database with mocked inference — no GPU, no trained weights, no uploaded images needed.


Training the Screening Engine

pip install -r requirements-ml.txt

python -m ml.train \
  --images_dir path/to/images \
  --csv_path   path/to/labels.csv

CSV format:

id_code,diagnosis
abc123,0
def456,2

diagnosis is an integer 0–4 (DR severity grade). The best checkpoint saves automatically to backend/weights/retinoguard_best.pth.


DR Severity Grading Scale

Grade Name Clinical Description
0 No DR No visible signs. Annual screening recommended.
1 Mild DR Microaneurysms only. Revisit in 9–12 months.
2 Moderate DR More than microaneurysms but less than Severe. Ophthalmologist referral; revisit in 6 months.
3 Severe DR Extensive haemorrhages, venous beading. Urgent specialist referral.
4 Proliferative DR Neovascularisation present. Immediate ophthalmic intervention needed.

Environment Variables

Variable Default Description
SECRET_KEY ephemeral (warns at startup) Flask session secret — set this before deploying
DATABASE_URL sqlite:///retinoguard.db SQLAlchemy connection string

Medical Disclaimer

RetinaGuard is a screening aid developed for educational and portfolio purposes. It is not a certified medical device and must not be used as a substitute for professional ophthalmic examination and diagnosis. All results must be reviewed and confirmed by a qualified healthcare professional. The authors accept no liability for clinical decisions based on this software.


License & Copyright

This software is proprietary. Viewing is permitted; copying, distribution, modification, and commercial use are strictly prohibited without explicit written permission from both authors. See LICENSE for the full terms.


Authors

I built RetinaGuard as an extension of a diabetic retinopathy detection system Niharika and I developed together during our undergraduate research. This platform takes that shared academic foundation and extends it into a full-stack clinical screening application.

Name Role
🔬 Gaurav Singh Thakur Co-author · Full-stack development, screening engine, platform architecture
🔬 Niharika Raghunandan Co-author · Original DR research, academic foundation, clinical knowledge

GitHub: github.com/Gaurav-0704


Copyright (c) 2024 Gaurav Singh Thakur, Niharika Raghunandan. All Rights Reserved.

About

Full-stack DR screening platform — EfficientNet-B4 + Grad-CAM, dual patient/clinician portals. Built on my ISSN 2321-2152 publication.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages