PyTorch中中间节点梯度的计算

PyTorch中中间节点梯度的计算,pytorch,Pytorch,我在试着学习在PyTorch中autograd是如何工作的。在下面的简单程序中,我不明白为什么w.r.t W1和W2的损失梯度为零。据我从文档中了解,W1和W2是易变的,因此无法计算梯度。是这样吗?我的意思是,我怎么能对损耗的w.r.t中间节点求导呢?有人能解释一下我在这里遗漏了什么吗 import torch import torch.autograd as tau W = tau.Variable(torch.FloatTensor([[0, 1]]), requires_grad=Tru

我在试着学习在PyTorch中autograd是如何工作的。在下面的简单程序中,我不明白为什么w.r.t W1和W2的损失梯度为零。据我从文档中了解,W1和W2是易变的,因此无法计算梯度。是这样吗?我的意思是,我怎么能对损耗的w.r.t中间节点求导呢?有人能解释一下我在这里遗漏了什么吗

import torch
import torch.autograd as tau

W = tau.Variable(torch.FloatTensor([[0, 1]]), requires_grad=True)
a = tau.Variable(torch.FloatTensor([[2, 2]]), requires_grad=False)
b = tau.Variable(torch.FloatTensor([[3, 3]]), requires_grad=False)

W1 = W  + a * a
W2 = W1 - b * b * b
Z = W2 * W2

print 'W:', W
print 'W1:', W1
print 'W2:', W2
print 'Z:', Z

loss = torch.sum((Z - 3) * (Z - 3))
print 'loss:', loss

# free W gradient buffer in case you are running this cell more than 2 times
if W.grad is not None: W.grad.data.zero_()

loss.backward()
print 'W.grad:', W.grad

# all of them are None
print 'W1.grad:', W1.grad
print 'W2.grad:', W2.grad
print 'a.grad:', a.grad
print 'b.grad:', b.grad
print 'Z.grad:', Z.grad

当需要时,中间渐变是累积的,但为了节省内存,默认情况下它们不会保留在python对象中。 只有设置为requires_grad=True的叶变量的梯度将被保留,所以请赢得您的示例

保留中间渐变的一种方法是注册挂钩。这项工作的一个重点是留级 在您的示例中,如果您编写W2.retain_grad,W2的中间渐变将显示在W2.grad中

W1和W2不是易失性的。您可以通过访问它们的易失性属性(即:W1.volatile)进行检查,因为它们不是叶变量,如W、a和b。相反,需要计算它们的梯度,请参见它们的requires_grad属性。 如果只有一个叶变量是volatile的,那么就不会构造整个反向图。您可以通过创建volatile并查看损失梯度函数进行检查

a = tau.Variable(torch.FloatTensor([[2, 2]]), volatile=True)
# ...
assert loss.grad_fn is None
总结

波动性意味着没有梯度计算:在推理模式中很有用 只有一个叶变量集可以禁用梯度计算 需要梯度意味着梯度计算。中间层是否暴露 只有一个叶变量需要梯度才能启用梯度计算
当需要时,中间渐变是累积的,但为了节省内存,默认情况下它们不会保留在python对象中。 只有设置为requires_grad=True的叶变量的梯度将被保留,所以请赢得您的示例

保留中间渐变的一种方法是注册挂钩。这项工作的一个重点是留级 在您的示例中,如果您编写W2.retain_grad,W2的中间渐变将显示在W2.grad中

W1和W2不是易失性的。您可以通过访问它们的易失性属性(即:W1.volatile)进行检查,因为它们不是叶变量,如W、a和b。相反,需要计算它们的梯度,请参见它们的requires_grad属性。 如果只有一个叶变量是volatile的,那么就不会构造整个反向图。您可以通过创建volatile并查看损失梯度函数进行检查

a = tau.Variable(torch.FloatTensor([[2, 2]]), volatile=True)
# ...
assert loss.grad_fn is None
总结

波动性意味着没有梯度计算:在推理模式中很有用 只有一个叶变量集可以禁用梯度计算 需要梯度意味着梯度计算。中间层是否暴露 只有一个叶变量需要梯度才能启用梯度计算
谢谢你的回答。现在清楚多了。嗨,那是哪个pytorch版本?在0.3和0.4中,即使我设置了W2.retain_grad=True,我也没有得到W2.grad.Hi,我认为它是v0.3。为了在W2上保留中间梯度,您是否尝试过在W2上使用requires_grad=True初始化W变量,如OP'问题中所述,并调用retain_grad?此外,将W2.retain_grad设置为True将覆盖旨在通过钩子有效保留渐变的方法谢谢您的回答。现在清楚多了。嗨,那是哪个pytorch版本?在0.3和0.4中,即使我设置了W2.retain_grad=True,我也没有得到W2.grad.Hi,我认为它是v0.3。为了在W2上保留中间梯度,您是否尝试过在W2上使用requires_grad=True初始化W变量,如OP'问题中所述,并调用retain_grad?此外,将W2.retain_grad设置为True将覆盖旨在通过挂钩有效保持渐变的方法