Получение градиента векторизованной функции в pytorch

#python #pytorch #derivative #autodiff

#python #pytorch #производная #автодифф

Вопрос:

Я новичок в PyTorch и хочу делать то, что, как я полагаю, очень просто, но у меня возникают большие трудности.

У меня есть функция sin(x) * cos(x) x^2 , и я хочу получить производную от этой функции в любой точке.

Если я делаю это с одной точкой, это отлично работает как

 x = torch.autograd.Variable(torch.Tensor([4]),requires_grad=True)
y = torch.sin(x)*torch.cos(x) torch.pow(x,2)
y.backward()
print(x.grad) # outputs tensor([7.8545])
 

Тем не менее, я хочу иметь возможность передавать вектор как x и оценивать производную по элементам. Например:

 Input: [4., 4., 4.,]
Output: tensor([7.8545, 7.8545, 7.8545])
 

Но, похоже, я не могу заставить это работать.

Я попытался просто сделать

 x = torch.tensor([4., 4., 4., 4.], requires_grad=True)
out = torch.sin(x)*torch.cos(x) x.pow(2)
out.backward()
print(x.grad)
 

Но я получаю сообщение об ошибке «RuntimeError: grad может быть неявно создан только для скалярных выходов»

Как мне настроить этот код для векторов?

Заранее спасибо,

Ответ №1:

Здесь вы можете найти соответствующее обсуждение вашей ошибки.

По сути, при вызове backward() без аргументов он неявно преобразуется в backward(torch.Tensor([1])) , где torch.Tensor([1]) — выходное значение, относительно которого вычисляются градиенты.

Если вы передаете 4 (или более) входные данные, каждому требуется значение, относительно которого вы вычисляете градиент. Вы можете передать torch.ones_like явно backward , как это:

 import torch

x = torch.tensor([4.0, 2.0, 1.5, 0.5], requires_grad=True)
out = torch.sin(x) * torch.cos(x)   x.pow(2)
# Pass tensor of ones, each for each item in x
out.backward(torch.ones_like(x))
print(x.grad)
 

Комментарии:

1. Потрясающе. Большое спасибо!