Downloads · 30 days
0
matanrich/dinov3_onnx_classifier
dinov3_onnx_classifier is a image classification model from matanrich. Use it when you need a label for an image. It is set up for onnx. The card lists the license as other.
A binary image classifier that runs before GeoCLIP geo-estimation. It decides whether an image shows a place that can plausibly be located, such as streets, buildings, landscape or landmarks. Images without one go no…
Downloads · 30 days
0
Access
Public
Updated Oct 5, 2026
Repo size
433 MB
Likes
0
Public
Click a slice to open those files.
.onnx433 MB · 100%
From the Hugging Face model README
A binary image classifier that runs before GeoCLIP geo-estimation. It decides whether an image shows a place that can plausibly be located, such as streets, buildings, landscape or landmarks. Images without one go no further, so GeoCLIP never assigns a location to them. That covers portraits and selfies, close-ups, screenshots, logos, documents and other graphics.
| File | Backbone | Size | Input batch | sha256 |
|---|---|---|---|---|
25.09.25-dinov3_vitb16_geo_filter.onnx | DINOv3 ViT-B/16 (frozen) + MLP head | 346 MB | dynamic | 49bb52b6d5bc22153cd2a4f433ac2ec00ea9a0e144712a73d45501e907119599 |
04.10.25-dino_v3_linear.onnx | DINOv3 + linear head (previous version) | 87 MB | 1 | 5ca53cc5a07d5b3102c6d68e85fdb8670f3c8e94622fa48964f61bf5ab54efb3 |
Both files have the same interface, so either is a drop-in replacement for the other.
pixel_values: float32 [batch, 3, 224, 224]. RGB, resized to 224×224 without keeping aspect ratio or cropping (bilinear), scaled to [0, 1], then normalised with ImageNet mean [0.485, 0.456, 0.406] and std [0.229, 0.224, 0.225].classification: float32 [batch, 2] logits. Index 0 means usable for geo-estimation, index 1 means reject.argmax. The operating threshold is built into the head's bias, so callers need no threshold of their own. Apply a softmax for probabilities.import numpy as np
import onnxruntime as ort
from PIL import Image
session = ort.InferenceSession("25.09.25-dinov3_vitb16_geo_filter.onnx")
image = Image.open("photo.jpg").convert("RGB").resize((224, 224), Image.BILINEAR)
x = (np.asarray(image, np.float32) / 255 - [0.485, 0.456, 0.406]) / [0.229, 0.224, 0.225]
logits = session.run(None, {"pixel_values": x.transpose(2, 0, 1)[None].astype(np.float32)})[0][0]
usable_for_geo = int(np.argmax(logits)) == 0
25.09.25)facebook/dinov3-vitb16-pretrain-lvd1689m, frozen.SmolVLM2-2.2B-Instruct. It answered two yes/no questions, read from next-token probabilities:
| Split | Images | Usable for geo |
|---|---|---|
| train | 25,307 | 2,185 |
| validation | 5,477 | 492 |
| test | 5,379 | 439 |
VLM-labelled test split (5,379 images, 439 usable): ROC AUC 0.995, average precision 0.963. At the built-in threshold, 89.6% of the images it passes are usable, and it keeps 90.7% of the usable images.
Hand-labelled held-out set: 300 random images, never used for training or tuning. Ambiguous images are excluded from these counts.
04.10.25 (previous) | 25.09.25 | |
|---|---|---|
| Usable images kept (of 10) | 10 | 8 |
| Reject images passed (of 264) | 143 | 9 |
| Passed images that are usable | 6.5% | 47% |
Fresh unlabelled images (3,000, never seen in training): the previous filter passes 60.1% of them and the new one 11.9%.
Known weakness: people posed outdoors with some scenery behind them, such as group photos or a selfie on a street, are the most common remaining false passes. Dense street crowds can also pass.
Per image, batch 1, onnxruntime 1.22.0 on CPU (AMD EPYC 7401P), median:
| Threads | 04.10.25 | 25.09.25 |
|---|---|---|
| 6 | 97 ms | 260 ms |
| 24 | 76 ms | 177 ms |
The new backbone needs about 4× the compute of the previous one. GPU latency was not measured.
Both files contain DINOv3 weights, so they are distributed under the DINOv3 License.