【问题标题】:Computing intermediate gradients using backward method in Pytorch在 Pytorch 中使用后向方法计算中间梯度
【发布时间】:2020-12-05 06:42:04
【问题描述】:

我无法理解 pytorch 中的 backward 方法

x1 = tensor(2.).requires_grad_()
x2 = tensor(3.).requires_grad_() # or x2 = tensor(3.)
x3 = x1 + x2

l = (x3**2).sum()
l.backward()

print(x1)
print(x3)
print(x1.grad)
print(x3.grad)

结果是

tensor(2., requires_grad=True)
tensor(5., grad_fn=<AddBackward0>)
tensor(10.)
None

为什么x3.grad 还是None?不应该是tensor(10.)吗?

当我运行以下代码行时,x3.grad 被评估为tensor(10.)

x3 = tensor(5.).requires_grad_()
l = (x3**2).mean()
l.backward()
print(x3.grad)

【问题讨论】:

    标签: pytorch


    【解决方案1】:

    如果您在第一个示例中打印 x3.grad,您可能会注意到 torch 输出警告:

    UserWarning:正在访问不是叶张量的 张量的.grad 属性。在autograd.backward() 期间不会填充其.grad 属性。如果您确实想要非叶张量的梯度,请在非叶张量上使用.retain_grad()。如果您错误地访问了非叶张量,请确保您访问的是叶张量。请参阅here 了解更多信息。

    为了节省内存,不缓冲非叶张量(非用户创建的张量)的梯度。

    如果您希望看到这些渐变,但您可以在创建图形之前调用.retain_grad()(即在调用.backward() 之前)保留x3 上的渐变。

    x3.retain_grad()
    l.backward()
    print(x3.grad)
    

    确实会输出tensor(10.)

    【讨论】:

    • 谢谢@Ivan。非叶(或非用户创建)张量是什么意思?
    • user-created 未按字面定义(如 x1x2 是)。看,x3 是非叶的,因为它依赖于图中的其他张量。在后向传递中,将首先运行l,然后运行x3,最后找到x1x2,即图中的两个叶子。
    • 我想我明白了。即使 pytorch 在计算图中使用了 x3,它也没有将梯度保存在中间节点上以节省内存。非常感谢@Ivan
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-16
    • 1970-01-01
    • 2020-05-12
    相关资源
    最近更新 更多