Image Classification
timm
PyTorch
medical-imaging
ophthalmology
fundus
retina
multi-label-classification
dinov2
lora
efficientnetv2
retfound
Instructions to use TheodoreCousin/2-Net with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- timm
How to use TheodoreCousin/2-Net with timm:
import timm model = timm.create_model("hf-hub:TheodoreCousin/2-Net", pretrained=True) - Notebooks
- Google Colab
- Kaggle
Commit ·
847a28a
1
Parent(s): 778fb04
model card
Browse files
README.md
CHANGED
|
@@ -1,3 +1,143 @@
|
|
| 1 |
---
|
| 2 |
license: cc-by-nc-4.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
license: cc-by-nc-4.0
|
| 3 |
+
pipeline_tag: image-classification
|
| 4 |
+
tags:
|
| 5 |
+
- medical-imaging
|
| 6 |
+
- ophthalmology
|
| 7 |
+
- fundus
|
| 8 |
+
- retina
|
| 9 |
+
- multi-label-classification
|
| 10 |
+
- pytorch
|
| 11 |
+
- timm
|
| 12 |
+
- dinov2
|
| 13 |
+
- lora
|
| 14 |
+
- efficientnetv2
|
| 15 |
+
- retfound
|
| 16 |
---
|
| 17 |
+
|
| 18 |
+
# 2-Net: a two-network ensemble for multi-label fundus classification
|
| 19 |
+
|
| 20 |
+
Trained weights for the paper **"A Two-Network Ensemble for Multi-Label Fundus Classification"**
|
| 21 |
+
by Théodore Cousin¹, Coralie Hemptinne², Sébastien Jodogne¹
|
| 22 |
+
(¹ ICTEAM, UCLouvain, Louvain-la-Neuve, Belgium; ² Cliniques Universitaires Saint-Luc, Brussels, Belgium).
|
| 23 |
+
|
| 24 |
+
Code: <https://github.com/TheodoreCouz/2-Net>
|
| 25 |
+
|
| 26 |
+
The 2-Net detects retinal conditions from a colour fundus photograph as a multi-label problem.
|
| 27 |
+
It combines two networks that fail differently: a general-purpose DINOv2 ViT-B/14 adapted with
|
| 28 |
+
LoRA, and an EfficientNetV2-L that sees the image at 896 px to capture fine-grained detail.
|
| 29 |
+
Each network is calibrated per class on validation data, and the two are fused by a geometric
|
| 30 |
+
mean of their probabilities. The 2-Net performs on par with the 30-member winner of the RIADD
|
| 31 |
+
challenge, with 4.5 times fewer parameters and a CPU inference time of 4.4 s instead of 77.5 s
|
| 32 |
+
per image.
|
| 33 |
+
|
| 34 |
+
## Files
|
| 35 |
+
|
| 36 |
+
One checkpoint per network and dataset, all trained with seed 42 (one of the five seeds of the paper).
|
| 37 |
+
|
| 38 |
+
| File | Network | Input | Parameters |
|
| 39 |
+
|---|---|---|---|
|
| 40 |
+
| `DINOv2-LoRA/{MuReD,RFMiD}/DINOv2-LoRA-<Dataset>.pt` | DINOv2 ViT-B/14, LoRA rank 16, token-pooling head | 518 × 518 | 87.8 M (1.2 M trained) |
|
| 41 |
+
| `EfficientNetV2-L/{MuReD,RFMiD}/EfficientNetV2-L-<Dataset>.pt` | EfficientNetV2-L, linear head | 896 × 896 | 117.3 M |
|
| 42 |
+
| `RETFound/{MuReD,RFMiD}/RETFound-<Dataset>.pt` | RETFound ViT-L/16, fully fine-tuned, token-pooling head | 384 × 384 | ≈ 304 M |
|
| 43 |
+
| `calibration/2-Net-<Dataset>.json` | 2-Net calibration: per-class Platt parameters of both members and decision thresholds, fitted on the validation split | | |
|
| 44 |
+
|
| 45 |
+
- **2-Net** = DINOv2-LoRA + EfficientNetV2-L (the main system of the paper).
|
| 46 |
+
- **2-Net (RETFound)** = RETFound + EfficientNetV2-L, the variant used to compare against
|
| 47 |
+
retina-specific pretraining.
|
| 48 |
+
- The ViT checkpoints are PyTorch `state_dict`s. The EfficientNetV2-L checkpoints are dicts with
|
| 49 |
+
the `state_dict` and its metadata (architecture, class names, seed, …). All of them are
|
| 50 |
+
loaded with the code of the repository above.
|
| 51 |
+
|
| 52 |
+
## Outputs
|
| 53 |
+
|
| 54 |
+
One probability per class, in this order:
|
| 55 |
+
|
| 56 |
+
- **MuReD (20)**: DR, NORMAL, MH, ODC, TSLN, ARMD, DN, MYA, BRVO, ODP, CRVO, CNV, RS, ODE, LS,
|
| 57 |
+
CSR, HTR, ASR, CRS, OTHER.
|
| 58 |
+
- **RFMiD (29)**: Disease_Risk, DR, ARMD, MH, DN, MYA, BRVO, TSLN, ERM, LS, MS, CSR, ODC, CRVO,
|
| 59 |
+
TV, AH, ODP, ODE, ST, AION, PT, RT, RS, CRS, EDN, RPEC, MHL, RP, OTHER (the 29 labels of the
|
| 60 |
+
RIADD challenge; OTHER groups the remaining 18 RFMiD labels).
|
| 61 |
+
|
| 62 |
+
## Training data
|
| 63 |
+
|
| 64 |
+
- **MuReD** (2,208 images, 20 labels). No official split: we use a class-stratified split of
|
| 65 |
+
1,504 / 260 / 444 images (train / validation / test), provided in the code repository.
|
| 66 |
+
- **RFMiD** (3,200 images). Official split of 1,920 / 640 / 640 images, 29 labels.
|
| 67 |
+
|
| 68 |
+
Images are cropped to the fundus disc and enhanced with CLAHE. Training uses
|
| 69 |
+
oversampling of rare-class images, data augmentation (flips, small rotations, photometric
|
| 70 |
+
changes, cutout, random crops) and MixUp / CutMix. DINOv2-LoRA and RETFound use a
|
| 71 |
+
distribution-balanced loss, EfficientNetV2-L an asymmetric loss.
|
| 72 |
+
|
| 73 |
+
## Results
|
| 74 |
+
|
| 75 |
+
Test set, macro F1 / macro mAP / Recall@n. Our models use per-class Platt calibration and
|
| 76 |
+
decision thresholds tuned on the validation split.
|
| 77 |
+
|
| 78 |
+
**These checkpoints (seed 42)**
|
| 79 |
+
|
| 80 |
+
| Model | F1 MuReD | F1 RFMiD | mAP MuReD | mAP RFMiD | R@n MuReD | R@n RFMiD |
|
| 81 |
+
|---|---|---|---|---|---|---|
|
| 82 |
+
| EfficientNetV2-L | .637 | .535 | .720 | .551 | .791 | .854 |
|
| 83 |
+
| RETFound, full fine-tuning | .621 | .481 | .683 | .534 | .764 | .864 |
|
| 84 |
+
| DINOv2, LoRA | .675 | .516 | .726 | .581 | .791 | .872 |
|
| 85 |
+
| 2-Net (RETFound) | .671 | .510 | .745 | .601 | .800 | .877 |
|
| 86 |
+
| **2-Net (DINOv2)** | **.706** | **.544** | **.747** | **.607** | **.804** | **.873** |
|
| 87 |
+
|
| 88 |
+
**Paper (mean ± 1 SD over five seeds)**
|
| 89 |
+
|
| 90 |
+
| Model | F1 MuReD | F1 RFMiD | mAP MuReD | mAP RFMiD | R@n MuReD | R@n RFMiD |
|
| 91 |
+
|---|---|---|---|---|---|---|
|
| 92 |
+
| EfficientNetV2-L | .629 ± .009 | .511 ± .031 | .704 ± .012 | .556 ± .010 | .779 ± .008 | .858 ± .006 |
|
| 93 |
+
| RETFound, full fine-tuning | .618 ± .015 | .489 ± .012 | .677 ± .012 | .546 ± .010 | .751 ± .020 | .866 ± .003 |
|
| 94 |
+
| DINOv2, LoRA | .655 ± .018 | .506 ± .030 | .711 ± .009 | .565 ± .012 | .792 ± .011 | .869 ± .003 |
|
| 95 |
+
| 2-Net (RETFound) | .658 ± .013 | .511 ± .003 | .730 ± .011 | .602 ± .010 | .799 ± .011 | .876 ± .001 |
|
| 96 |
+
| **2-Net (DINOv2)** | **.673 ± .020** | **.527 ± .012** | **.735 ± .008** | .589 ± .011 | **.806 ± .004** | .875 ± .003 |
|
| 97 |
+
|
| 98 |
+
Comparisons with C-Tran, RetExpert, RET-CLIP and the RIADD winner are in the paper.
|
| 99 |
+
|
| 100 |
+
## How to use
|
| 101 |
+
|
| 102 |
+
```bash
|
| 103 |
+
git clone https://github.com/TheodoreCouz/2-Net && cd 2-Net
|
| 104 |
+
pip install -r requirements.txt
|
| 105 |
+
hf download TheodoreCousin/2-Net --local-dir weights
|
| 106 |
+
|
| 107 |
+
python infer.py --dataset MURED --images path/to/images/ --out predictions.csv
|
| 108 |
+
```
|
| 109 |
+
|
| 110 |
+
`--dataset` selects the label set and the networks trained on it (`MURED` or `RFMiD`). Each
|
| 111 |
+
image goes through DINOv2-LoRA and EfficientNetV2-L; their probabilities are calibrated with
|
| 112 |
+
`calibration/2-Net-<Dataset>.json`, fused by a geometric mean and thresholded per class. The
|
| 113 |
+
CSV has one row per image with the probability of every class and the predicted labels.
|
| 114 |
+
Preprocessing (fundus crop, CLAHE, resizing) is done by the script. The code repository also
|
| 115 |
+
explains how to reproduce every result of the paper.
|
| 116 |
+
|
| 117 |
+
## Intended use and limitations
|
| 118 |
+
|
| 119 |
+
- **Research use only.** These models are not medical devices and have not been validated
|
| 120 |
+
in clinical practice. They must not be used for diagnosis.
|
| 121 |
+
- They were trained and evaluated on MuReD and RFMiD only; performance on other cameras,
|
| 122 |
+
populations or acquisition protocols is unknown, and no cross-dataset evaluation was done.
|
| 123 |
+
- Rare diseases remain hard: macro F1 on the rarest classes stays around 0.3.
|
| 124 |
+
- Calibration and thresholds are fitted on each dataset's validation split and do not transfer
|
| 125 |
+
as is to new data.
|
| 126 |
+
- The label sets mix pathological signs and diseases, and the models give probabilities
|
| 127 |
+
without an explanation of the evidence behind them.
|
| 128 |
+
|
| 129 |
+
## License
|
| 130 |
+
|
| 131 |
+
CC BY-NC 4.0 (non-commercial use). The RETFound checkpoints are fine-tuned from RETFound,
|
| 132 |
+
itself released under CC BY-NC 4.0. DINOv2-LoRA starts from Meta's DINOv2 and
|
| 133 |
+
EfficientNetV2-L from ImageNet weights distributed with `timm`.
|
| 134 |
+
|
| 135 |
+
## Citation
|
| 136 |
+
|
| 137 |
+
```bibtex
|
| 138 |
+
@misc{cousin2net,
|
| 139 |
+
title = {A Two-Network Ensemble for Multi-Label Fundus Classification},
|
| 140 |
+
author = {Cousin, Th{\'e}odore and Hemptinne, Coralie and Jodogne, S{\'e}bastien},
|
| 141 |
+
note = {Code: https://github.com/TheodoreCouz/2-Net}
|
| 142 |
+
}
|
| 143 |
+
```
|