kd13 commited on
Commit
23a2e3f
·
verified ·
1 Parent(s): c3cb148

Update modeling_vit.py

Browse files
Files changed (1) hide show
  1. modeling_vit.py +223 -1
modeling_vit.py CHANGED
@@ -1 +1,223 @@
1
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import torch.nn.functional as F
4
+ from transformers import PreTrainedModel
5
+ from transformers.modeling_outputs import SequenceClassifierOutput
6
+ from .configuration_vit import CustomViTNanoV2Config
7
+
8
+ class RMSNorm(nn.Module):
9
+ def __init__(self, dim: int, eps: float = 1e-6):
10
+ super().__init__()
11
+ self.eps = eps
12
+ self.weight = nn.Parameter(torch.ones(dim))
13
+
14
+ def forward(self, x):
15
+ variance = x.pow(2).mean(-1, keepdim=True)
16
+ x = x * torch.rsqrt(variance + self.eps)
17
+ return self.weight * x
18
+
19
+ class SwiGLU(nn.Module):
20
+ def __init__(self, in_features, hidden_features, out_features):
21
+ super().__init__()
22
+ self.w_gate = nn.Linear(in_features, hidden_features, bias=False)
23
+ self.w_up = nn.Linear(in_features, hidden_features, bias=False)
24
+ self.w_down = nn.Linear(hidden_features, out_features, bias=False)
25
+
26
+ def forward(self, x):
27
+ return self.w_down(F.silu(self.w_gate(x)) * self.w_up(x))
28
+
29
+ class RotaryEmbedding2D(nn.Module):
30
+ def __init__(self, head_dim: int, grid_size: int, base: float = 10000.0):
31
+ super().__init__()
32
+ self.head_dim = head_dim
33
+ self.axis_dim = head_dim // 2
34
+ self.grid_size = grid_size
35
+ self.num_patches = grid_size * grid_size
36
+
37
+ inv_freq = 1.0 / (
38
+ base ** (torch.arange(0, self.axis_dim, 2, dtype=torch.float32) / self.axis_dim)
39
+ )
40
+ coords = torch.arange(grid_size, dtype=torch.float32)
41
+ yy, xx = torch.meshgrid(coords, coords, indexing="ij")
42
+ x_freqs = torch.outer(xx.reshape(-1), inv_freq)
43
+ y_freqs = torch.outer(yy.reshape(-1), inv_freq)
44
+
45
+ self.register_buffer("cos_x", x_freqs.cos()[None, None, :, :], persistent=False)
46
+ self.register_buffer("sin_x", x_freqs.sin()[None, None, :, :], persistent=False)
47
+ self.register_buffer("cos_y", y_freqs.cos()[None, None, :, :], persistent=False)
48
+ self.register_buffer("sin_y", y_freqs.sin()[None, None, :, :], persistent=False)
49
+
50
+ @staticmethod
51
+ def _rotate_axis(x, cos, sin):
52
+ x_even = x[..., 0::2]
53
+ x_odd = x[..., 1::2]
54
+ out_even = x_even * cos - x_odd * sin
55
+ out_odd = x_even * sin + x_odd * cos
56
+ return torch.stack((out_even, out_odd), dim=-1).flatten(-2)
57
+
58
+ def _apply_rope(self, x):
59
+ cls_token = x[:, :, :1, :]
60
+ patches = x[:, :, 1:, :]
61
+ x_axis, y_axis = patches.split(self.axis_dim, dim=-1)
62
+ cos_x = self.cos_x.to(device=x.device, dtype=x.dtype)
63
+ sin_x = self.sin_x.to(device=x.device, dtype=x.dtype)
64
+ cos_y = self.cos_y.to(device=x.device, dtype=x.dtype)
65
+ sin_y = self.sin_y.to(device=x.device, dtype=x.dtype)
66
+ x_axis = self._rotate_axis(x_axis, cos_x, sin_x)
67
+ y_axis = self._rotate_axis(y_axis, cos_y, sin_y)
68
+ patches = torch.cat((x_axis, y_axis), dim=-1)
69
+ return torch.cat((cls_token, patches), dim=2)
70
+
71
+ def forward(self, q, k):
72
+ return self._apply_rope(q), self._apply_rope(k)
73
+
74
+ class ConvStem(nn.Module):
75
+ def __init__(self, in_chans: int, embed_dim: int, channels: tuple[int, int, int]):
76
+ super().__init__()
77
+ c1, c2, c3 = channels
78
+ self.proj = nn.Sequential(
79
+ nn.Conv2d(in_chans, c1, kernel_size=3, stride=2, padding=1, bias=False),
80
+ nn.BatchNorm2d(c1),
81
+ nn.GELU(),
82
+ nn.Conv2d(c1, c2, kernel_size=3, stride=2, padding=1, bias=False),
83
+ nn.BatchNorm2d(c2),
84
+ nn.GELU(),
85
+ nn.Conv2d(c2, c3, kernel_size=3, stride=2, padding=1, bias=False),
86
+ nn.BatchNorm2d(c3),
87
+ nn.GELU(),
88
+ nn.Conv2d(c3, embed_dim, kernel_size=3, stride=2, padding=1, bias=False),
89
+ )
90
+ def forward(self, x):
91
+ return self.proj(x)
92
+
93
+ class Attention(nn.Module):
94
+ def __init__(self, dim, num_heads, grid_size, dropout=0.0):
95
+ super().__init__()
96
+ self.num_heads = num_heads
97
+ self.head_dim = dim // num_heads
98
+ self.dropout = float(dropout)
99
+
100
+ self.qkv = nn.Linear(dim, dim * 3, bias=False)
101
+ self.proj = nn.Linear(dim, dim)
102
+ self.proj_drop = nn.Dropout(dropout)
103
+ self.rope = RotaryEmbedding2D(self.head_dim, grid_size=grid_size)
104
+
105
+ def forward(self, x):
106
+ B, N, C = x.shape
107
+ qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, self.head_dim).permute(2, 0, 3, 1, 4)
108
+ q, k, v = qkv[0], qkv[1], qkv[2]
109
+ q, k = self.rope(q, k)
110
+
111
+ x = F.scaled_dot_product_attention(
112
+ q, k, v,
113
+ dropout_p=(self.dropout if self.training else 0.0),
114
+ is_causal=False,
115
+ )
116
+ x = x.transpose(1, 2).reshape(B, N, C)
117
+ x = self.proj(x)
118
+ return self.proj_drop(x)
119
+
120
+ class Block(nn.Module):
121
+ def __init__(self, dim, num_heads, grid_size, mlp_hidden_dim, dropout=0.0):
122
+ super().__init__()
123
+ self.norm1 = RMSNorm(dim)
124
+ self.attn = Attention(dim, num_heads=num_heads, grid_size=grid_size, dropout=dropout)
125
+ self.norm2 = RMSNorm(dim)
126
+ self.mlp = nn.Sequential(
127
+ SwiGLU(dim, mlp_hidden_dim, dim),
128
+ nn.Dropout(dropout),
129
+ )
130
+
131
+ def forward(self, x):
132
+ x = x + self.attn(self.norm1(x))
133
+ x = x + self.mlp(self.norm2(x))
134
+ return x
135
+
136
+ class CustomViTNanoV2PreTrainedModel(PreTrainedModel):
137
+ config_class = CustomViTNanoV2Config
138
+ base_model_prefix = "custom_vit"
139
+ main_input_name = "pixel_values"
140
+ _no_split_modules = ["Block"]
141
+
142
+ def _init_weights(self, module):
143
+ if isinstance(module, nn.Linear):
144
+ nn.init.trunc_normal_(module.weight, std=0.02)
145
+ if module.bias is not None:
146
+ nn.init.zeros_(module.bias)
147
+ elif isinstance(module, nn.Conv2d):
148
+ nn.init.kaiming_normal_(module.weight, mode="fan_out", nonlinearity="relu")
149
+ if module.bias is not None:
150
+ nn.init.zeros_(module.bias)
151
+ elif isinstance(module, nn.BatchNorm2d):
152
+ nn.init.ones_(module.weight)
153
+ nn.init.zeros_(module.bias)
154
+ elif isinstance(module, RMSNorm):
155
+ nn.init.ones_(module.weight)
156
+
157
+ class CustomViTNanoV2ForImageClassification(CustomViTNanoV2PreTrainedModel):
158
+ def __init__(self, config):
159
+ super().__init__(config)
160
+ self.num_labels = config.num_classes
161
+ self.config = config
162
+
163
+ self.patch_size = config.patch_size
164
+ self.grid_size = config.image_size // config.patch_size
165
+
166
+ self.patch_embed = ConvStem(
167
+ in_chans=config.in_chans,
168
+ embed_dim=config.embed_dim,
169
+ channels=tuple(config.stem_channels),
170
+ )
171
+ self.cls_token = nn.Parameter(torch.zeros(1, 1, config.embed_dim))
172
+ self.pos_drop = nn.Dropout(p=config.dropout)
173
+
174
+ self.blocks = nn.ModuleList(
175
+ [
176
+ Block(
177
+ dim=config.embed_dim,
178
+ num_heads=config.num_heads,
179
+ grid_size=self.grid_size,
180
+ mlp_hidden_dim=config.mlp_hidden_dim,
181
+ dropout=config.dropout,
182
+ )
183
+ for _ in range(config.depth)
184
+ ]
185
+ )
186
+ self.norm = RMSNorm(config.embed_dim)
187
+ self.head = nn.Linear(config.embed_dim, config.num_classes) if config.num_classes > 0 else nn.Identity()
188
+
189
+ self.post_init()
190
+
191
+ def forward(self, pixel_values=None, labels=None, return_dict=None):
192
+ return_dict = return_dict if return_dict is not None else self.config.use_return_dict
193
+
194
+ B = pixel_values.shape[0]
195
+ x = self.patch_embed(pixel_values)
196
+ x = x.flatten(2).transpose(1, 2)
197
+
198
+ cls_tokens = self.cls_token.expand(B, -1, -1)
199
+ x = torch.cat((cls_tokens, x), dim=1)
200
+ x = self.pos_drop(x)
201
+
202
+ for block in self.blocks:
203
+ x = block(x)
204
+
205
+ x = self.norm(x)
206
+ cls_out = x[:, 0]
207
+ logits = self.head(cls_out)
208
+
209
+ loss = None
210
+ if labels is not None:
211
+ loss_fct = nn.CrossEntropyLoss()
212
+ loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))
213
+
214
+ if not return_dict:
215
+ output = (logits,)
216
+ return ((loss,) + output) if loss is not None else output
217
+
218
+ return SequenceClassifierOutput(
219
+ loss=loss,
220
+ logits=logits,
221
+ )
222
+
223
+ CustomViTNanoV2ForImageClassification.register_for_auto_class("AutoModelForImageClassification")