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

实现多变量线性回归梯度下降时出现inf/nan值的问题排查

多变量线性回归梯度下降出现inf/nan问题排查

问题描述

我手动实现多变量线性回归的梯度下降算法,运行代码后输出全为inf值,调小学习率也无法解决。对数据做标准化处理后,输出又变成nan值,但使用sklearn的LinearRegression无论是否标准化都能正常运行,求排查错误原因。

原始实现代码

# Starting values
w = np.ones(3) # 特征数量为3
b = float(0)

def gradient_descent():
  global w
  global b

  learning_rate = 0.0001

  for i in range(x_train.shape[0]):
    prediction = np.dot(x_train[i], w) + b
    error = x_train[i] - prediction
    for j in range(w.shape[0]):
      w[j] = w[j] - (error * x_train[i][j] * learning_rate)
    b = b - (error * learning_rate)

def train():
  for i in range(10_000):
    gradient_descent()
    print(i, ':', w, b)

train()

输出示例

0 : [inf inf inf] inf
1 : [inf inf inf] inf
....

数据说明

特征为total_rooms、population、households(x_train形状(17000,3)),目标变量是bedrooms(y_train形状(17000,1)),样本示例:

total_rooms,population,households,bedrooms(target)
5612.0,1015.0,472.0,1283.0
7650.0,1129.0,463.0,1901.0
720.0,333.0,117.0,174.0
1501.0,515.0,226.0,337.0
1454.0,624.0,262.0,326.0

标准化处理代码

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
train_data = scaler.fit_transform(train_data)
x_train = train_data[:, :3]
y_train = train_data[:, -1]

错误原因分析

  • 核心错误:误差计算逻辑完全错误
    线性回归梯度下降中,误差应为预测值与真实目标值的差值,即error = prediction - y_train[i](或y_train[i] - prediction,仅影响梯度更新方向),但你写成了error = x_train[i] - prediction——用特征向量和预测值做差,完全违背了损失函数的逻辑。
    这个错误会导致参数更新时使用完全错误的梯度方向,加上原始数据特征值量级较大(比如total_rooms达数千),参数会在迭代中迅速膨胀到无穷大(inf);标准化后,错误的误差计算会引发数值不稳定,最终变成nan。

  • 额外问题:迭代次数冗余
    当前实现是随机梯度下降(SGD),但外层又套了10000次全样本循环,相当于做了10000轮SGD,迭代次数过多会加剧数值不稳定。

修正方案

1. 修复误差计算逻辑

将误差计算改为目标值与预测值的差,同时确保梯度更新符号正确:

# 修正误差计算
error = prediction - y_train[i]
# 或者用 y_train[i] - prediction,此时梯度更新需改为 += (因为梯度方向反转)

2. 标准化优化(推荐保留)

标准化能均衡不同量级特征对参数更新的影响,建议仅对特征做标准化,目标变量可按需处理:

# 仅标准化特征x_train
scaler = StandardScaler()
x_train = scaler.fit_transform(x_train)
# 若需对y_train标准化,可单独处理,最后用逆变换还原结果

3. 优化梯度下降实现(可选)

改成批量梯度下降(计算所有样本的梯度均值再更新),提升稳定性:

def gradient_descent():
    global w, b
    learning_rate = 0.01
    m = x_train.shape[0]
    dw = np.zeros_like(w)
    db = 0.0

    # 计算所有样本的梯度总和
    for i in range(m):
        prediction = np.dot(x_train[i], w) + b
        error = prediction - y_train[i]
        dw += error * x_train[i]
        db += error
    
    # 取梯度均值,避免样本数量影响更新幅度
    dw /= m
    db /= m

    # 更新参数
    w -= learning_rate * dw
    b -= learning_rate * db

验证结果

修正后,无论是否标准化数据,梯度下降的参数都会逐步收敛到合理值,结果与sklearn的LinearRegression输出接近,不会再出现inf或nan。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 10:25:13