| 79 | |
| 80 | |
| 81 | def check_gradient_numerical(channels=4, |
| 82 | grad_value=True, |
| 83 | grad_sampling_loc=True, |
| 84 | grad_attn_weight=True): |
| 85 | |
| 86 | value = torch.rand(N, S, M, channels).cuda() * 0.01 |
| 87 | sampling_locations = torch.rand(N, Lq, M, L, P, 2).cuda() |
| 88 | attention_weights = torch.rand(N, Lq, M, L, P).cuda() + 1e-5 |
| 89 | attention_weights /= attention_weights.sum(-1, |
| 90 | keepdim=True).sum(-2, |
| 91 | keepdim=True) |
| 92 | im2col_step = 2 |
| 93 | func = MSDeformAttnFunction.apply |
| 94 | |
| 95 | value.requires_grad = grad_value |
| 96 | sampling_locations.requires_grad = grad_sampling_loc |
| 97 | attention_weights.requires_grad = grad_attn_weight |
| 98 | |
| 99 | gradok = gradcheck( |
| 100 | func, |
| 101 | (value.double(), shapes, level_start_index, |
| 102 | sampling_locations.double(), attention_weights.double(), im2col_step)) |
| 103 | |
| 104 | print(f'* {gradok} check_gradient_numerical(D={channels})') |
| 105 | |
| 106 | |
| 107 | if __name__ == '__main__': |