| 38 | |
| 39 | |
| 40 | class ComputeMatGrad: |
| 41 | |
| 42 | @classmethod |
| 43 | def __call__(cls, input, grad_output, layer): |
| 44 | if isinstance(layer, nn.Linear): |
| 45 | grad = cls.linear(input, grad_output, layer) |
| 46 | elif isinstance(layer, nn.Conv2d): |
| 47 | grad = cls.conv2d(input, grad_output, layer) |
| 48 | else: |
| 49 | raise NotImplementedError |
| 50 | return grad |
| 51 | |
| 52 | @staticmethod |
| 53 | def linear(input, grad_output, layer): |
| 54 | """ |
| 55 | :param input: batch_size * input_dim |
| 56 | :param grad_output: batch_size * output_dim |
| 57 | :param layer: [nn.module] output_dim * input_dim |
| 58 | :return: batch_size * output_dim * (input_dim + [1 if with bias]) |
| 59 | """ |
| 60 | with torch.no_grad(): |
| 61 | if layer.bias is not None: |
| 62 | input = torch.cat([input, input.new(input.size(0), 1).fill_(1)], 1) |
| 63 | input = input.unsqueeze(1) |
| 64 | grad_output = grad_output.unsqueeze(2) |
| 65 | grad = torch.bmm(grad_output, input) |
| 66 | return grad |
| 67 | |
| 68 | @staticmethod |
| 69 | def conv2d(input, grad_output, layer): |
| 70 | """ |
| 71 | :param input: batch_size * in_c * in_h * in_w |
| 72 | :param grad_output: batch_size * out_c * h * w |
| 73 | :param layer: nn.module batch_size * out_c * (in_c*k_h*k_w + [1 if with bias]) |
| 74 | :return: |
| 75 | """ |
| 76 | with torch.no_grad(): |
| 77 | input = _extract_patches(input, layer.kernel_size, layer.stride, layer.padding) |
| 78 | input = input.view(-1, input.size(-1)) # b * hw * in_c*kh*kw |
| 79 | grad_output = grad_output.transpose(1, 2).transpose(2, 3) |
| 80 | grad_output = try_contiguous(grad_output).view(grad_output.size(0), -1, grad_output.size(-1)) |
| 81 | # b * hw * out_c |
| 82 | if layer.bias is not None: |
| 83 | input = torch.cat([input, input.new(input.size(0), 1).fill_(1)], 1) |
| 84 | input = input.view(grad_output.size(0), -1, input.size(-1)) # b * hw * in_c*kh*kw |
| 85 | grad = torch.einsum('abm,abn->amn', (grad_output, input)) |
| 86 | return grad |
| 87 | |
| 88 | |
| 89 | class ComputeCovA: |
nothing calls this directly
no outgoing calls
no test coverage detected