Diabetic Retinopathy Grading β EfficientNetV2-L (v26)
5-fold OOF ensemble of EfficientNet-V2-L trained at 384px on the standard 1st-place Kaggle APTOS-2019 recipe (SmoothL1 regression, GeM pool, EMA 0.9999, 3-phase progressive unfreeze, threshold optimisation). Stage-2 fine-tuned on IDRiD for clinical generalisation.
Metrics
| Split | QWK |
|---|---|
| OOF (APTOS, full coverage) | 0.8201 |
| Messidor-2 (external) | 0.3415 |
See pipeline_metadata.json for full per-class P/R/F1, calibration, and ensemble config.
Datasets used (training)
- APTOS 2019 (5-fold OOF target)
- EyePACS / DR-2015 (auxiliary train)
- DDR (auxiliary train)
- IDRiD (Stage-2 fine-tune)
- Messidor-2 (held out for external validation)
Files
models/effv2l_s42_best.ptβ final regression checkpointfundus_validator.ptβ MobileNetV3-Small binary classifier (used to gate non-fundus inputs)thresholds.jsonβ 4 cut-points for converting score β gradecalibration.jsonβ Brier-optimal Ο for soft probabilitiespipeline_metadata.jsonβ full training config + metrics
Quick inference
import torch, json, cv2, numpy as np
import torch.nn as nn, torch.nn.functional as F
from torch.nn.parameter import Parameter
import timm
class GeM(nn.Module):
def __init__(self, p=3.0, eps=1e-6):
super().__init__()
self.p = Parameter(torch.ones(1)*p); self.eps = eps
def forward(self, x):
return F.avg_pool2d(x.clamp(min=self.eps).pow(self.p),
(x.size(-2), x.size(-1))).pow(1.0/self.p)
class DRModel(nn.Module):
def __init__(self, backbone, drop=0.5):
super().__init__()
self.backbone = timm.create_model(backbone, pretrained=False, num_classes=0, global_pool='')
feat = self.backbone.num_features
self.pool = GeM()
self.head = nn.Sequential(
nn.Flatten(), nn.Linear(feat, 256), nn.BatchNorm1d(256),
nn.ReLU(True), nn.Dropout(drop), nn.Linear(256, 1))
def forward(self, x):
f = self.backbone(x)
p = f.unsqueeze(-1).unsqueeze(-1) if f.dim()==2 else self.pool(f)
return self.head(p).squeeze(-1)
ckpt = torch.load('models/effv2l_s42_best.pt', map_location='cpu', weights_only=False)
m = DRModel(ckpt['backbone']); m.load_state_dict(ckpt['model'], strict=False); m.eval()
# β¦ see README in the bundle zip for the full preprocess + grade-conversion code.
- Downloads last month
- -