Skip to main content

VisBench

Probe any vision backbone across high-, mid- and low-level computer vision tasks.

PyPI CI License: MIT Documentation DOI Python 3.10+


Status: v0.17.0. Seventeen probes across high, mid and low level, thirteen backbones from three families, and a committed corpus covering 204 board cells — seventeen boards, twelve backbones each, every one of them reproducible from the flags in its own record. The full documentation, including a generated API reference, is at https://turhancan97.github.io/VisBench.

Try it in thirty seconds

No dataset, no configuration, no large download:

pip install visbench
visbench demo
drawing 20 images per class for 4 shapes...
loading resnet18 (torchvision, ~45 MB on first run)...
running the classification probe...

  top1         0.8125

  chance is 0.25 — the shapes differ in outline only.

That is a real probe, on a real pretrained backbone, through the same code path every other run uses. The images are generated: four shapes with colour, size, position and rotation randomised, so only geometry identifies a class and a backbone that has not learned shape scores about chance.

The number is deliberately not 1.0. Turn the difficulty up and watch it fall:

visbench demo --noise 90      # top1 ~0.31, against a chance of 0.25
--noise 28 45 (default) 60 75 90
top1 0.975 0.812 0.550 0.438 0.312

A probe whose score does not move when you destroy the signal is not measuring the signal. That slide into chance is the demo's actual point.

Install

pip install visbench                    # core: DINOv2, every probe, the CLI
pip install 'visbench[clip,timm]'       # + CLIP and timm backbones
pip install 'visbench[hub]'             # + push/pull probes to Hugging Face

A backbone whose extra is missing stays listed — visbench list backbones marks it — and constructing one tells you which extra to install rather than pretending the name does not exist.

Full instructions, including a source install and what each extra buys: installation.

What it is

The name is literal: Vis(ion) Bench(mark). Both halves are a scope commitment. Vis — the subject is a vision backbone's features, not a multimodal or language model's behaviour; a text tower is only ever used to build the visual one. Bench — the output is a comparable number rather than a score: every run writes a record saying which backbone, dataset, pooling, layers and protocol produced it, and explicit rules decide which records may be ranked against each other at all.

VisBench answers one question with as little ceremony as possible: what does this vision backbone actually encode?

as root/<class_name>/<image>:

import visbench
from visbench.data import ImageFolderDataset

result = visbench.run(
    "dinov2_vitb14",
    "retrieval",
    ImageFolderDataset("data/tiny", split="val"),
    results="results/visbench.jsonl",
)
result.metrics    # {"recall@1": 0.94, "recall@5": 0.99, "mAP": 0.87}
result.record     # the ResultRecord that says exactly how they were produced

run() resolves pooling, extracts through the cache, fits the probe if it trains, evaluates, and appends the record. The pieces are public if you want them separately — see the quickstart.

Installing the package also puts a visbench command on your path, a thin wrapper over the same call:

visbench demo                       # a real probe on generated data, no setup
visbench list                       # backbones, probes and heads that exist
visbench run retrieval --data /path/to/imagenette2 --split val
visbench show depth --data /path/to/nyuv2 --out panels.png

Each probe is its own subcommand, because they do not take the same data — the CLI reference.

Look before you measure

visbench show <probe> draws what a probe saw beside what it predicted. It measures nothing — it exists because a dense target that has drifted from its image fails silently: the probe trains, and the number merely comes out mediocre. Two of the most expensive bugs in this project were exactly that, and both are obvious in one frame.

Depth panels: a photograph and a predicted depth map, each row captioned with the range in metres it is drawn against

Correspondence: two views with the matches between them

Every probe is drawable, and every figure here is a real photograph run through the real command — see looking at a probe for all seventeen and how to read them.

Task levels

Following Chen, Marks & Cheng (arXiv:2411.17474):

Level Tasks Status
High-level — semantic / category classification, retrieval v0.1
semantic (multi-class) segmentation v0.2
detection (anchor-free, single-scale) v0.3
Mid-level — geometry & generic structure geometric correspondence v0.1
depth, surface normals, generic (binary) segmentation, mid-level similarity v0.2
occlusion-edge detection v0.5
Low-level — signal properties edge detection (dense magnitude regression) v0.4
2D keypoint detection v0.5
optical flow, texture, IQA scope only

Mid-level is where VisBench aims to be strongest relative to existing tooling. Note that mid-level image similarity and high-level retrieval are separate tasks — one judges perceptual/geometric resemblance, the other category membership.

Design in three points

