web-dev-qa-db-ja.com

autogradが中間変数の勾配を生成しないのはなぜですか?

グラデーションがどのように表され、autogradがどのように機能するかについて頭を悩ませようとしています。

import torch
from torch.autograd import Variable

x = Variable(torch.Tensor([2]), requires_grad=True)
y = x * x
z = y * y

z.backward()

print(x.grad)
#Variable containing:
#32
#[torch.FloatTensor of size 1]

print(y.grad)
#None

yの勾配が生成されないのはなぜですか? y.grad = dz/dyの場合、少なくともy.grad = 2*yのような変数を生成するべきではありませんか?

11
foobar

デフォルトでは、勾配は葉の変数に対してのみ保持されます。非リーフ変数の勾配は、後で検査するために保持されません。これは、メモリを節約するために設計によって行われました。

-soumith chintala

参照: https://discuss.pytorch.org/t/why-cant-i-see-grad-of-an-intermediate-variable/94

オプション1:

y.retain_grad()を呼び出します

x = Variable(torch.Tensor([2]), requires_grad=True)
y = x * x
z = y * y

y.retain_grad()

z.backward()

print(y.grad)
#Variable containing:
# 8
#[torch.FloatTensor of size 1]

出典: https://discuss.pytorch.org/t/why-cant-i-see-grad-of-an-intermediate-variable/94/16

オプション2:

hookを登録します。これは基本的に、その勾配が計算されるときに呼び出される関数です。次に、保存、割り当て、印刷など、何でもできます...

from __future__ import print_function
import torch
from torch.autograd import Variable

x = Variable(torch.Tensor([2]), requires_grad=True)
y = x * x
z = y * y

y.register_hook(print) ## this can be anything you need it to be

z.backward()

出力:

Variable containing:  8 [torch.FloatTensor of size 1

出典: https://discuss.pytorch.org/t/why-cant-i-see-grad-of-an-intermediate-variable/94/2

参照: https://discuss.pytorch.org/t/why-cant-i-see-grad-of-an-intermediate-variable/94/7

15
T. Scharf