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)
| 134 | self.softmax = nn.Softmax(dim=-1) |
| 135 | |
| 136 | def forward(self, x, mask=None): |
| 137 | """Forward function. |
| 138 | Args: |
| 139 | x: input features with shape of (num_windows*B, N, C) |
| 140 | mask: (0/-inf) mask with shape of (num_windows, Wh*Ww, Wh*Ww) or None |
| 141 | """ |
| 142 | B_, N, C = x.shape |
| 143 | qkv = ( |
| 144 | self.qkv(x) |
| 145 | .reshape(B_, N, 3, self.num_heads, C // self.num_heads) |
| 146 | .permute(2, 0, 3, 1, 4) |
| 147 | ) |
| 148 | q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple) |
| 149 | |
| 150 | q = q * self.scale |
| 151 | attn = q @ k.transpose(-2, -1) |
| 152 | |
| 153 | relative_position_bias = self.relative_position_bias_table[ |
| 154 | self.relative_position_index.view(-1) |
| 155 | ].view( |
| 156 | self.window_size[0] * self.window_size[1], self.window_size[0] * self.window_size[1], -1 |
| 157 | ) # Wh*Ww,Wh*Ww,nH |
| 158 | relative_position_bias = relative_position_bias.permute( |
| 159 | 2, 0, 1 |
| 160 | ).contiguous() # nH, Wh*Ww, Wh*Ww |
| 161 | attn = attn + relative_position_bias.unsqueeze(0) |
| 162 | |
| 163 | if mask is not None: |
| 164 | nW = mask.shape[0] |
| 165 | attn = attn.view(B_ // nW, nW, self.num_heads, N, N) + mask.unsqueeze(1).unsqueeze(0) |
| 166 | attn = attn.view(-1, self.num_heads, N, N) |
| 167 | attn = self.softmax(attn) |
| 168 | else: |
| 169 | attn = self.softmax(attn) |
| 170 | |
| 171 | attn = self.attn_drop(attn) |
| 172 | |
| 173 | x = (attn @ v).transpose(1, 2).reshape(B_, N, C) |
| 174 | x = self.proj(x) |
| 175 | x = self.proj_drop(x) |
| 176 | |
| 177 | return x |
| 178 | |
| 179 | |
| 180 | class SwinTransformerBlock(nn.Module): |
nothing calls this directly
no outgoing calls
no test coverage detected