(self, x, xm, mask=None, img_size = (128, 128))
| 790 | f"win_size={self.win_size}, shift_size={self.shift_size}, mlp_ratio={self.mlp_ratio}" |
| 791 | |
| 792 | def forward(self, x, xm, mask=None, img_size = (128, 128)): |
| 793 | B, L, C = x.shape |
| 794 | H = img_size[0] |
| 795 | W = img_size[1] |
| 796 | assert L == W * H, \ |
| 797 | f"Input image size ({H}*{W} doesn't match model ({L})." |
| 798 | |
| 799 | ## input mask |
| 800 | if mask != None: |
| 801 | input_mask = F.interpolate(mask, size=(H,W)).permute(0,2,3,1) |
| 802 | input_mask_windows = window_partition(input_mask, self.win_size) # nW, win_size, win_size, 1 |
| 803 | attn_mask = input_mask_windows.view(-1, self.win_size * self.win_size) # nW, win_size*win_size |
| 804 | attn_mask = attn_mask.unsqueeze(2)*attn_mask.unsqueeze(1) # nW, win_size*win_size, win_size*win_size |
| 805 | attn_mask = attn_mask.masked_fill(attn_mask!=0, float(-100.0)).masked_fill(attn_mask == 0, float(0.0)) |
| 806 | else: |
| 807 | attn_mask = None |
| 808 | |
| 809 | ## shift mask |
| 810 | if self.shift_size > 0: |
| 811 | # calculate attention mask for SW-MSA |
| 812 | shift_mask = torch.zeros((1, H, W, 1)).type_as(x) |
| 813 | h_slices = (slice(0, -self.win_size), |
| 814 | slice(-self.win_size, -self.shift_size), |
| 815 | slice(-self.shift_size, None)) |
| 816 | w_slices = (slice(0, -self.win_size), |
| 817 | slice(-self.win_size, -self.shift_size), |
| 818 | slice(-self.shift_size, None)) |
| 819 | cnt = 0 |
| 820 | for h in h_slices: |
| 821 | for w in w_slices: |
| 822 | shift_mask[:, h, w, :] = cnt |
| 823 | cnt += 1 |
| 824 | shift_mask_windows = window_partition(shift_mask, self.win_size) # nW, win_size, win_size, 1 |
| 825 | shift_mask_windows = shift_mask_windows.view(-1, self.win_size * self.win_size) # nW, win_size*win_size |
| 826 | shift_attn_mask = shift_mask_windows.unsqueeze(1) - shift_mask_windows.unsqueeze(2) # nW, win_size*win_size, win_size*win_size |
| 827 | shift_attn_mask = shift_attn_mask.masked_fill(shift_attn_mask != 0, float(-100.0)).masked_fill(shift_attn_mask == 0, float(0.0)) |
| 828 | attn_mask = attn_mask + shift_attn_mask if attn_mask is not None else shift_attn_mask |
| 829 | |
| 830 | shortcut = x |
| 831 | x = self.norm1(x) |
| 832 | |
| 833 | |
| 834 | |
| 835 | x = x.view(B, H, W, C) |
| 836 | xm = xm.permute(0, 2, 3, 1) |
| 837 | # cyclic shift |
| 838 | if self.shift_size > 0: |
| 839 | shifted_x = torch.roll(x, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2)) |
| 840 | shifted_m = torch.roll(xm, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2)) |
| 841 | else: |
| 842 | shifted_x = x |
| 843 | shifted_m = xm |
| 844 | |
| 845 | # partition windows |
| 846 | x_windows = window_partition(shifted_x, self.win_size) # nW*B, win_size, win_size, C N*C->C |
| 847 | x_windows = x_windows.view(-1, self.win_size * self.win_size, C) # nW*B, win_size*win_size, C |
| 848 | m_windows = window_partition(shifted_m, self.win_size) # nW*B, win_size, win_size, C N*C->C |
| 849 | m_windows = m_windows.view(-1, self.win_size * self.win_size, 1) # nW*B, win_size*win_size, C |
nothing calls this directly
no test coverage detected