TRACE: Trustworthy Retinal Contrastive Encoder
A frozen ResNet-50 encoder for colour fundus photos, trained without disease labels (MoCo v2 with retina-safe views and a camera-artifact simulator) on 22,500 public fundus photos, plus the small heads and trust layer built on it. Team div4maxxers (BMSIT Bengaluru), ZEISS India Campus Hackathon "Beyond Code 2026", Theme 2.
Code, full model card, data card and every result: https://github.com/nithinj25/zesis-contrastive-learning
Research use only. Not a medical device. The weights were trained on datasets whose terms are research-only or still to be verified (EyePACS, APTOS, RFMiD; see the data card). The code is MIT-licensed; these files are not.
Files
| File | What |
|---|---|
checkpoints/trace_v2/encoder.pt |
ResNet-50 backbone state_dict (torchvision, fc = Identity); output 2048-d, L2-normalised |
artifacts/trace_v2/finding_models.pt, findings.joblib |
20 calibrated finding detectors (disc edema, haemorrhage, drusen, β¦) |
artifacts/trace_v2/trust.joblib |
Temperature-scaled 7-class classifier, per-camera conformal thresholds, OOD thresholds |
artifacts/trace_v2/quality.joblib |
Photo-quality gate |
artifacts/trace_v2/bank.npz |
Rare-disease prototype bank |
artifacts/trace_v2/demo_bundle.joblib |
Demo index: feature vectors, ids and labels of public dataset photos (no images) |
The .joblib files are Python pickles: load them only from this repository.
Use
git clone https://github.com/nithinj25/zesis-contrastive-learning.git && cd zesis-contrastive-learning
pip install -r requirements.txt
huggingface-cli download higgsboson25/trace-retinal-encoder --local-dir . # puts checkpoints/ and artifacts/ in place
python -m demo.app # demo on http://127.0.0.1:7860
python -m encoder.embed --images <folder> --out features.npy # (N, 2048) features of a folder of photos
import cv2
from encoder.export import load_trace_encoder, preprocess
enc = load_trace_encoder("checkpoints/trace_v2/encoder.pt")
x = preprocess(cv2.cvtColor(cv2.imread("fundus.jpg"), cv2.COLOR_BGR2RGB)) # (3, 384, 384)
features = enc(x[None]) # (1, 2048)
Results (frozen encoder; details and intervals in the model card)
| Test | ImageNet R50 | Plain MoCo v2 | Supervised R50 | TRACE |
|---|---|---|---|---|
| RFMiD test, 18 labels, linear probe AUROC | 0.885 | 0.917 | 0.918 | 0.917 |
| Unseen camera (Kowa / Topcon OCT-2000 held out) | 0.867 / 0.796 | 0.903 / 0.809 | β | 0.921 / 0.858 |
| JSIEC-1000, 39 diseases, 5 photos each, top-1 | 0.536 | 0.611 | 0.571 | 0.628 |
| Stress test, error vs ImageNet (lower is better) | 1.00 | 0.72 | 0.74 | 0.67 |
The supervised baseline, fine-tuned on RFMiD's labels, beats TRACE on RFMiD's own diseases (0.941 with its own head) and on DR at a new hospital. TRACE's advantage is on diseases with few labels, on new cameras and on poor photos.