请考虑以下代码块:
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 中计算图形的基本问题。我希望得到一些澄清。谢谢!
2条答案
按热度按时间e4yzc0pl1#
当你把
x
设置成一个Tensor除以某个标量时,x
就不再是PyTorch中所谓的“叶子”Tensor
了。(其是具有表示诸如Tensor的对象的节点和表示数学运算的边的DAG图)。更具体地,它是一个Tensor,它不是通过由autograd
引擎跟踪的一些计算操作创建的。在你的例子中,
torch.ones(n, requires_grad=True)
是一个叶Tensor,但你不能直接在代码中访问它。不为非叶Tensor保留grad
的原因是,通常当你训练一个网络时,权重和偏差是叶Tensor,它们是我们需要梯度的地方。如果要访问非叶Tensor的渐变,则应调用
retain_grad
函数,这意味着应在代码中添加:在赋值给x之后。
798qvoo82#
你确实需要维护grad。但是,最简单的修正方法是使用torch.div()函数。