vit-oct-wamd / README.md
kavin-aravindhan's picture
Upload README.md with huggingface_hub
ecbd081 verified
|
Raw
History Blame Contribute Delete
5.25 kB
---
license: mit
base_model: google/siglip-so400m-patch14-384
tags:
- medical-imaging
- ophthalmology
- oct
- age-related-macular-degeneration
- vision-transformer
- siglip
- pytorch
pipeline_tag: image-classification
---
# vit-oct-wamd
A [SigLIP](https://huggingface.co/google/siglip-so400m-patch14-384) vision transformer
fine-tuned to classify optical coherence tomography (OCT) B-scan images as **normal**
or **wet AMD** (neovascular age-related macular degeneration).
Released as supporting material for an accompanying paper.
## Model description
- **Base encoder:** `google/siglip-so400m-patch14-384`, fine-tuned end-to-end.
- **Head:** a single linear layer (`1152 β†’ 2`) on top of the encoder's CLS token, with dropout before the head.
- **Auxiliary branch:** the released checkpoint also includes a frozen T5-base text encoder + projection (`siglip_loss` in the state dict),
used only for an auxiliary contrastive image-text alignment loss during training.
It is **not used at inference time** β€” `forward()` only calls `image_encoder` and `cls_head`.
## Dataset
Dataset: [kavin-aravindhan/oct-wamd](https://huggingface.co/datasets/kavin-aravindhan/oct-wamd).
Public access is pending IRB approval β€” for interim access, contact Kavin
Aravindhan (kr3131@columbia.edu).
## Files in this repo
| File | Purpose |
|---|---|
| `best_model.pt` | Full training checkpoint (classifier weights + auxiliary branch + optimizer/scheduler state). |
| `modeling.py`, `alignment.py`, `embedder.py` | Model definition matching the checkpoint exactly. |
| `infer.py` | Quick-start CLI: run the classifier on one or more images. |
| `demo_app.py` | Local interactive Gradio demo (image upload β†’ prediction). |
| `train.py` | Trainer script reproducing the paper's training procedure. |
| `training_config.json` | Exact hyperparameters used for this checkpoint. |
| `requirements.txt`, `requirements-train.txt`, `requirements-demo.txt` | Pinned dependency versions for `infer.py`, `train.py`, and `demo_app.py` respectively. |
## Quick start
```bash
pip install huggingface_hub
huggingface-cli download kavin-aravindhan/vit-oct-wamd infer.py requirements.txt --local-dir .
pip install -r requirements.txt
python infer.py path/to/scan.png
```
`requirements.txt` pins `torch`/`transformers`/`huggingface_hub` to the exact
versions used to produce `best_model.pt` β€” an unpinned `pip install
transformers` can resolve to a version whose `SiglipVisionModel` uses
different internal parameter names, which will fail to load this
checkpoint's state dict.
```
path/to/scan.png: wet_amd (confidence=0.513)
```
First run downloads the checkpoint (~5.1GB) and caches it; subsequent runs take a few seconds per image on GPU, ~15-20s on CPU.
Or from Python:
```python
from huggingface_hub import hf_hub_download
import sys, os, torch
repo_id = "kavin-aravindhan/vit-oct-wamd"
local_dir = os.path.dirname(hf_hub_download(repo_id=repo_id, filename="modeling.py"))
for f in ["alignment.py", "embedder.py", "best_model.pt"]:
hf_hub_download(repo_id=repo_id, filename=f, local_dir=local_dir)
sys.path.insert(0, local_dir)
from modeling import load_model, IMAGE_SIZE
model = load_model(os.path.join(local_dir, "best_model.pt"), device="cuda") # or "cpu"
```
See `infer.py` for the exact image preprocessing (resize to 384Γ—384, normalize to `[-1, 1]`).
## Interactive demo
Run the demo locally:
```bash
pip install huggingface_hub
huggingface-cli download kavin-aravindhan/vit-oct-wamd demo_app.py requirements-demo.txt --local-dir .
pip install -r requirements-demo.txt
python demo_app.py
```
This opens a local web UI where you can upload an OCT B-scan and see the
prediction. `requirements-demo.txt` pins a specific gradio + transformers +
huggingface_hub + pydantic/starlette/fastapi combination verified to work
together end-to-end β€” gradio's latest releases require `huggingface_hub>=1.0`,
which conflicts with the `transformers==4.53.0` needed to load the
checkpoint, and an unpinned newer pydantic/starlette paired with older
gradio breaks page rendering outright.
## Reproducing training
`train.py` is a cleaned-up, parameterized version of the exact script used
to train this checkpoint β€” same architecture, loss, hyperparameters (500-trial
Optuna search, see `training_config.json`), and augmentation recipe.
```bash
pip install -r requirements-train.txt
python train.py --tfrecord-path /path/to/.tfrecord --output-dir ./runs/my_run
```
**Data access:** see [Dataset](#dataset) above β€” the training set (112
labeled images with clinical-finding captions) is hosted as a private HF
dataset pending IRB approval.
**Note on training-set size:** training draws 1000 samples per epoch, with replacement and augmentation, from only 112 unique images β€” not 1000 unique examples.
| Hyperparameter | Value |
|---|---|
| Image encoder | `google/siglip-so400m-patch14-384` |
| Text encoder (auxiliary branch) | `google-t5/t5-base` |
| Batch size | 8 |
| Learning rate | 1e-4 |
| Weight decay | 1.6e-6 |
| Alpha (loss mixing, cls vs. alignment) | 0.884 |
| Dropout | 0.057 |
| Epochs | 50 (early stopping patience 20) |
## License
MIT.
## Citation
TODO β€” paper citation to be added before camera-ready.