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

手动实现梯度下降线性回归 迭代次数增加效果变差问题排查

问题诊断

该异常90%以上由特征预处理逻辑和预测/可视化逻辑不一致、预处理步骤位置错误两类实现bug导致,和梯度下降的理论本身无关,且这类bug和学习率大小无关,无论把学习率降到多低,只要迭代次数足够,参数收敛到错误空间的最优值,都会出现拟合偏离、cost虚低的现象。高频触发原因按概率从高到低排列:

  • 第一类最高发bug:特征标准化逻辑放错位置+预测阶段未复用训练集统计量
    多数错误实现会把特征标准化(减均值除标准差)的代码写在梯度下降迭代循环内部,每轮迭代都重新计算当前输入特征的均值、标准差做归一化;更常见的是训练时对特征做了标准化,但训练完成后画拟合直线、计算预测值时,直接拿原始尺度的特征和训练得到的theta做矩阵乘法,没有用训练集特征的固定均值、标准差对预测阶段的输入做相同变换。
    迭代100次时theta还接近初始值(一般初始化为0或接近0的小随机数),和原始尺度下的粗拟合参数偏差不大,看起来直线贴合样本,本质是参数还没走到bug触发的区间;迭代次数增加后,theta在标准化后的特征空间里确实朝着最小化cost的方向收敛,cost计算因为是在标准化空间执行所以持续降低,但放到原始特征尺度下预测值会完全偏离,迭代越久偏离越明显。
  • 第二类次高发bug:标准化时误处理了偏置项列
    实现时先给特征矩阵拼接了全1的偏置项列,再对整个矩阵做标准化,导致全1的偏置列被减均值、除标准差,不再是全1值,直接破坏了偏置项的学习逻辑。迭代过程中成本在特征空间确实持续下降,但偏置参数完全学错,迭代越久偏置偏移越大,最终拟合直线整体偏离样本分布。
  • 第三类bug:成本函数计算逻辑和拟合效果评估逻辑尺度不统一
    计算cost时用的是标准化后的标签y、标准化后的特征计算MSE,所以数值持续下降;但可视化拟合直线时用的是原始尺度的y轴,和模型预测的标准化尺度y值完全不匹配。迭代越久模型在标准化空间拟合越好,放到原始尺度看偏差越大。
  • 低概率bug:梯度更新逻辑错误
    比如计算梯度时没有按样本数做平均、矩阵乘法时维度搞反导致权重更新方向虽然整体让cost下降,但单特征权重的缩放比例完全错误;或者更新权重时没有用本轮迭代初始的theta计算所有维度的梯度,而是逐个更新权重后用新权重算下一个维度的梯度,导致参数更新步长错乱。
修复方案

按优先级逐一排查修改即可:

  1. 修正特征标准化的逻辑位置
    • 标准化操作必须放在梯度下降迭代循环外部,只在训练开始前对训练集特征执行一次
    • 标准化用的均值、标准差必须是只从训练集计算得到的固定值,不能随迭代更新,也不能用预测阶段/测试集的数据计算
    • 预测、可视化阶段的所有输入特征,必须使用同一套训练集均值、标准差做完全相同的标准化处理,再送入模型和theta做计算得到预测值
      正确逻辑参考片段:
    # 训练阶段(迭代外执行一次)
    x_mean = np.mean(X_train, axis=0)
    x_std = np.std(X_train, axis=0)
    X_train_norm = (X_train - x_mean) / x_std
    # 拼接偏置项必须在标准化之后做
    X_train_norm = np.c_[np.ones(len(X_train_norm)), X_train_norm]
    # 再执行梯度下降迭代更新theta
    
    # 可视化/预测阶段
    x_plot = np.linspace(X_train.min(), X_train.max(), 100)
    # 用训练集的均值标准差标准化绘图用的x
    x_plot_norm = (x_plot - x_mean) / x_std
    x_plot_norm = np.c_[np.ones(len(x_plot_norm)), x_plot_norm]
    y_plot = x_plot_norm @ theta
    # 再用原始尺度的x_plot和y_plot画拟合直线
    
  2. 修正偏置项拼接顺序
    永远先对原始特征做标准化,再拼接全1的偏置项列,禁止把偏置项列加入标准化计算。
  3. 统一成本计算和效果评估的尺度
    如果训练时对标签y也做了标准化,计算cost可以用标准化后的y,但可视化、预测时必须把预测值用y的训练集均值、标准差逆变换回原始尺度,再和原始标签对比。
  4. 核对梯度更新公式
    批量梯度下降的正确更新逻辑是每轮迭代先用当前固定的theta计算所有样本的整体梯度,再一次性更新所有theta值,参考实现:
    # MSE损失下的正确梯度计算
    n = len(X)
    y_pred = X @ theta
    grad = (2 / n) * X.T @ (y_pred - y)
    theta = theta - lr * grad
    
    禁止在单轮迭代中逐个更新theta元素后,用新theta计算剩余维度的梯度。
验证标准

修改后打印100次、1000次、10000次迭代的theta值,如果参数收敛到固定值不再大幅变化,同时原始尺度下计算的数据集MSE随迭代次数增加先下降后稳定,即说明修复完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 01:42:27