web-dev-qa-db-ja.com

PYTORCHのテンソルのためのAutoGrad.grad()

ネット内の2つのテンソル間の勾配を計算したいです。入力Xテンソル(バッチサイズX M)は、私に戻って出力Yテンソル(バッチサイズx n)を与える一組の畳み込み層を介して送られる。

私は新しい損失を生み出しています、そして、私はY wの勾配を知りたいのですが。 X.テンソルフローの中でのようなものは次のようになります。

tf.gradients(ys=Y, xs=X)

残念ながら、私はtorch.autograd.grad()でテストをしていましたが、それを行う方法を理解できませんでした。 “RunTimeerror: grad can be implicitly created only for scalar outputs”のようなエラーが発生します。

Y w。r.tの勾配を知りたいのであれば、torch.autograd.grad()の入力になるべきです。 NS?

9
Xbel

普通損失関数と通常の後ろ向きで簡単な実施例から始めましょう。短い計算グラフを構築し、その上にいくつかのグレード計算を行います。

コード:

_import torch
from torch.autograd import grad
import torch.nn as nn


# Create some dummy data.
x = torch.ones(2, 2, requires_grad=True)
gt = torch.ones_like(x) * 16 - 0.5  # "ground-truths" 

# We will use MSELoss as an example.
loss_fn = nn.MSELoss()

# Do some computations.
v = x + 2
y = v ** 2

# Compute loss.
loss = loss_fn(y, gt)

print(f'Loss: {loss}')

# Now compute gradients:
d_loss_dx = grad(outputs=loss, inputs=x)
print(f'dloss/dx:\n {d_loss_dx}')
_

出力:

_Loss: 42.25
dloss/dx:
(tensor([[-19.5000, -19.5000], [-19.5000, -19.5000]]),)
_

わかりました、これはうまくいきます!それでは、エラーを再現しようとしましょう。「グラードは、スカラ出力に対してのみ暗黙的に作成できます」。あなたが気づくことができるように、前の例の損失はスカラーです。 backward()grad()はデフォルトでシングルスカラー値をお届けします。loss.backward(torch.tensor(1.))。より多くの値でテンソルを渡しようとすると、エラーが発生します。

コード:

_v = x + 2
y = v ** 2

try:
    dy_hat_dx = grad(outputs=y, inputs=x)
except RuntimeError as err:
    print(err)
_

出力:

_grad can be implicitly created only for scalar outputs_

したがって、grad()を使用するときは、次のように_grad_outputs_パラメータを指定する必要があります。

コード:

_v = x + 2
y = v ** 2

dy_dx = grad(outputs=y, inputs=x, grad_outputs=torch.ones_like(y))
print(f'dy/dx:\n {dy_dx}')

dv_dx = grad(outputs=v, inputs=x, grad_outputs=torch.ones_like(v))
print(f'dv/dx:\n {dv_dx}')
_

出力:

_dy/dx:
(tensor([[6., 6.],[6., 6.]]),)

dv/dx:
(tensor([[1., 1.], [1., 1.]]),)
_

注:代わりにbackward()を使用している場合は、y.backward(torch.ones_like(y))をしてください。

6
trsvchn