| 53 | self.register_buffer("relative_position_index", relative_position_index) |
| 54 | |
| 55 | def forward(self, x, mask=None): |
| 56 | |
| 57 | B, C, H, W = x.size() |
| 58 | r1, r2 = H // self.window_size[0], W // self.window_size[1] |
| 59 | |
| 60 | x_total = einops.rearrange(x, 'b c (r1 h1) (r2 w1) -> b (r1 r2) (h1 w1) c', h1=self.window_size[0], w1=self.window_size[1]) # B x Nr x Ws x C |
| 61 | |
| 62 | x_total = einops.rearrange(x_total, 'b m n c -> (b m) n c') |
| 63 | |
| 64 | qkv = self.proj_qkv(x_total) # B' x N x 3C |
| 65 | q, k, v = torch.chunk(qkv, 3, dim=2) |
| 66 | |
| 67 | q = q * self.scale |
| 68 | q, k, v = [einops.rearrange(t, 'b n (h c1) -> b h n c1', h=self.heads) for t in [q, k, v]] |
| 69 | attn = torch.einsum('b h m c, b h n c -> b h m n', q, k) |
| 70 | |
| 71 | relative_position_bias = self.relative_position_bias_table[self.relative_position_index.view(-1)].view( |
| 72 | self.window_size[0] * self.window_size[1], self.window_size[0] * self.window_size[1], -1) # Wh*Ww,Wh*Ww,nH |
| 73 | relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous() # nH, Wh*Ww, Wh*Ww |
| 74 | attn_bias = relative_position_bias |
| 75 | attn = attn + attn_bias.unsqueeze(0) |
| 76 | |
| 77 | if mask is not None: |
| 78 | # attn : (b * nW) h w w |
| 79 | # mask : nW ww ww |
| 80 | nW, ww, _ = mask.size() |
| 81 | attn = einops.rearrange(attn, '(b n) h w1 w2 -> b n h w1 w2', n=nW, h=self.heads, w1=ww, w2=ww) + mask.reshape(1, nW, 1, ww, ww) |
| 82 | attn = einops.rearrange(attn, 'b n h w1 w2 -> (b n) h w1 w2') |
| 83 | attn = self.attn_drop(attn.softmax(dim=3)) |
| 84 | |
| 85 | x = torch.einsum('b h m n, b h n c -> b h m c', attn, v) |
| 86 | x = einops.rearrange(x, 'b h n c1 -> b n (h c1)') |
| 87 | x = self.proj_drop(self.proj_out(x)) # B' x N x C |
| 88 | x = einops.rearrange(x, '(b r1 r2) (h1 w1) c -> b c (r1 h1) (r2 w1)', r1=r1, r2=r2, h1=self.window_size[0], w1=self.window_size[1]) # B x C x H x W |
| 89 | |
| 90 | return x, None, None |
| 91 | |
| 92 | |
| 93 | class ShiftWindowAttention(LocalAttention): |