This is a more standard version of the position embedding, very similar to the one used by the Attention is all you need paper, generalized to work on images.
| 55 | |
| 56 | |
| 57 | class PositionEmbeddingSineHW(nn.Module): |
| 58 | """This is a more standard version of the position embedding, very similar |
| 59 | to the one used by the Attention is all you need paper, generalized to work |
| 60 | on images.""" |
| 61 | def __init__(self, |
| 62 | num_pos_feats=64, |
| 63 | temperatureH=10000, |
| 64 | temperatureW=10000, |
| 65 | normalize=False, |
| 66 | scale=None): |
| 67 | super().__init__() |
| 68 | self.num_pos_feats = num_pos_feats # 128 |
| 69 | self.temperatureH = temperatureH # 20 |
| 70 | self.temperatureW = temperatureW |
| 71 | self.normalize = normalize # true |
| 72 | if scale is not None and normalize is False: |
| 73 | raise ValueError('normalize should be True if scale is passed') |
| 74 | if scale is None: |
| 75 | scale = 2 * math.pi |
| 76 | self.scale = scale |
| 77 | |
| 78 | def forward(self, tensor_list: NestedTensor): |
| 79 | x = tensor_list.tensors |
| 80 | mask = tensor_list.mask |
| 81 | assert mask is not None |
| 82 | not_mask = ~mask |
| 83 | y_embed = not_mask.cumsum(1, dtype=torch.float32) |
| 84 | x_embed = not_mask.cumsum(2, dtype=torch.float32) |
| 85 | |
| 86 | # import pdb; pdb.set_trace() |
| 87 | |
| 88 | if self.normalize: |
| 89 | eps = 1e-6 |
| 90 | y_embed = y_embed / (y_embed[:, -1:, :] + eps) * self.scale |
| 91 | x_embed = x_embed / (x_embed[:, :, -1:] + eps) * self.scale |
| 92 | |
| 93 | dim_tx = torch.arange(self.num_pos_feats, |
| 94 | dtype=torch.float32, |
| 95 | device=x.device) |
| 96 | dim_tx = self.temperatureW**(2 * (dim_tx // 2) / self.num_pos_feats) |
| 97 | pos_x = x_embed[:, :, :, None] / dim_tx |
| 98 | |
| 99 | dim_ty = torch.arange(self.num_pos_feats, |
| 100 | dtype=torch.float32, |
| 101 | device=x.device) |
| 102 | dim_ty = self.temperatureH**(2 * (dim_ty // 2) / self.num_pos_feats) |
| 103 | pos_y = y_embed[:, :, :, None] / dim_ty |
| 104 | |
| 105 | pos_x = torch.stack( |
| 106 | (pos_x[:, :, :, 0::2].sin(), pos_x[:, :, :, 1::2].cos()), |
| 107 | dim=4).flatten(3) |
| 108 | pos_y = torch.stack( |
| 109 | (pos_y[:, :, :, 0::2].sin(), pos_y[:, :, :, 1::2].cos()), |
| 110 | dim=4).flatten(3) |
| 111 | pos = torch.cat((pos_y, pos_x), dim=3).permute(0, 3, 1, 2) |
| 112 | |
| 113 | # import pdb; pdb.set_trace() |
| 114 |
no outgoing calls
no test coverage detected