MCPcopy Create free account
hub / github.com/OpenGVLab/HumanBench / WindowAttention

Class WindowAttention

PATH/core/models/backbones/vitdet.py:185–256  ·  view source on GitHub ↗

Window based multi-head self attention (W-MSA) module with relative position bias. It supports both of shifted and non-shifted window. Args: dim (int): Number of input channels. window_size (tuple[int]): The height and width of the window. num_heads (int): Number of

Source from the content-addressed store, hash-verified

183
184
185class WindowAttention(nn.Module):
186 """ Window based multi-head self attention (W-MSA) module with relative position bias.
187 It supports both of shifted and non-shifted window.
188 Args:
189 dim (int): Number of input channels.
190 window_size (tuple[int]): The height and width of the window.
191 num_heads (int): Number of attention heads.
192 qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True
193 """
194
195 def __init__(self, dim, window_size, num_heads, qkv_bias=True, rel_pos_spatial=False):
196 super().__init__()
197 self.dim = dim
198 self.window_size = window_size # Wh, Ww
199 self.num_heads = num_heads
200 head_dim = dim // num_heads
201 self.scale = head_dim ** -0.5
202 self.rel_pos_spatial=rel_pos_spatial
203
204 if COMPAT:
205 q_size = window_size[0]
206 kv_size = window_size[1]
207 rel_sp_dim = 2 * q_size - 1
208 self.rel_pos_h = nn.Parameter(torch.zeros(rel_sp_dim, head_dim))
209 self.rel_pos_w = nn.Parameter(torch.zeros(rel_sp_dim, head_dim))
210
211 self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
212 self.proj = nn.Linear(dim, dim)
213
214 def forward(self, x, H, W):
215 """ Forward function.
216 Args:
217 x: input features with shape of (num_windows*B, N, C)
218 mask: (0/-inf) mask with shape of (num_windows, Wh*Ww, Wh*Ww) or None
219 """
220 B_, N, C = x.shape
221 x = x.reshape(B_, H, W, C)
222 pad_l = pad_t = 0
223 pad_r = (self.window_size[1] - W % self.window_size[1]) % self.window_size[1]
224 pad_b = (self.window_size[0] - H % self.window_size[0]) % self.window_size[0]
225
226 x = F.pad(x, (0, 0, pad_l, pad_r, pad_t, pad_b))
227 _, Hp, Wp, _ = x.shape
228
229 x = window_partition(x, self.window_size[0]) # nW*B, window_size, window_size, C
230 x = x.view(-1, self.window_size[1] * self.window_size[0], C) # nW*B, window_size*window_size, C
231
232 B_w = x.shape[0]
233 N_w = x.shape[1]
234 qkv = self.qkv(x).reshape(B_w, N_w, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)
235 q, k, v = qkv.unbind(0) # make torchscript happy (cannot use tensor as tuple) --> (batchsize, heads, len, head_dim)
236
237 attn = ((q * self.scale) @ k.transpose(-2, -1))
238 if self.rel_pos_spatial:
239 raise
240
241 attn = attn.softmax(dim=-1)
242 _attn_mask = (torch.isinf(attn) + torch.isnan(attn))

Callers 1

__init__Method · 0.70

Calls

no outgoing calls

Tested by

no test coverage detected