One extraction method. backbone.extract_features(image, pooling=..., layers=...) returns {"dense": (B, C, H, W), "pooled": (B, C), "grid_hw": (H, W)} — both representations from one forward pass. ViTs and CNNs share the exact same signature and return shape despite completely different internals.

Tasks choose pooling, backbones don't. A task passes pooling="cls" or "mean" down into extraction. Backbones stay dumb and interchangeable; the "what representation does this task need" decision lives in one place.

The cache is not optional. Disk-backed, keyed by (image_hash, backbone_name, layer, pooling). Every task reads through it, so the backbone forward pass runs at most once per image per backbone.

Documentation

Install, first run, the CLI Getting started
Backbones, datasets, dense probes, sharing Guides
Every probe, its data layout and its board The probes
How to read a board before quoting one Reading a board
Every class, function and attribute API reference
Sixteen probes against twelve backbones LEADERBOARD.md
What each board means, and what it does not CORPUS_FINDINGS.md
Setting up, the checks, adding a probe CONTRIBUTING.md
How it was built, and what might come next docs/roadmap.md
What changed, release by release CHANGELOG.md
The reference, page by page docs/probes/overview.md, docs/api/index.md

Reproducibility

Sixteen probes against twelve backbones, as records: LEADERBOARD.md. Every board is generated from results/corpus/visbench.jsonl, the committed corpus, by scripts/render_tables.py. A test in the fast suite fails if any of them drifts, so a published number and the run behind it cannot disagree.

Every run logs a structured JSON record — backbone, weights key, task, dataset, pooling, feature mode, metrics, seed, timestamp — under one additive-only schema, so leaderboard tooling never needs a retrofit. Dependencies are pinned in uv.lock, and CI fails if it drifts from pyproject.toml.

Before quoting any board, read how to read one. The short version: "which backbone is best" is not a well-formed question against this corpus — mae_vitb16 is first on six of the seventeen boards and last on four.

Prior art

VisBench reuses established protocols rather than re-deriving them, and cites them at the point of use in the code:

Citing VisBench

If VisBench contributed to work you are publishing, please cite it. GitHub's Cite this repository button generates APA and BibTeX from CITATION.cff, or use:

@software{kargin_visbench,
  author  = {Kargın, Turhan Can},
  title   = {VisBench: probing vision backbones across high-, mid- and low-level tasks},
  doi     = {10.5281/zenodo.21822684},
  url     = {https://doi.org/10.5281/zenodo.21822684},
  license = {MIT},
  version = {0.12.0}
}

If you are reporting numbers, cite the version you ran. Every VisBench result record carries the schema, the resolved pooling, the layers and the protocol that produced it, so a number is reproducible — but only against the release that produced it. visbench.__version__ is in every record.

The DOI above is the concept DOI: it always resolves to the newest release, which is what you want when citing the software itself. Zenodo also mints a version DOI per release, listed on the archive page under Versions — pin that one in a paper reporting measured numbers, for the same reason every record carries its schema and protocol.

License

MIT — see LICENSE.

VisBench borrows evaluation protocols from prior work, all permissively licensed and MIT-compatible; NOTICE records what came from where. Backbone weights are downloaded at runtime, never redistributed here, and carry their own upstream terms.

Metadata

Release files for visbench 0.17.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for visbench 0.17.0
File Size Uploaded
visbench-0.17.0.tar.gz 1.3 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for visbench 0.17.0
File Interpreter ABI Platform
visbench-0.17.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.7 MB

Release files / visbench-0.17.0.tar.gz

Download URL visbench-0.17.0.tar.gz
Size 1.3 MB
Tags Source
SHA-256 checksum
How to use checksums
2d41ae4e31393485630e3253b04e2e16b10993af94479f75b361103cc2457bc1
BLAKE2b-256 checksum
How to use checksums
d7195b94bfdda4aa2f79de241aa6d75ad7c955e3534c44cc843d149da9e330ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.8

Release files / visbench-0.17.0-py3-none-any.whl

Download URL visbench-0.17.0-py3-none-any.whl
Size 407.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3cd28f6ffc1a2c0948f978a14c9ff88321871e48bc531e5c9a7ff88546823292
BLAKE2b-256 checksum
How to use checksums
8daa1d2254233ec4c672093349597ed3886f48c414c5695072a2057d3e21bbe5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.8

Release history Release notifications | RSS feed

0.27.0

2 release files

0.26.0

2 release files

0.25.0

2 release files

0.24.0

2 release files

0.23.0

2 release files

0.22.0

2 release files

0.21.0

2 release files

0.20.0

2 release files

0.19.0

2 release files

0.18.0

2 release files

This release

0.17.0 This release

2 release files

0.13.0

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page