Pytorch no_grad 对 a = a – b 和 a -= b 类型的操作有何作用?

社会演员多 pytorch 421

原文标题How does Pytorch no_grad function for a = a – b and a -= b type of operation?

import torch

def model(x, W, b):
    return x@W + b


def mse(t1, t2):
    diff = t1 - t2
    return torch.sum(diff * diff) / diff.numel()

inputs = torch.rand(2, 3, requires_grad=True)
targets = torch.rand( 2,2, requires_grad=True)

W = torch.rand(3, 2, requires_grad=True)
b = torch.rand(2, requires_grad=True)

pred = model(inputs, W, b)

loss = mse(pred, targets)
loss.backward()

print(W.grad)
print(b.grad)
with torch.no_grad():
    W -= W.grad * 1e-5
    b -= b.grad * 1e-5
print(W.grad)
print(b.grad)

对于上面的示例,最后 2 个 print 语句的输出与前两个 print 语句的输出相同。

但是,对于下面的代码片段,最后 2 个打印语句给出的结果为None。我不明白为什么会这样?

print(W.grad)
print(b.grad)
with torch.no_grad():
    W = W - W.grad * 1e-5
    b = b -  b.grad * 1e-5
print(W.grad)
print(b.grad)

原文链接:https://stackoverflow.com//questions/71420187/how-does-pytorch-no-grad-function-for-a-a-b-and-a-b-type-of-operation

回复

我来回复
  • Ivan的头像
    Ivan 评论

    请记住,在这两种情况下,您都处于torch.no_grad上下文管理器下,这实际上会禁用梯度计算。

    一方面,您正在对张量执行就地操作,这意味着它们的基础数据会被修改,而不会更改张量存储在内存中的引用两个,而且它的元数据保持不变,即Wb是需要梯度的张量(在第一个作业中用requires_grad=True定义)。

    另一方面,您正在执行异地操作,这意味着变量Wb都被分配了全新的张量。实际上,异地分配会创建副本。因此Wb不再是赋值之前定义的,而是不同的。不仅它们的值不同,而且张量的元数据本身也发生了变化。最后,你有None的原因是在这个上下文管理器下定义的张量不会有一个requires_grad=Trueset bydefinitionof context。

    2年前 0条评论