Spaces:
Running on Zero
Running on Zero
Upload model/dinov2.py with huggingface_hub
Browse files- model/dinov2.py +40 -0
model/dinov2.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""DINOv2 ViT backbone — extracts 4 intermediate feature maps.
|
| 2 |
+
|
| 3 |
+
Loads via torch.hub from facebookresearch/dinov2. Patch size 14, so inputs must
|
| 4 |
+
be divisible by 14. All transformer blocks operate at the same spatial
|
| 5 |
+
resolution H/14 x W/14; the decoder builds the feature pyramid.
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
import torch
|
| 9 |
+
import torch.nn as nn
|
| 10 |
+
|
| 11 |
+
_VARIANTS = {
|
| 12 |
+
'dinov2_vits14': {'embed_dim': 384, 'depth': 12, 'layers': (2, 5, 8, 11)},
|
| 13 |
+
'dinov2_vitb14': {'embed_dim': 768, 'depth': 12, 'layers': (2, 5, 8, 11)},
|
| 14 |
+
'dinov2_vitl14': {'embed_dim': 1024, 'depth': 24, 'layers': (4, 11, 17, 23)},
|
| 15 |
+
'dinov2_vitg14': {'embed_dim': 1536, 'depth': 40, 'layers': (9, 19, 29, 39)},
|
| 16 |
+
}
|
| 17 |
+
PATCH_SIZE = 14
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
class DINOv2Backbone(nn.Module):
|
| 21 |
+
"""Returns 4 patch-token feature maps reshaped to (B, C, H/14, W/14)."""
|
| 22 |
+
|
| 23 |
+
def __init__(self, name='dinov2_vitb14', pretrained=True, out_layers=None):
|
| 24 |
+
super().__init__()
|
| 25 |
+
if name not in _VARIANTS:
|
| 26 |
+
raise ValueError(f'unknown variant {name!r}; choose from {list(_VARIANTS)}')
|
| 27 |
+
spec = _VARIANTS[name]
|
| 28 |
+
self.name = name
|
| 29 |
+
self.embed_dim = spec['embed_dim']
|
| 30 |
+
self.out_layers = tuple(out_layers) if out_layers is not None else spec['layers']
|
| 31 |
+
self.patch_size = PATCH_SIZE
|
| 32 |
+
self.channels = [self.embed_dim] * len(self.out_layers)
|
| 33 |
+
self.vit = torch.hub.load('facebookresearch/dinov2', name, pretrained=pretrained)
|
| 34 |
+
|
| 35 |
+
def forward(self, x):
|
| 36 |
+
h, w = x.shape[-2:]
|
| 37 |
+
if h % self.patch_size or w % self.patch_size:
|
| 38 |
+
raise ValueError(f'input {h}x{w} not divisible by patch size {self.patch_size}')
|
| 39 |
+
return list(self.vit.get_intermediate_layers(
|
| 40 |
+
x, n=self.out_layers, reshape=True, return_class_token=False, norm=True))
|