--- license: other license_name: research-use-only license_link: https://github.com/adarshcod30/Diabetic-Retinopathy-Detection/blob/main/MODEL_CARD.md tags: - diabetic-retinopathy - medical-imaging - fundus - explainable-ai - efficientnet - pytorch - onnx library_name: pytorch pipeline_tag: image-classification --- # drdetect: Diabetic Retinopathy Screening Model **Research prototype. NOT a medical device. NOT a substitute for clinical judgement.** EfficientNet-B0 (regression-loss ordinal head) for 5-class ICDR diabetic retinopathy grading, trained on APTOS 2019 and evaluated once, honestly, on a locked external test set (Messidor-2 + IDRiD). Full code, every experiment, and the complete evidence trail: [github.com/adarshcod30/Diabetic-Retinopathy-Detection](https://github.com/adarshcod30/Diabetic-Retinopathy-Detection). ## Why this checkpoint This is **not** the checkpoint with the best internal-validation accuracy — a plain cross-entropy baseline scored higher there. It is the checkpoint that won a **pre-registered, one-time external evaluation** on data neither model was tuned on: referable-DR AUC 0.9242 vs. 0.8878 for the CE baseline (DeLong test, p=6.1×10⁻¹⁰). See the full write-up: [`docs/22_PHASE8_VALIDATION_RESULTS.md`](https://github.com/adarshcod30/Diabetic-Retinopathy-Detection/blob/main/docs/22_PHASE8_VALIDATION_RESULTS.md). ## Files - `best.ckpt` — PyTorch Lightning checkpoint (EfficientNet-B0, regression head, 512×512 input). - `efficientnet_b0_regression_512px.onnx` — ONNX export, parity-verified against the PyTorch module (max abs diff 2.4×10⁻⁷). ## Headline results (locked external test, run once) | | QWK | Sensitivity | Specificity | Referable AUC | |---|---:|---:|---:|---:| | This model | 0.6995 | 0.441 | 0.976 | 0.9242 | **Read the limitation, not just the AUC**: referable-DR sensitivity is 44.1% against a >=90% target — well below every published comparator. This is diagnosed (not just disclosed) as a threshold-transfer/calibration failure, not a pure discrimination failure: the frozen operating threshold from internal validation does not transfer to this external population, even though the model's ranking ability (AUC) held up in a range comparable to a cited external-validation drop in the literature. **Any real use of this model's binary referable/non-referable output requires fitting a new threshold on a local calibration set first.** Full detail: [`MODEL_CARD.md`](https://github.com/adarshcod30/Diabetic-Retinopathy-Detection/blob/main/MODEL_CARD.md). ## Usage ```python import torch from drdetect.grading.model import build_model # from the GitHub repo's src/ model = build_model("efficientnet_b0", num_outputs=1, pretrained=False, freeze_bn=True) ckpt = torch.load("best.ckpt", map_location="cpu", weights_only=False) state = ckpt.get("state_dict", ckpt) state = {k.removeprefix("model."): v for k, v in state.items() if k.startswith("model.")} model.load_state_dict(state) model.eval() ``` Or with the repo's own pipeline (handles preprocessing, quality gating, and decoding): ```python from drdetect.serve.pipeline import load_grader, run_pipeline model = load_grader("best.ckpt", backbone="efficientnet_b0", loss_name="regression", device="cpu") result = run_pipeline(image_rgb, model, loss_name="regression", size=512, device="cpu") ``` ## License **Research use only.** Derived from training data under mixed licenses that restrict redistribution (APTOS/Kaggle competition rules, Messidor-2's ADCIS terms) — see [`DATASET_CARD.md`](https://github.com/adarshcod30/Diabetic-Retinopathy-Detection/blob/main/DATASET_CARD.md). Not licensed for any clinical, diagnostic, or commercial product.