Я использую инструмент autograd
в PyTorch
и оказался в ситуации, когда мне нужно получить доступ к значениям в одномерном тензоре с помощью целочисленного индекса. Что-то вроде этого:
def basic_fun(x_cloned):
res = []
for i in range(len(x)):
res.append(x_cloned[i] * x_cloned[i])
print(res)
return Variable(torch.FloatTensor(res))
def get_grad(inp, grad_var):
A = basic_fun(inp)
A.backward()
return grad_var.grad
x = Variable(torch.FloatTensor([1, 2, 3, 4, 5]), requires_grad=True)
x_cloned = x.clone()
print(get_grad(x_cloned, x))
Я получаю следующее сообщение об ошибке:
[tensor(1., grad_fn=<ThMulBackward>), tensor(4., grad_fn=<ThMulBackward>), tensor(9., grad_fn=<ThMulBackward>), tensor(16., grad_fn=<ThMulBackward>), tensor(25., grad_fn=<ThMulBackward>)]
Traceback (most recent call last):
File "/home/mhy/projects/pytorch-optim/predict.py", line 74, in <module>
print(get_grad(x_cloned, x))
File "/home/mhy/projects/pytorch-optim/predict.py", line 68, in get_grad
A.backward()
File "/home/mhy/.local/lib/python3.5/site-packages/torch/tensor.py", line 93, in backward
torch.autograd.backward(self, gradient, retain_graph, create_graph)
File "/home/mhy/.local/lib/python3.5/site-packages/torch/autograd/__init__.py", line 90, in backward
allow_unreachable=True) # allow_unreachable flag
RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn
Я в целом немного скептически отношусь к тому, как использование клонированной версии переменной должно сохранять эту переменную при вычислении градиента. Сама переменная фактически не используется при вычислении A
, поэтому, когда вы вызываете A.backward()
, она не должна быть частью этой операции.
Я ценю вашу помощь с этим подходом или если есть лучший способ избежать потери истории градиента и по-прежнему индексировать через одномерный тензор с requires_grad=True
!
** Редактировать (15 сентября): **
res
- это список нульмерных тензоров, содержащих значения в квадрате от 1 до 5. Чтобы объединить в один тензор, содержащий [1.0, 4.0, ..., 25.0], я изменил return Variable(torch.FloatTensor(res))
на torch.stack(res, dim=0)
, что дает tensor([ 1., 4., 9., 16., 25.], grad_fn=<StackBackward>)
.
Однако я получаю эту новую ошибку, вызванную строкой A.backward()
.
Traceback (most recent call last):
File "<project_path>/playground.py", line 22, in <module>
print(get_grad(x_cloned, x))
File "<project_path>/playground.py", line 16, in get_grad
A.backward()
File "/home/mhy/.local/lib/python3.5/site-packages/torch/tensor.py", line 93, in backward
torch.autograd.backward(self, gradient, retain_graph, create_graph)
File "/home/mhy/.local/lib/python3.5/site-packages/torch/autograd/__init__.py", line 84, in backward
grad_tensors = _make_grads(tensors, grad_tensors)
File "/home/mhy/.local/lib/python3.5/site-packages/torch/autograd/__init__.py", line 28, in _make_grads
raise RuntimeError("grad can be implicitly created only for scalar outputs")
RuntimeError: grad can be implicitly created only for scalar outputs
PyTorch
версия. Я выполнил ваш код в версии0.3.1
, и он работал как надо. Ошибок нет. - person papabiceps   schedule 14.09.2018