梯度下降求解线性回归MSE最优参数时始终返回NaN值问题咨询
问题原因与解决方法
首先明确:均方误差(MSE)作为线性回归的代价函数是凸函数,定义域覆盖全体实数,你遇到的溢出问题和函数定义域无关,属于梯度爆炸导致的数值计算异常,可按照以下步骤排查解决:
1. 修正数据预处理逻辑
你遇到的现象大概率是预处理错误导致的,重点检查两点:
- 不要对包含截距项的X_b直接做标准化:正确流程是先对原始特征(不含全1列)做StandardScaler变换,再给标准化后的特征拼接全1列得到X_b。如果对包含全1列的X_b直接做标准化,全1列会被处理为全0,直接破坏截距项的更新逻辑。
- 对目标向量y同步做标准化:如果仅标准化了输入特征X,y仍保持原始的大量级,误差项
X_b.dot(theta) - y的数值会非常大,直接导致第一步梯度计算就爆炸,哪怕X已经标准化也没用。训练完成后如果需要原始尺度的参数,可以对得到的theta做反标准化转换即可。
2. 检查张量维度匹配
确认所有参与计算的张量维度符合预期:
- X_b维度应为
(样本数, 2) - y应为
(样本数, 1)的二维数组,不要用(样本数,)的一维数组,避免numpy广播机制导致梯度计算结果异常 - theta维度应为
(2, 1),和你代码中的初始化逻辑一致
3. 优化梯度下降配置
如果预处理和维度都没有问题,可以通过以下配置避免溢出同时保证收敛效果:
- 不用直接把学习率压到极低值,可以使用学习率衰减策略,比如采用衰减公式
eta = initial_eta / (1 + decay_rate * iteration),初始eta可以设为0.01,decay_rate设为1e-3,兼顾前期收敛速度和后期稳定性。 - 添加梯度裁剪:每次计算完梯度后,将梯度的L2范数限制在固定阈值(比如5)以内,从根源上避免梯度过大导致参数溢出。
- 小学习率场景下增加迭代次数:你把学习率调到0.00001后结果不准,是因为500次迭代完全不足以让小学习率的梯度下降收敛,可把迭代次数提升到1e5~1e6,或者添加早停逻辑:当两次迭代的theta变化量小于1e-6时直接停止训练,不用固定迭代次数。
内容的提问来源于stack exchange,提问作者Raffaele Zanardo
相关产品推荐
相关产品推荐

