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

基于梯度下降的多项式近似:高次权重爆炸问题优化问询

高次多项式反向传播权重爆炸问题的优化方案

你的核心问题是高次幂项x^n数值随次数急剧膨胀,导致SGD更新时梯度项过大,权重被推到极端值引发溢出或发散。以下是几个直接有效的优化方案:

1. 用正交多项式基替代普通幂次项

普通幂次项x^n在x>1时会指数级增长,而正交多项式(如切比雪夫、勒让德多项式)在标准化区间内数值始终维持在[-1,1]左右,从根源上解决特征值爆炸的问题。

修改特征生成逻辑,以切比雪夫多项式为例:

import numpy as np
import matplotlib.pyplot as plt
from numpy.polynomial import chebyshev as cheb

x = np.array([1,2,3,4,5])
y = np.array([5,15,25,45,65])
grade = 10  # 测试高次场景

def interpolate_backprop(x,y,grade,alfa=1e-3, steps = 50000):
    # 先把x缩放到切比雪夫多项式的标准区间[-1,1]
    x_scaled = 2 * (x - x.min()) / (x.max() - x.min()) - 1
    # 生成0到grade-1阶的切比雪夫特征矩阵
    inputs = cheb.chebvander(x_scaled, grade-1).astype(np.double)
    
    weights = np.random.normal(size=grade)  # 用正态分布初始化权重更稳定
    for n in range(steps):
        # 批量梯度下降,用所有样本的平均梯度
        outputs = np.dot(inputs, weights)
        error = outputs - y
        gradient = np.dot(inputs.T, error) / len(x)
        weights -= alfa * gradient
        
        if n % 5000 == 0:
            mse = np.mean(error**2)
            print(f"Step {n}, MSE = {mse:.4f}")
    return weights, x.min(), x.max()

weights, x_min, x_max = interpolate_backprop(x,y,grade)

# 测试拟合效果
x_scaled = 2 * (x - x_min) / (x_max - x_min) - 1
inputs = cheb.chebvander(x_scaled, grade-1)
for xi, pred, true in zip(x, np.dot(inputs, weights), y):
    print(f"x={xi}: 预测值={pred:.2f}, 真实值={true}")

# 绘制拟合曲线
xx = np.arange(x[0]-1, x[-1]+1, 0.1)
xx_scaled = 2 * (xx - x_min) / (x_max - x_min) - 1
xx_inputs = cheb.chebvander(xx_scaled, grade-1)
yy = np.dot(xx_inputs, weights)

plt.scatter(x, y, label='原始数据')
plt.plot(xx, yy, label=f'{grade}次切比雪夫多项式拟合')
plt.legend()
plt.show()

2. 输入特征标准化

如果坚持用普通幂次项,必须对每个特征维度(即每个n次项)做标准化,消除不同次项之间的数值差异:

def interpolate_backprop(x,y,grade,alfa=1e-3, steps = 50000):
    inputs = np.array([[xi**n for n in range(grade)] for xi in x], dtype=np.double)
    # 对每一列(每个幂次项)做Z-score标准化
    mean = np.mean(inputs, axis=0)
    std = np.std(inputs, axis=0)
    std[std == 0] = 1e-8  # 避免除以0
    inputs = (inputs - mean) / std
    
    weights = np.random.normal(size=grade)
    for n in range(steps):
        outputs = np.dot(inputs, weights)
        error = outputs - y
        gradient = np.dot(inputs.T, error) / len(x)
        weights -= alfa * gradient
        
        if n % 5000 == 0:
            mse = np.mean(error**2)
            print(f"Step {n}, MSE = {mse:.4f}")
    return weights, mean, std

# 预测时要对新输入做同样的标准化
weights, mean, std = interpolate_backprop(x,y,grade)
xx_inputs = np.array([[xi**n for n in range(grade)] for xi in xx], dtype=np.double)
xx_inputs = (xx_inputs - mean) / std
yy = np.dot(xx_inputs, weights)

3. 添加权重正则化

在权重更新时加入L2正则项,限制权重的绝对值大小,防止过度膨胀:

lambda_reg = 1e-4  # 正则系数,根据情况调整
weights -= alfa * (gradient + lambda_reg * weights)

关键注意事项

  • 优先用正交多项式方案,这是解决高次多项式拟合数值不稳定最有效的方法;
  • 避免用纯SGD,改用批量或小批量梯度下降,梯度更稳定;
  • 不要随意修改反向传播的梯度公式(你之前去掉input项的做法是错误的,破坏了导数的正确性)。

内容的提问来源于stack exchange,提问作者Smer5

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 22:40:31