PyTorch线性回归报错:张量无需梯度且无grad_fn的解决方法
PyTorch线性回归梯度清零报错解决方案
问题概述
编写PyTorch线性回归程序时,手动更新权重、偏置并清零梯度后,程序仅运行一轮就触发报错:RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn。
错误原因
问题出在权重与偏置的更新逻辑:
在with torch.no_grad()代码块中,使用w = w - w.grad * 1e-5和b = b - b.grad * 1e-5的赋值方式,会生成全新的张量对象。新的w和b不再保留原张量的requires_grad=True属性,也没有梯度追踪所需的grad_fn。第二轮循环执行loss.backward()时,无法对这些普通张量进行反向传播,从而触发报错。
修正方案
需对原张量进行原地修改,保持张量对象不变的同时保留梯度追踪属性:
- 用原地减法操作替代赋值操作,比如
w -= w.grad * 1e-5或w.sub_(w.grad * 1e-5) - 梯度清零可使用
w.grad.zero_()(原地清零,复用内存更高效)或w.grad = None
完整修正代码
import torch # 示例输入与目标张量(实际使用时替换为自己的数据) inputs_t = torch.randn(10, 3) targets_t = torch.randn(10, 2) # weights and biases w = torch.randn(2,3, requires_grad=True) b = torch.randn(2, requires_grad=True) print(w.dtype, b.dtype) # a linear function def model(x): return x @ w.t() + b # loss function def mse(t1, t2): diff = (t1-t2)**2 return torch.mean(diff) # do this in a loop for _ in range(100): preds = model(inputs_t) loss = mse(targets_t, preds) loss.backward() # print(loss) print(w.grad, b.grad) print("==============") with torch.no_grad(): # 原地更新权重和偏置,避免创建新张量 w -= w.grad * 1e-5 b -= b.grad * 1e-5 # 原地清零梯度 w.grad.zero_() b.grad.zero_()
额外说明
with torch.no_grad()的作用是临时禁用梯度计算,避免更新操作被追踪,这部分逻辑是正确的- 若使用
w.grad = None清零梯度,后续反向传播时PyTorch会重新创建梯度张量,功能上与zero_()一致,但zero_()内存复用效率更高
内容的提问来源于stack exchange,提问作者jodh singh
相关产品推荐
相关产品推荐

