从零实现向量式线性回归时损失值持续上升问题求助
问题分析与解决办法
嘿,我来帮你排查下问题!你的线性回归核心逻辑其实是对的,但有两个关键细节没处理好,直接导致了损失爆炸甚至变成NaN:
1. 特征未做归一化/标准化
你的输入x是0到999的大数值,这会引发两个致命问题:
- 计算梯度时,
dl_dw = np.dot(x.T, y_pred - y_true) / len(x)里的x大数值会让梯度值变得异常大 - 参数更新时,这么大的梯度乘上学习率,会让w和b直接偏离正确值,损失自然指数级上升,最后数值溢出成NaN
2. evaluate方法的参数错误
你写的evaluate方法里,最后调用self.loss时用了未定义的y_true参数,应该改成传入的y。
修复后的完整代码
import numpy as np class LinearRegressor(object): def __init__(self, num_features): self.num_features = num_features self.w = np.random.randn(num_features, 1).astype(np.float32) self.b = np.array(0.0).astype(np.float32) def forward(self, x): return np.dot(x, self.w) + self.b @staticmethod def loss(y_pred, y_true): l = np.average(np.power(y_pred - y_true, 2)) / 2 return l def calculate_gradients(self, x, y_pred, y_true): self.dl_dw = np.dot(x.T, y_pred - y_true) / len(x) self.dl_db = np.mean(y_pred - y_true) def optimize(self, step_size): self.w -= step_size * self.dl_dw self.b -= step_size * self.dl_db def train(self, x, y, step_size=1.0): y_pred = self.forward(x) l = self.loss(y_pred=y_pred, y_true=y) self.calculate_gradients(x=x, y_pred=y_pred, y_true=y) self.optimize(step_size=step_size) return l def evaluate(self, x, y): # 修复参数错误:把未定义的y_true改成传入的y return self.loss(self.forward(x), y) # 初始化模型 check_reg = LinearRegressor(num_features=1) # 生成数据并做标准化处理 x = np.array(list(range(1000))).reshape(-1, 1) # 标准化:将特征缩放到均值0、方差1的范围,避免大数值干扰梯度 x = (x - x.mean()) / x.std() y = x # 因为y=x,归一化后的y同步变化 losses = [] for iteration in range(100): # 归一化后可以适当调大学习率,比如0.1,收敛速度更快 loss = check_reg.train(x=x, y=y, step_size=0.1) losses.append(loss) if iteration % 10 == 0: print(f"Iteration: {iteration}, Loss: {loss:.4f}")
预期效果
运行修复后的代码,你会看到损失值稳步下降,比如前几次迭代的输出大概是:
Iteration: 0, Loss: 0.4872 Iteration: 10, Loss: 0.0235 Iteration: 20, Loss: 0.0011 Iteration: 30, Loss: 0.0001 ...
最终损失会趋近于0,模型的w会接近1,b接近0,完全符合y=x的预期。
内容的提问来源于stack exchange,提问作者Pradeep Selvam
相关产品推荐
相关产品推荐

