除以标量时pyTorch渐变变为无

vzgqcmou  于 2022-12-13  发布在  其他
关注(0)|答案(2)|浏览(118)

请考虑以下代码块:

import torch as torch

n=10
x = torch.ones(n, requires_grad=True)/n
y = torch.rand(n)
z = torch.sum(x*y)
z.backward()
print(x.grad) # results in None
print(y)

但是,如果我通过去掉标量乘法(x = torch.ones(n, requires_grad=True))来改变x的定义,那么我确实得到了一个非None的梯度,它等价于y。
我在谷歌上搜索了一堆关于这个问题的文章,我认为它反映了一些我不理解的关于 Torch 中计算图形的基本问题。我希望得到一些澄清。谢谢!

e4yzc0pl

e4yzc0pl1#

当你把x设置成一个Tensor除以某个标量时,x就不再是PyTorch中所谓的“叶子”Tensor了。(其是具有表示诸如Tensor的对象的节点和表示数学运算的边的DAG图)。更具体地,它是一个Tensor,它不是通过由autograd引擎跟踪的一些计算操作创建的。
在你的例子中,torch.ones(n, requires_grad=True)是一个叶Tensor,但你不能直接在代码中访问它。不为非叶Tensor保留grad的原因是,通常当你训练一个网络时,权重和偏差是叶Tensor,它们是我们需要梯度的地方。
如果要访问非叶Tensor的渐变,则应调用retain_grad函数,这意味着应在代码中添加:

x.retain_grad()

在赋值给x之后。

798qvoo8

798qvoo82#

你确实需要维护grad。但是,最简单的修正方法是使用torch.div()函数。

相关问题