Расчет карт активации пространственных градиентов в PyTorch - PullRequest
0 голосов
/ 02 апреля 2019

У меня есть 4-мерный тензор карт активации, то есть X размера (bs, channels, dim, dim); например,

import torch
bs = 3
channels = 512
dim = 64
X = torch.rand(bs, channels, dim, dim)

Я хочу вычислить (x, y) -градиенты карт активации (которые грубо рассматриваются как «изображения»). Я думаю, что это можно сделать с помощью двумерной свертки с фиксированными весами. Для x-градиента, например,

import numpy as np
import torch.nn as nn

grad_x_weights = np.array([[1, 0, -1],
                           [2, 0, -2],
                           [1, 0, -1]])
conv_x = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1, bias=False)
conv_x.weight = nn.Parameter(torch.from_numpy(grad_x_weights).float().expand(1, 512, 3,3))

grad_x = conv_x(X)

Это (как и ожидалось) даст результат размером (3, 1, 64, 64), но я хотел бы иметь градиент карт активации для каждой карты активации, поэтому что-то размером (3, 512, 64, 64) таким образом, что grad_x[i, j, :, :] будет иметь x-градиент j-й карты активации i-го входа.

Наконец, я хотел бы установить grad_x_weights как необучаемый, чтобы conv_x всегда вычислял градиенты карт активации.

Спасибо!

1 Ответ

0 голосов
/ 02 апреля 2019

Вот, пожалуйста:

import torch
import torch.nn.functional as F

bs = 3
channels = 512
dim = 64
X = torch.rand(bs, channels, dim, dim)

grad_x_weights = torch.tensor([
    [1, 0, -1],
    [2, 0, -2],
    [1, 0, -1]
], dtype=torch.float32)
grad_x_weights = grad_x_weights.expand(channels, 1, 3, 3)

grad_x = F.conv2d(X, grad_x_weights, groups=X.shape[1], padding=1)

Я

  1. Используя torch.nn.functional версию conv2d, поскольку по умолчаниюобучаемое
  2. Использование параметра groups=in_channels, который здесь означает, что каждый входной канал свертывается отдельно в один выходной канал
  3. Расширение ядра вдоль первого (out_channels)размерность до channels для сохранения той же размерности на выходе
...