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

使用KerasRegressor预测训练数据结果极差,求技术解决方案

问题:KerasRegressor拟合训练数据时输出全为极小值,无法得到准确预测

我在一个非随机的模拟数据集上使用KerasRegressor,尝试直接预测训练数据本身,但输出结果完全不符合预期。以下是我的实现代码:

from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasRegressor
import numpy as ny
X = ny.array([[1,2], [3,4], [5,6], [7,8], [9,10]])
Y = ny.array([3, 4, 5, 6, 7])
N = 5
def brain():
    #Create the brain
    br_model=Sequential()
    br_model.add(Dense(3, input_dim=2, kernel_initializer='normal',activation='relu'))
    br_model.add(Dense(2, kernel_initializer='normal',activation='relu'))
    br_model.add(Dense(1,kernel_initializer='normal'))
    #Compile the brain
    br_model.compile(loss='mean_squared_error',optimizer='adam')
    return br_model
estimator = KerasRegressor(build_fn=brain, nb_epoch=1000000, batch_size=5,verbose=1)
print "Done"
estimator.fit(X,Y)
prediction = estimator.predict(X)
print Y
print prediction

真实输出应为[3 4 5 6 7],但我的预测结果全是[0.001 0.001 0.001 0.001 0.001]。我试过调整多种网络配置,但问题依旧,请问该怎么调整才能得到准确的预测结果?


解决方案

我帮你梳理几个核心问题点,以及对应的调整方案:

1. 数据未归一化是核心问题

你的输入数据X范围是1-10,输出Y是3-7,但模型使用了relu激活函数,搭配默认的normal初始化(均值0,标准差0.05)。初始权重极小,导致relu直接把大量神经元输出压制到0,模型根本无法有效学习数据规律。

  • 调整方法:对输入和输出做归一化处理,把数据缩放到模型更容易处理的范围(比如0-1):
from sklearn.preprocessing import MinMaxScaler
import numpy as np

# 修正代码里ny的笔误为np
X = np.array([[1,2], [3,4], [5,6], [7,8], [9,10]])
Y = np.array([3, 4, 5, 6, 7]).reshape(-1, 1)  # 转成二维数组适配缩放器

# 初始化缩放器
scaler_x = MinMaxScaler()
X_scaled = scaler_x.fit_transform(X)
scaler_y = MinMaxScaler()
Y_scaled = scaler_y.fit_transform(Y)

# 用缩放后的数据训练
estimator.fit(X_scaled, Y_scaled)

# 预测后反缩放得到真实值
prediction_scaled = estimator.predict(X_scaled).reshape(-1, 1)
prediction = scaler_y.inverse_transform(prediction_scaled).flatten()

2. 训练轮数严重超标

你设置了nb_epoch=1000000,这完全没必要。Adam优化器在训练后期会因为梯度趋近于0而停止更新,甚至可能出现数值不稳定的情况。

  • 调整方法:把轮数降到合理范围(比如1000-5000),同时加入早停机制避免无效训练:
from keras.callbacks import EarlyStopping

# 新版本Keras中nb_epoch已更名为epochs,建议使用新参数名
estimator = KerasRegressor(
    build_fn=brain, 
    epochs=5000, 
    batch_size=5, 
    verbose=1,
    callbacks=[EarlyStopping(monitor='loss', patience=50, restore_best_weights=True)]
)

早停会在损失连续不再下降时停止训练,并恢复到最优的权重状态。

3. 网络结构与初始化不匹配

你的数据集只有5个样本,两层隐藏层(3+2神经元)反而可能让模型难以收敛;同时normal初始化对relu激活函数不够友好,容易引发“死亡神经元”问题。

  • 调整方向:
    • 简化网络:比如只用一层隐藏层(甚至不用隐藏层,因为你的数据明显存在线性规律);
    • 更换初始化方式:用he_normal(专门针对relu的初始化策略):
def brain():
    br_model=Sequential()
    br_model.add(Dense(3, input_dim=2, kernel_initializer='he_normal', activation='relu'))
    br_model.add(Dense(2, kernel_initializer='he_normal', activation='relu'))
    br_model.add(Dense(1, kernel_initializer='normal'))
    br_model.compile(loss='mean_squared_error', optimizer='adam')
    return br_model

4. 学习率可能过低

Adam默认学习率0.001对于未归一化的数据来说太小,导致权重更新缓慢,无法移动到有效拟合区域。可以尝试调大学习率:

from keras.optimizers import Adam

def brain():
    br_model=Sequential()
    br_model.add(Dense(3, input_dim=2, kernel_initializer='he_normal', activation='relu'))
    br_model.add(Dense(2, kernel_initializer='he_normal', activation='relu'))
    br_model.add(Dense(1, kernel_initializer='normal'))
    # 调整学习率为0.01
    opt = Adam(learning_rate=0.01)
    br_model.compile(loss='mean_squared_error', optimizer=opt)
    return br_model

5. 批量大小可灵活调整

你的数据集只有5个样本,batch_size=5意味着每次训练用全量数据。可以尝试改成1或2,让优化器有更多更新步骤,可能更容易收敛。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:39:07