Получение градиента векторизованной функции в pytorch - PullRequest
0 голосов
/ 18 апреля 2019

Я новичок в 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 Ответ

2 голосов
/ 18 апреля 2019

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

По сути, когда вы вызываете 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)
...