使用神经网络拟合三次方程y=x³+9x²损失过高波动大如何解决
问题成因
- 输入输出特征未做归一化:你生成的输入
xs取值范围是[-50, 50],对应输出ys的取值范围达到了[-102500, 147500],数值跨度过大导致均方误差损失的基准值本身就很高,同时反向传播时梯度过大,训练过程出现大幅震荡,无法平稳收敛。 - 学习率设置过高:Adam优化器的默认学习率为
1e-3,你设置的1e-1远高于合理值,会导致参数更新步长过大,每次迭代参数在最优值附近来回跳动,无法收敛到极小值点。 - 正则化配置不合理:在拟合简单多项式函数的场景下,L2正则化的惩罚项会额外增加损失值,同时限制模型的拟合能力,反而阻碍收敛。
遗漏的关键配置
- 输入输出特征的归一化/标准化处理:需要将输入和输出的数值范围缩放到
[-1,1]或者[0,1]区间,降低损失基准值的同时稳定梯度。 - 合理的学习率设置:将Adam优化器的学习率调整到
1e-3到1e-4区间即可。 - 移除不必要的L2正则化:当前拟合的是确定的多项式函数,不存在过拟合风险,不需要加正则化项。
优化后可运行参考代码
import tensorflow as tf import numpy as np from tensorflow import keras model = tf.keras.Sequential([ keras.layers.Dense(units=8, activation='relu', input_shape=[1]), keras.layers.Dense(units=8, activation='relu'), keras.layers.Dense(units=8, activation='relu'), keras.layers.Dense(units=8, activation='relu'), keras.layers.Dense(units=1) ]) # 调整为合理学习率 optimizer = keras.optimizers.Adam(learning_rate=1e-3) model.compile(optimizer=optimizer, loss='mean_squared_error') # 生成原始数据 xs = np.random.random((10000, 1)) * 100 - 50 ys = xs**3 + 9*xs**2 # 新增归一化处理 x_mean, x_std = xs.mean(), xs.std() y_mean, y_std = ys.mean(), ys.std() xs_norm = (xs - x_mean) / x_std ys_norm = (ys - y_mean) / y_std # 用归一化后的数据训练 model.fit(xs_norm, ys_norm, epochs=500, batch_size=256, validation_split=0.2) # 预测时先做归一化,输出后反归一化得到真实值 x_test = np.array([[10.0]]) x_test_norm = (x_test - x_mean) / x_std y_pred_norm = model.predict(x_test_norm) y_pred = y_pred_norm * y_std + y_mean print(y_pred) # 正确输出应为10^3 +9*10^2=1900,优化后误差可控制在个位数
内容的提问来源于stack exchange,提问作者Fabio R.
相关产品推荐
相关产品推荐

