多变量梯度下降如何求解系数?二次函数拟合得到线性结果怎么修复?
问题原因与修复方案
核心问题点
- 归一化逻辑不合理:将X、Y合并取最大值做归一化时,Y是二次函数输出,量级远大于X,归一化后X的取值被压缩到
[-0.01, 0.01]区间,X平方的量级仅为1e-4,导致二次项系数w1的梯度极小,更新速度远慢于一次项和偏置,训练结束后w1仍接近0,拟合结果自然近似直线。 - 训练超参数不合理:学习率过小、训练轮数不足的情况下,w1还没有更新到接近真实值就停止训练,也会出现拟合为直线的问题。
- 代码语法小缺陷:生成样本的代码缺少右括号,运行时会报错。
修复步骤
- 修正样本生成代码的语法错误
- 调整归一化逻辑,避免X取值被过度压缩
- 调大学习率、增加训练轮数,保证参数收敛
- 训练过程中监控损失变化,确认损失收敛后再输出结果
修复后参考代码
import numpy as np import random import matplotlib.pyplot as plt # 1. 生成样本数据 function = lambda x: x ** 2 + x + 1 X=[] Y=[] for i in range(-100,100): X.append(i) # 补全右括号 Y.append(function(i) + random.randrange(-10,10)) # 2. 调整归一化逻辑 X = np.asarray(X) Y = np.asarray(Y) # X归一化到[-1,1]区间 X = X / 100 # Y做对应量级缩放 Y = Y / 10000 # 3. 初始化超参数 w1 = 0 w2 = 0 b = 0 L = 1e-2 # 适配梯度量级调整学习率 epochs = 20000 # 增加训练轮数保证收敛 n = len(X) w1Arr = [] w2Arr = [] bArr = [] lossArr = [] # 4. 梯度下降训练 for i in range(epochs): Y_pred =w1*np.square(X)+w2*X+b D_w1 = (-2/n) * sum( np.square(X) * (Y - Y_pred)) D_w2 = (-2/n) * sum(X * (Y - Y_pred)) D_b = (-2/n) * sum(Y - Y_pred) w1 = w1 - L * D_w1 w2 = w2 - L * D_w2 b = b - L * D_b loss = sum((Y - Y_pred) * (Y - Y_pred)) w1Arr.append(w1) w2Arr.append(w2) bArr.append(b) lossArr.append(loss) # 5. 绘制拟合结果 Y_pred = w1*(np.square(X))+w2*X+b plt.scatter(X, Y, label="原始样本") plt.plot(X, Y_pred, color='red', label="拟合结果") plt.legend() plt.show()
内容的提问来源于stack exchange,提问作者LiavC
相关产品推荐
相关产品推荐

