多变量线性回归梯度下降报错:系数变为NaN问题求助
解决多变量线性回归梯度下降出现NaN的问题
出现invalid value encountered in subtract错误并得到[nan nan nan]系数,大概率是梯度爆炸导致的,常见原因和解决方法如下:
特征未做归一化/标准化
多变量线性回归中,不同特征的数值范围差异过大时,梯度更新会出现数值不稳定,最终导致系数溢出成NaN。必须先对输入特征x做标准化处理:
手动实现方式:# 对特征做标准化(均值为0,方差为1) x_scaled = (x - np.mean(x, axis=0)) / np.std(x, axis=0)或使用sklearn工具:
from sklearn.preprocessing import StandardScaler scaler = StandardScaler() x_scaled = scaler.fit_transform(x)之后将
x_scaled传入gD函数替代原x。学习率设置过高
即使做了归一化,过大的学习率也可能导致梯度更新步长太大,越过最优值后发散。可以尝试降低学习率,比如从0.01调整到0.001,或者添加学习率衰减逻辑(比如每轮按固定比例缩小学习率)。检查数据完整性
先确认输入数据x和y中是否存在缺失值或异常值:# 检查x是否有NaN print(np.isnan(x).any()) # 检查y是否有NaN print(np.isnan(y).any())如果有缺失值,需要先填充或删除对应样本。
验证梯度计算逻辑
可以在训练过程中打印前几轮的cost值,观察是否持续增大直到变成inf:def gD(x, y, coeff, epochs, learning_rate): past_costs = [] past_coeff = [coeff] for i in range(epochs): prediction = np.dot(x, coeff) error = prediction - y cost = 1/(2*N) * np.dot(error.T,error) past_costs.append(cost) # 打印前10轮的cost,观察变化 if i < 10: print(f"Epoch {i}, Cost: {cost}") der = (1/N) * learning_rate * np.dot(x.T, error) coeff = coeff - der past_coeff.append(coeff) return past_coeff, past_costs如果cost快速增大,说明梯度爆炸,优先做特征归一化。
修改后的完整代码示例(含特征标准化):
import numpy as np # 模拟输入数据(替换为你的实际数据) x = np.random.rand(100, 3) y = 2*x[:,0] + 3*x[:,1] + 4*x[:,2] + np.random.randn(100)*0.1 learning_rate = 0.01 epochs = 2000 N = y.size np.random.seed(123) coeff = np.random.rand(3) print("Initial values of coefficients : ", coeff) # 特征标准化 x_scaled = (x - np.mean(x, axis=0)) / np.std(x, axis=0) def gD(x, y, coeff, epochs, learning_rate): past_costs = [] past_coeff = [coeff] for i in range(epochs): prediction = np.dot(x, coeff) error = prediction - y cost = 1/(2*N) * np.dot(error.T,error) past_costs.append(cost) der = (1/N) * learning_rate * np.dot(x.T, error) coeff = coeff - der past_coeff.append(coeff) return past_coeff, past_costs past_coeff, past_costs = gD(x_scaled, y, coeff, epochs, learning_rate) coeff = past_coeff[-1] print("Final values of coefficients : ", coeff)
内容的提问来源于stack exchange,提问作者butters149
相关产品推荐
相关产品推荐

