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

Python实现梯度下降做数据拟合,线性正常二次模型结果异常如何解决

二次拟合梯度下降异常的原因及解决方法

核心问题原因

你写的偏导数计算逻辑本身是完全正确的,异常是训练配置问题导致的:

  • 特征量级不匹配,未做归一化:二次项X²的取值范围是136,一次项`X`取值范围是16,不同特征的数值量级差异过大,导致各参数的梯度更新步长差距明显,统一学习率下无法同时适配所有参数的更新需求,收敛速度极慢。
  • 迭代次数不足:仅设置100次迭代,对于未归一化的特征,完全不足以让参数收敛到全局最优值,运行结束时参数还处于迭代的初始阶段,自然得到异常拟合结果。
  • 学习率设置不合理:线性拟合时你使用的学习率为100,切换到二次拟合后直接将学习率降到0.01,步长太小,参数更新的幅度非常有限,进一步加剧了收敛慢的问题。

修复方案

你可以选择两种方式调整:

  1. 先对所有特征做归一化,把一次项、二次项都缩放到相近的数值区间,再用原迭代次数和学习率训练即可正常收敛
  2. 不做归一化的话,直接调大迭代次数到10000次以上,同时将学习率调整到0.001左右,也可以得到正常收敛结果

修复后可正常运行的代码示例

import numpy as np
import matplotlib.pyplot as plt

def gradient(x, y):
    P0 = P1 = P2 = 0
    # 增大迭代次数
    iterations = 20000
    # 调整到合适的学习率
    learning_rate = 0.001
    l = len(x)

    for i in range(iterations):
        y_predicted = P0 + P1*x + P2*(x**2)
        err = (1/l) * sum([val**2 for val in (y-y_predicted)])
        if err <= 1e-6:
            break

        P0d = - (2/l) * sum(y - y_predicted)
        P1d = - (2/l) * sum(x * (y - y_predicted))
        P2d = - (2/l) * sum(x**2 * (y - y_predicted))
        
        P0 = P0 - learning_rate * P0d
        P1 = P1 - learning_rate * P1d
        P2 = P2 - learning_rate * P2d
    return P0, P1, P2
    
X = np.asarray([1, 2, 4, 5, 6])
Y = np.asarray([2, 4, 6, 8, 10])

P0, P1, P2 = gradient(X, Y)
# 收敛后P2会非常接近0,拟合结果和线性模型一致
pred = P0 + P1*X + P2*X**2
plt.figure(1, figsize=(6,4), dpi=120)
plt.scatter(x=X, y=Y, c='red', marker='o', label='Data')
plt.plot(X, pred, '--m', label='Model')
plt.legend()
plt.show()

内容的提问来源于stack exchange,提问作者Никита Михалков

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:15:11