File size: 5,517 Bytes
2abfa39 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | ---
license: mit
tags:
- scanpath-prediction
- eye-tracking
- saliency
- computer-vision
---
# Scanpath Prediction Checkpoints
Model checkpoints for a transformer-based scanpath prediction architecture — predicting the
sequence of eye fixations `(x, y)` a human makes when free-viewing an image.
Evaluated against **DeepGaze III** (Kümmerer, Bethge & Wallis, *Journal of Vision* 2022) on
**MIT1003** and **CAT2000**.
---
## ⚠️ Which folder should I use?
**Use `v2_phase2/`.** It holds the current, published configuration. The `nb17/`, `nb19/`,
`nb20/` and `nb21_*` folders are *older exploratory runs* kept for provenance — they use
different hyperparameters (K=4 instead of K=8, plain L2 loss, learned-sigma variant) and
**will not reproduce the reported numbers**.
---
## Results (`v2_phase2`)
L2 = mean Euclidean distance between predicted and ground-truth fixation, with **each axis
normalized independently to [0,1]** (`x/W`, `y/H`). Teacher-forced, all valid steps 1..8,
10-fold cross-validation on predefined 8/1/1 splits (identical splits to DeepGaze III).
| Dataset | Ours | DeepGaze III | Improvement |
|---|---|---|---|
| **MIT1003** | **0.1227** | 0.2112 | **−42%** |
| **CAT2000** | **0.1432** | 0.1998 * | **−28%** |
\* DeepGaze III on CAT2000 is a **transfer** baseline — its scanpath components are
cross-validated on MIT1003 and were never retrained on CAT2000. We ensemble all 10 components.
Label it as transfer wherever the number is used.
### Per-step L2 (per-axis, [0,1])
| step | MIT1003 ours | MIT1003 DG3 | CAT2000 ours | CAT2000 DG3 |
|---|---|---|---|---|
| 1 | 0.1220 | 0.139 | 0.1051 | 0.168 |
| 2 | 0.1211 | 0.204 | 0.1176 | 0.175 |
| 3 | 0.1167 | 0.223 | 0.1389 | 0.172 |
| 4 | 0.1184 | 0.224 | 0.1510 | 0.176 |
| 5 | 0.1256 | 0.224 | 0.1576 | 0.184 |
| 6 | 0.1247 | 0.230 | 0.1583 | 0.187 |
| 7 | 0.1271 | 0.231 | 0.1591 | 0.189 |
| 8 | 0.1261 | 0.229 | 0.1606 | 0.188 |
Our model has lower error at every fixation step on both datasets.
---
## Contents
```
v2_phase2/
mit1003/
dinov2_big_unfrozen/ fold0..fold9 (+ trainsummary json) best L2 on MIT1003
clip_small_unfrozen/ fold0..fold9 (+ trainsummary json) best NSS on MIT1003
cat2000/
dinov2_big_unfrozen/ fold0..fold9 (+ trainsummary json)
nb17_mit1003_cv10/ older baseline (pre-Phase-2), single-fold samples
nb19_mit1003_cv10_k4/ K_FIX=4 ablation
nb20_cat2000_cv10_k4/ K_FIX=4 ablation, CAT2000
nb21_mit1003_cv10_learned_sigma/ learned-sigma experiment
```
Each `v2_phase2` config ships **all 10 CV folds**, so the cross-validated numbers above are
fully reproducible. `trainsummary_*.json` records per-fold best val-NSS, per-epoch history
and wall-clock time.
---
## Architecture
```
image → encoder (frozen or fine-tuned) → transformer autoregressive decoder → Linear(d, 2) → (x, y)
```
| Config | Encoder | enc_dim | dec_dim | layers | batch |
|---|---|---|---|---|---|
| `dinov2_big` | DINOv2 ViT-B/14 | 512 | 512 | 10 | 32 |
| `clip_small` | CLIP | 512 | 256 | 4 | 128 |
- `K_FIX = 8` fixations predicted per image
- `context_len = 4` — the decoder's causal attention sees at most the last 4 fixations,
matching DeepGaze III's history length
- First fixation is predicted from a BOS token at the image centre `(0.5, 0.5)`
## Training hyperparameters
```
image size 224 x 224 (448 was tested and was worse)
epochs 30
optimiser AdamW (fused), weight_decay 5e-4
lr 3.3e-4 head; 2e-5 encoder when unfrozen (differential LR)
schedule 3-epoch linear warmup -> cosine
precision bfloat16 AMP, drop_last=True
dropout 0.1
grad clip max_norm 1.0
augmentation horizontal flip (train only), x -> 1-x
loss masked_L2 + 0.3 * NSS_aux (map_size 128, sigmas 3/5/8, active from epoch 3)
selection best checkpoint by validation NSS (not validation L2)
seed 42
CV 10 folds, 8/1/1, predefined splits (identical to DeepGaze III)
```
## Usage
```python
import torch
from huggingface_hub import hf_hub_download
from scanpath_lib.models.scanpath_model import ScanpathModel
path = hf_hub_download(
"businesslion/scanpath-prediction-checkpoints",
"v2_phase2/mit1003/dinov2_big_unfrozen/fold0_dinov2_big_unfrozen.pt",
)
model = ScanpathModel(
k_fix=8, enc_dim=512, dec_dim=512, n_heads=4, n_layers=10,
max_len=64, encoder_name="dinov2", image_size=224,
context_len=4, predict_sigma=False,
)
model.load_state_dict(torch.load(path, map_location="cpu", weights_only=True))
model.eval()
```
For the cross-validated numbers, evaluate each fold's checkpoint on **that fold's test split**
(every image is then scored exactly once by a model that never trained on it) and pool.
## Reproducibility note
The `v2_phase2` weights were retrained in Aug 2026 after the originals were lost, using the
same code, seed and fold splits but a newer PyTorch (2.10). They reproduce the original
numbers to within **0.7%** (MIT1003 0.1219 → 0.1227; CAT2000 0.1426 → 0.1432). Exact
bit-level equality is not expected across PyTorch versions.
## Citation
DeepGaze III baseline:
```bibtex
@article{kummerer2022deepgaze3,
title = {DeepGaze III: Modeling free-viewing human scanpaths with deep learning},
author = {K{\"u}mmerer, Matthias and Bethge, Matthias and Wallis, Thomas S. A.},
journal = {Journal of Vision},
volume = {22}, number = {5}, pages = {7}, year = {2022},
doi = {10.1167/jov.22.5.7}
}
```
|