You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何手写PyTorch线性回归程序损失归零仍出现周期性振荡

核心问题原因

  • 每轮迭代未清空梯度缓存:PyTorch默认累加requires_grad=True张量的梯度,多次迭代后梯度值越来越大,参数更新步长失控,最终导致损失振荡。你使用内置SGD优化器时会调用optimizer.zero_grad()完成梯度清空,因此不会出现该问题。
  • 非核心优化点:直接存储损失张量会留存计算图占用内存,手动更新参数时未禁用梯度记录不符合PyTorch规范,这两点不会导致振荡,但会影响代码运行效率。
    注:你提到的torch.nn.smeloss为笔误,实际应为torch.nn.MSELoss

修复后可运行代码

import torch
import numpy as np
import matplotlib.pyplot as plt

class fit():
    def __init__(self, w, b):
        self.w = w
        self.b = b
    
    def forward(self, x):
        return torch.mm(self.w, x) + self.b
        
w = torch.tensor([[1., 1.1, 1.2],
                  [1., 1.1, 1.2],
                  [1., 1.1, 1.2]], requires_grad=True)

b = torch.tensor([[10.], [11.], [12.]], requires_grad=True)

x = torch.tensor([[1.], [2.], [3.]], requires_grad=False)
t = torch.tensor([[0.], [0.9], [0.1]], requires_grad=False)

model = fit(w, b)

alpha = 0.001
loss = []
arange = np.arange(200)

for i in arange:
    z = model.forward(x)
    l = (z - t)**2
    l = l.sum()
    loss.append(l.item()) # 取标量存储,避免留存计算图
    l.backward()
    
    # 禁用梯度记录,规范参数更新逻辑
    with torch.no_grad():
        model.w -= alpha * model.w.grad
        model.b -= alpha * model.b.grad
    
    # 清空梯度缓存,核心修复点
    model.w.grad.zero_()
    model.b.grad.zero_()

plt.plot(arange, loss)
plt.show()

运行修复后代码损失会持续单调下降,不再出现振荡问题。

内容的提问来源于stack exchange,提问作者prometeu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 00:06:05