TensorFlow/Keras拟合y=x²结果错误 如何正确近似多项式函数
原代码问题分析
- 未做数据尺度归一化:训练用的x范围为0~999,对应标签y最大接近100万,数值跨度过大。全连接神经网络对输入、标签的数值尺度极其敏感,大尺度数值会导致MSE损失量级过高,参数更新时极易出现梯度震荡甚至爆炸,模型完全无法收敛,这就是预测值出现离谱负数的核心原因。
- 隐藏层未添加非线性激活:所有Dense层默认使用线性激活函数,无论堆叠多少层线性变换,最终本质都等价于单层线性映射
y=wx+b,完全不具备拟合y=x²这类非线性关系的能力,训练轮次再高也学不到平方规律。 - 结构存在冗余设计:第一层先接
units=1的全连接层再接128维隐藏层,相当于先把输入特征压缩成单值再升维,属于完全多余的操作,还会额外损失信息、拖慢训练效率。
正确实现方法
拟合y=x²这类简单非线性函数不需要复杂的大宽度网络,核心要做对数据归一化和添加非线性激活两个步骤,参考实现如下:
import tensorflow as tf import numpy as np # 生成训练数据 xs = np.arange(0, 1000, dtype=np.float32) ys = xs ** 2 # 归一化:将x、y都缩放到0~1区间,消除大尺度数值的负面影响 x_max = xs.max() y_max = ys.max() x_norm = xs / x_max y_norm = ys / y_max # 构建模型:隐藏层使用relu激活提供非线性拟合能力 model = tf.keras.Sequential([ tf.keras.layers.Dense(32, activation='relu', input_shape=[1]), tf.keras.layers.Dense(32, activation='relu'), tf.keras.layers.Dense(1) ]) model.compile(optimizer='adam', loss='mse') # 用归一化后的数据训练 model.fit(x_norm, y_norm, epochs=500, verbose=2) # 预测时输入要做和训练集一致的归一化,输出再反归一化得到真实值 pred_norm = model.predict([2 / x_max]) pred = pred_norm * y_max print(f"输入2时的预测值:{pred[0][0]}")
运行上述代码,预测值会非常接近真实值4,误差可控制在1以内。
如果你明确知道要拟合的是多项式函数,不需要依赖神经网络:直接构造x、x²作为输入特征,用最简单的线性模型就能实现零误差拟合。
内容的提问来源于stack exchange,提问作者red Program
相关产品推荐
相关产品推荐

