Я использую Pytorch для реализации нейронной сети, которая имеет (скажем) 5 входов и 2 выхода.
class myNetwork(nn.Module):
def __init__(self):
super(myNetwork,self).__init__()
self.layer1 = nn.Linear(5,32)
self.layer2 = nn.Linear(32,2)
def forward(self,x):
x = torch.relu(self.layer1(x))
x = self.layer2(x)
return x
Очевидно, я могу использовать этот тензор (N x 5) и получить (N x 2) результат,
net = myNetwork()
nbatch = 100
inp = torch.rand([nbatch,5])
inp.requires_grad = True
out = net(inp)
Теперь я хотел бы вычислить производные вывода NN по одному элементу входного вектора (скажем, 5-му элементу) для каждого примера в пакете. Я знаю, что могу вычислить производные одного элемента вывода относительно всех входов, используя torch.autograd.grad
, и я мог бы использовать это следующим образом:
deriv = torch.zeros([nbatch,2])
for i in range(nbatch):
for j in range(2):
deriv[i,j] = torch.autograd.grad(out[i,j],inp,retain_graph=True)[0][i,4]
Однако это кажется очень неэффективным: он вычисляет градиент out[i,j]
по отношению к каждому элементу в пакете, а затем отбрасывает все, кроме одного. Есть ли лучший способ сделать это?