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

Class WindowAttention

PATH/core/models/backbones/vit.py:176–247  ·  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

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

Callers 1

__init__Method · 0.70

Calls

no outgoing calls

Tested by

no test coverage detected