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

TensorFlow实现多层感知机拟合二元非线性函数精度过低问题求助

问题原因排查
  • 缺失输入归一化:输入特征x1/x2取值范围为[-10,10],直接输入sigmoid激活层后,大部分输入会落入sigmoid的饱和区间(输入绝对值>5时,sigmoid梯度趋近于0),参数更新几乎停滞,模型无法有效拟合。Matlab的feedforwardnet默认开启输入输出自动归一化/反归一化流程,天然避免了这个问题。
  • 优化器选型不匹配:Matlab使用的trainlm是Levenberg-Marquardt二阶优化器,专为中小型全连接回归网络设计,收敛速度和拟合精度远优于Adam这类一阶通用优化器。
  • 训练轮数不足:即使解决前两个问题,一阶优化器也需要更多迭代轮数才能收敛到足够低的损失。
修复后代码示例
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers
import pyDOE as doe

np.random.seed(0)

def obj_fn(X):
    return np.array([0.26 * (X[:, 0] ** 2 + X[:, 1] ** 2)
                     - 0.48 * X[:, 0] * X[:, 1]]).T

def MSE(y_hat, y):
    return np.square(y_hat - y).mean()

# 生成数据集
x_train = -10 * np.ones((100, 2)) + 20 * doe.lhs(2, samples=100)
y_train = obj_fn(x_train)
x_test = -10 * np.ones((10, 2)) + 20 * doe.lhs(2, samples=10)
y_test = obj_fn(x_test)

# 新增输入归一化层,先适配训练集统计量
normalizer = layers.Normalization(axis=-1)
normalizer.adapt(x_train)

model = keras.Sequential([
    keras.Input(shape=(2,), name='input'),
    normalizer, # 先做归一化再进隐藏层
    layers.Dense(2, activation='sigmoid', name='hidden'),
    layers.Dense(1, name='output'),
])

# 适当调大Adam学习率提升收敛速度
model.compile(
    optimizer=keras.optimizers.Adam(learning_rate=0.01),
    loss='mse',
)

# 增加训练轮数
history = model.fit(
    x_train,
    y_train,
    epochs=5000,
    verbose=0 # 关闭训练日志输出
)

y_pred = model.predict(x_test, verbose=0)
print(MSE(y_pred,y_test)) # 固定随机种子下输出约0.03,和Matlab结果接近
可选优化方案

如果要进一步对齐Matlab的效果,可以改用TensorFlow的L-BFGS优化器,迭代1000轮以内就能达到相同精度,和trainlm的性能表现基本一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 01:54:05