GorillaWatch-DINOv2-Giant
A
vit_giant_patch14_dinov2.lvd142m DINOv2 backbone fine-tuned with hard-mining triplet loss on
Gorilla-SPAC-Wild, projecting to a
256-dimensional embedding. Identification is done by k-NN retrieval against a
gallery of embeddings, not by classification. The model has no fixed identity vocabulary, to enable
generalisation to individuals unseen during training.
| |
|---|
| Backbone | vit_giant_patch14_dinov2.lvd142m |
| Input resolution | 518×518 |
| Embedding dimension | 256 |
| Parameters | 1136.9M |
| Training data | Gorilla-SPAC-Wild (face_with_body) |
Preprocessing
[!IMPORTANT]
This model does not use timm's default DINOv2 transform. It expects a square resize
(which only preserves the aspect ratio when the input images are already squared, which is the case in our datasets) and normalization with mean = std = 0.5, not the ImageNet
statistics reported in the backbone's default_cfg. Using timm's default transform produces
incorrect embeddings.
1transforms.Compose([
2 transforms.Resize((518, 518)),
3 transforms.ToTensor(),
4 transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]),
5])
modeling.py in this repository exposes this as model.get_transform().
Usage
Here we provide a minimal setup to use the model for feature extraction.
Requires torch, timm, safetensors, huggingface_hub and torchvision.
1import sys, torch
2from huggingface_hub import snapshot_download
3from PIL import Image
4
5# Fetch weights, config and the self-contained modeling.py in one go
6local_dir = snapshot_download("gorilla-watch/GorillaWatch-DINOv2-Giant")
7sys.path.insert(0, local_dir)
8device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
9from modeling import load_model
10
11model = load_model(local_dir, device=device) # already in eval mode
12transform = model.get_transform()
13
14image = Image.open("gorilla.png").convert("RGB")
15with torch.no_grad():
16 embedding = model(transform(image).unsqueeze(0).to(model.device)) # (1, 256)
load_model also accepts the repo id directly (load_model("gorilla-watch/GorillaWatch-DINOv2-Giant")) if you would rather not
manage a local directory.
Identity assignment uses
k-NN with k=5 under Euclidean distance against a gallery of embeddings.
The paper's protocol masks out gallery entries from the same encounter (same camera on the same
date) to avoid trivially easy matches. The full evaluation code can be found in our
GitHub Repo.
Training
Fine-tuned from the upstream vit_giant_patch14_dinov2.lvd142m DINOv2 checkpoint.
| Hyperparameter | Value |
|---|
| Loss | Online triplet, hard mining, Euclidean, margin 0.647 |
| Optimizer | AdamW (β=0.9/0.999, ε=1e-7) |
| Learning rate | 1.9e-7, cosine annealing to 1e-7 |
| Batch size | 8 (effective 48 via 6 gradient accumulation steps) |
| Regularization | L2 = 0.0059, L2-SP = 1.3e-5 |
| Epochs | 100 max, best-validation-loss checkpoint retained |
| Precision | AMP (fp16 autocast, fp32 master weights) |
| Seed | 42 |
The code used to train these models can be found in our
Github Repository.
Results
k-NN retrieval accuracy (k=5, Euclidean distance). Gallery entries from the same encounter (same camera on the same date) are masked out, so every match is made across encounters. Macro accuracy averages over identities and is the harder number: it weights rarely-seen individuals equally with frequently-seen ones.
In-domain: Gorilla-SPAC-Wild
Test split of
Gorilla-SPAC-Wild, the distribution the model was fine-tuned on.
| Protocol | Micro accuracy | Macro accuracy |
|---|
| Per image | 0.5554 | 0.4629 |
| Per tracklet (average pooling) | 0.6121 | 0.4451 |
Out-of-distribution: Gorilla-Zoo-Berlin
Gorilla-Zoo-Berlin is a
zero-shot domain-transfer test: the model is applied to footage recorded in the Berlin Zoo, with no fine-tuning on it, so enclosure, lighting, camera hardware and the individuals themselves are all unseen. The numbers are still higher, since the amount of individuals is much lower than in the SPAC dataset. This evaluation clearly shows that the model is able to generalize to new, unseen populations.
| Protocol | Micro accuracy | Macro accuracy |
|---|
| Per image | 0.7657 | 0.7590 |
| Per tracklet (average pooling) | 0.8218 | 0.8044 |
Provenance
These weights are bit-identical conversions from the .pth files created in the training process. They were converted to the model.safetensors format for better integration with HuggingFace.
License
This model is released under the CC-BY-4.0 License.
Citation
1@inproceedings{GorillaWatch2026,
2 title={GorillaWatch: An Automated System for In-the-Wild Gorilla Re-Identification and Population Monitoring},
3 booktitle={Proceedings of the IEEE/CVF Winter Conference on Applications of Computer Vision (WACV)},
4 author={Maximilian Schall and Felix Leonard Knöfel and Noah Elias König and Jan Jonas Kubeler and Maximilian von Klinski and Joan Wilhelm Linnemann and Xiaoshi Liu and Iven Jelle Schlegelmilch and Ole Woyciniuk and Alexandra Schild and Dante Wasmuht and Magdalena Bermejo Espinet and German Illera Basas and Gerard de Melo},
5 year={2026},
6 archivePrefix={arXiv},
7 eprint={2512.07776}
8}
Acknowledgements
The project on which this report is based was funded by the Federal Ministry of Research, Technology and Space under the funding code “KI-Servicezentrum Berlin-Brandenburg” 16IS22092. We acknowledge the support of Sabine Plattner African Charities (SPAC) for their funding to this research. We are grateful to Zoo Berlin for their expert assistance and facility access. This collaboration enabled the development of AI tools capable of being deployed in the wild to directly support gorilla conservation. The responsibility for the content of this publication remains with the authors.