| 50 | |
| 51 | |
| 52 | class _LinearClassifierWrapper(nn.Module): |
| 53 | def __init__(self, *, backbone: nn.Module, linear_head: nn.Module, layers: int = 4): |
| 54 | super().__init__() |
| 55 | self.backbone = backbone |
| 56 | self.linear_head = linear_head |
| 57 | self.layers = layers |
| 58 | |
| 59 | def forward(self, x): |
| 60 | if self.layers == 1: |
| 61 | x = self.backbone.forward_features(x) |
| 62 | cls_token = x["x_norm_clstoken"] |
| 63 | patch_tokens = x["x_norm_patchtokens"] |
| 64 | # fmt: off |
| 65 | linear_input = torch.cat([ |
| 66 | cls_token, |
| 67 | patch_tokens.mean(dim=1), |
| 68 | ], dim=1) |
| 69 | # fmt: on |
| 70 | elif self.layers == 4: |
| 71 | x = self.backbone.get_intermediate_layers(x, n=4, return_class_token=True) |
| 72 | # fmt: off |
| 73 | linear_input = torch.cat([ |
| 74 | x[0][1], |
| 75 | x[1][1], |
| 76 | x[2][1], |
| 77 | x[3][1], |
| 78 | x[3][0].mean(dim=1), |
| 79 | ], dim=1) |
| 80 | # fmt: on |
| 81 | else: |
| 82 | assert False, f"Unsupported number of layers: {self.layers}" |
| 83 | return self.linear_head(linear_input) |
| 84 | |
| 85 | |
| 86 | def _make_dinov2_linear_classifier( |
no outgoing calls
no test coverage detected