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)
回复
我来回复-
Ivan 评论
请记住,在这两种情况下,您都处于
torch.no_grad
上下文管理器下,这实际上会禁用梯度计算。一方面,您正在对张量执行就地操作,这意味着它们的基础数据会被修改,而不会更改张量存储在内存中的引用两个,而且它的元数据保持不变,即
W
和b
是需要梯度的张量(在第一个作业中用requires_grad=True
定义)。另一方面,您正在执行异地操作,这意味着变量
W
和b
都被分配了全新的张量。实际上,异地分配会创建副本。因此W
和b
不再是赋值之前定义的,而是不同的。不仅它们的值不同,而且张量的元数据本身也发生了变化。最后,你有None
的原因是在这个上下文管理器下定义的张量不会有一个requires_grad=True
set bydefinitionof context。2年前