ネット内の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?
普通損失関数と通常の後ろ向きで簡単な実施例から始めましょう。短い計算グラフを構築し、その上にいくつかのグレード計算を行います。
コード:
_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))
をしてください。