- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
有人可以向我解释一下以下行为吗?
import torch
import numpy as np
z = torch.tensor(np.array([1., 1.]), requires_grad=True).float()
def pre_main(z):
return z * 3.0
x = pre_main(z)
x.backward(torch.tensor([1., 1.]))
print(z.grad)
打印:
None
同时:
import torch
import numpy as np
z = torch.tensor([1., 1.], requires_grad=True).float()
def pre_main(z):
return z * 3.0
x = pre_main(z)
x.backward(torch.tensor([1., 1.]))
print(z.grad)
打印:
tensor([3., 3.])
为什么我的梯度在从 numpy 数组构建时被破坏?我该如何解决这个问题?
最佳答案
你的梯度没有被破坏:grad
返回None
因为它从未保存在grad
上属性。这是因为非叶张量在反向传播期间不存储其梯度。因此,您在运行第一个代码片段时收到的警告消息:
UserWarning: The
.grad
attribute of aTensor
that is not a leafTensor
is being accessed. Its.grad
attribute won't be populated duringautograd.backward()
.
您的 z
就是这种情况张量定义为:
>>> z = torch.tensor(np.array([1., 1.]), requires_grad=True).float()
>>> z.is_leaf
False
比较:
>>> z = torch.tensor([1., 1.], requires_grad=True).float()
>>> z.is_leaf
True
这意味着后者的梯度值将在 z.grad
中.
但请注意:
>>> z = torch.tensor(np.array([1., 1.]), requires_grad=True)
>>> z.is_leaf
True
为了进一步解释这一点:当张量首次初始化时,它是一个叶节点( .is_leaf
返回 True
)。一旦您在其上应用函数(此处 .float()
是一个就地运算符),它就不再是叶子,因为它在计算图中有父级。
所以说真的,没有什么可以修复...不过你可以做的是确保渐变保存在z.grad
上当向后传递被调用时。因此,第二个问题归结为如何在非叶节点上存储/访问梯度?。
现在,如果您想将渐变存储在 .backward()
上称呼。您可以使用 retain_grad()
如警告消息中所述:
z = torch.tensor(np.array([1., 1.]), requires_grad=True).float()
z.retain_grad()
或者,由于我们期望它是叶节点,因此使用 FloatTensor
来解决它转换numpy.array
到 torch.Tensor
:
z = torch.FloatTensor(np.array([1., 1.]))
z.requires_grad=True
或者,您可以坚持使用 torch.tensor
并提供 dtype
:
z = torch.tensor(np.array([1., 1.]), dtype=torch.float64, requires_grad=True)
关于python - 从 numpy 创建张量时缺少梯度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65532022/
我是一名优秀的程序员,十分优秀!