You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

LSTM时间序列递归预测收敛至同一值的问题排查求助

递归LSTM预测收敛到固定值的问题分析与解决办法

我之前也碰到过类似的递归多步预测“坍缩”到固定值的情况,结合你的代码和描述,咱们来拆解可能的原因和对应的解决思路:

核心原因分析

1. 训练与推理场景的 mismatch

你的模型是单步预测训练(用25个历史值预测下1个真实值),但推理时是递归多步预测(用前一次的预测值当输入)。训练时模型从未接触过带误差的预测值作为输入,一旦进入递归模式,误差会不断累积,模型很容易退化为预测序列的均值——毕竟MSE损失下,预测均值是最小化整体误差的“安全选择”。

2. 模型的均值回归倾向

MSE损失函数本身会引导模型趋向于预测数据的期望均值,尤其是当序列波动不大、训练数据中均值样本占比高时,模型会逐渐失去捕捉序列趋势的能力,递归几次后就会收敛到均值附近。

3. 归一化流程可能存在疏漏

你提到用了MinMaxScaler,但如果:

  • Scaler是用测试集单独拟合的(而不是训练集),会导致缩放尺度不一致;
  • 递归预测时,预测值的缩放/逆变换时机错误(比如提前逆变换后再加入窗口,破坏了缩放后的分布),也可能引发异常。

具体解决办法

1. 切换到多步预测训练模式

直接让模型学习预测未来25个值,而不是单步预测,让训练目标和推理需求对齐。修改模型输出层为Dense(units=25),训练时输入25个历史值,输出对应后续25个真实值:

# 假设y_train已调整为形状(样本数, 25)的多步标签
regressor = Sequential()
regressor.add(LSTM(units = 100, return_sequences = True, input_shape = (25, 1)))
regressor.add(Dropout(0.2))
regressor.add(LSTM(units = 100))
regressor.add(Dropout(0.2))
regressor.add(Dense(units = 25))  # 直接输出25个预测值
regressor.compile(optimizer = 'adam', loss = 'mean_squared_error')
regressor.fit(X_train, y_train, epochs = 20, batch_size = 16)

这种方式避免了递归的误差累积,模型直接学习序列的多步依赖关系。

2. 引入教师强制(Teacher Forcing)训练

如果坚持用递归方式,可以在训练时混合真实数据和模型预测值作为输入,让模型适应带误差的输入:

  • 训练时,一部分时间步用真实的下一个值作为输入,一部分用模型预测的值;
  • 可以通过自定义训练循环实现,或者用tf.keras.utils.timeseries_dataset_from_array构建混合数据集。

3. 调整损失函数与正则化

  • 替换或混合损失函数:比如用MSE+MAE的组合损失(loss = lambda y_true, y_pred: 0.5*tf.keras.losses.MSE(y_true, y_pred) + 0.5*tf.keras.losses.MAE(y_true, y_pred)),减少模型对均值的依赖;
  • 增强正则化:把Dropout比例提高到0.2-0.3,给LSTM层添加kernel_regularizer=tf.keras.regularizers.l2(0.01),防止模型过度拟合到“安全”的均值预测。

4. 修正归一化流程

  • 确保Scaler仅用训练数据拟合sc = MinMaxScaler(); sc.fit(X_train.reshape(-1, 1)),测试数据和预测值都用同一个scaler进行缩放/逆变换;
  • 递归预测时,保持所有输入在缩放后的状态:每次得到预测值(缩放后),直接加入输入窗口,完成25步预测后,再统一逆变换回原始尺度。

5. 调整模型结构

  • 试试双向LSTM:Bidirectional(LSTM(units=100, return_sequences=True)),捕捉序列的双向依赖关系;
  • 替换为GRU层:GRU参数更少,有时在序列预测中对误差累积的鲁棒性更强;
  • 添加BatchNormalization层:在Dense层前加入BatchNormalization(),稳定模型输出分布。

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

火山引擎 最新活动