Forward function. Args: x: input features with shape of (num_windows*B, N, C) mask: (0/-inf) mask with shape of (num_windows, Wh*Ww, Wh*Ww) or None
(self, x, mask=None)
| 111 | self.softmax = nn.Softmax(dim=-1) |
| 112 | |
| 113 | def forward(self, x, mask=None): |
| 114 | """ Forward function. |
| 115 | |
| 116 | Args: |
| 117 | x: input features with shape of (num_windows*B, N, C) |
| 118 | mask: (0/-inf) mask with shape of (num_windows, Wh*Ww, Wh*Ww) or None |
| 119 | """ |
| 120 | B_, N, C = x.shape |
| 121 | qkv = self.qkv(x).reshape(B_, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4) |
| 122 | q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple) |
| 123 | q = q * self.scale |
| 124 | attn = (q @ k.transpose(-2, -1)) |
| 125 | relative_position_bias = self.relative_position_bias_table[self.relative_position_index.view(-1)].view( |
| 126 | self.window_size[0] * self.window_size[1], self.window_size[0] * self.window_size[1], -1) # Wh*Ww,Wh*Ww,nH |
| 127 | relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous() # nH, Wh*Ww, Wh*Ww |
| 128 | attn = attn + relative_position_bias.unsqueeze(0) |
| 129 | |
| 130 | if mask is not None: |
| 131 | nW = mask.shape[0] |
| 132 | attn = attn.view(B_ // nW, nW, self.num_heads, N, N) + mask.unsqueeze(1).unsqueeze(0) |
| 133 | attn = attn.view(-1, self.num_heads, N, N) |
| 134 | attn = self.softmax(attn) |
| 135 | else: |
| 136 | attn = self.softmax(attn) |
| 137 | |
| 138 | attn = self.attn_drop(attn) |
| 139 | |
| 140 | x = (attn @ v).transpose(1, 2).reshape(B_, N, C) # cat op |
| 141 | x = self.proj(x) |
| 142 | x = self.proj_drop(x) |
| 143 | return x |
| 144 | |
| 145 | |
| 146 | class SwinTransformerBlock(nn.Module): |
nothing calls this directly
no outgoing calls
no test coverage detected