web-dev-qa-db-ja.com

PyTorch autograd --gradは、スカラー出力に対してのみ暗黙的に作成できます

autogradPyTorchツールを使用していますが、整数インデックスを使用して1Dテンソルの値にアクセスする必要がある状況にあります。このようなもの:

_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_を使用した1Dテンソルを介してインデックスを作成するためのより良い方法がある場合は、ご協力いただきありがとうございます。

**編集(9月15日):**

resは、1から5の2乗値を含むゼロ次元テンソルのリストです。[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
_
5
mhyousefi

basic_funを次のように変更しました。これにより、問題が解決しました。

def basic_fun(x_cloned):
    res = torch.FloatTensor([0])
    for i in range(len(x)):
        res += x_cloned[i] * x_cloned[i]
    return res

このバージョンはスカラー値を返します。

0
mhyousefi

basic_fun関数では、res変数はすでにtorch-autograd-Variableであり、再度変換する必要はありません。私見では

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))
    return res[0]

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))
1
Salih Karagoz