PyTorch报错:'NoneType'对象无'zero_'属性,如何解决梯度重置问题?
解决PyTorch中
AttributeError: 'NoneType' object has no attribute 'zero_'错误 错误原因
你在更新权重w和偏置b时,使用了w = w - w.grad*1e-5这类赋值语句,这会创建全新的张量覆盖原有变量。新张量默认不继承requires_grad=True属性,且原张量的梯度信息无法传递给新变量,导致后续执行w.grad.zero_()时,w.grad已经是None,触发属性错误。
修复方案
方案1:使用原地操作更新参数
直接修改原张量的数值,不创建新变量,保留梯度相关属性:
for i in range(100): islem = model(inputnew) loss = fix(targetnew,islem) loss.backward() with torch.no_grad(): # 用原地减法更新,不创建新张量 w -= w.grad * 1e-5 b -= b.grad * 1e-5 # 清零梯度,为下一轮迭代做准备 w.grad.zero_() b.grad.zero_()
方案2:使用PyTorch优化器管理参数(推荐)
用PyTorch内置的优化器自动处理参数更新和梯度清零,代码更规范且不易出错:
input = torch.tensor([73,67,43,91,88,64,87,134,58,102,43,37,69,96,70],dtype=torch.float32) inputnew = input.reshape(5,3) target = torch.tensor([56,70,81,101,119,133,22,37,103,119]) targetnew = target.reshape(5,2) w = torch.randn(2,3,requires_grad = True) b = torch.randn(2,requires_grad = True) def model(x): return x @ w.t()+ b def fix(real,pred): diff = real-pred return torch.sum((diff*diff)/diff.numel()) # 初始化SGD优化器,传入参数和学习率 optimizer = torch.optim.SGD([w, b], lr=1e-5) for i in range(100): islem = model(inputnew) loss = fix(targetnew,islem) # 清空上一轮的梯度 optimizer.zero_grad() # 反向传播计算梯度 loss.backward() # 一步完成参数更新 optimizer.step()
注意事项
- 每次反向传播前必须清零梯度,否则梯度会累加(除非你需要刻意累加梯度的场景)
- 避免随意重新赋值带
requires_grad=True的参数,优先用原地操作或优化器管理
内容的提问来源于stack exchange,提问作者T K J
相关产品推荐
相关产品推荐

