psychofict commited on
Commit
6efc19d
·
verified ·
1 Parent(s): 3fbde4c

Upload model/dinov2.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. 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))