Keras中使用RNN预测未来固定时长时间序列的代码验证
结论
你的代码没有实现你预期的「基于过往96个时间步数据预测后续96个时间步」的需求,核心问题出在测试阶段的取值逻辑、误差对比逻辑两处,具体拆解如下:
1. 训练阶段的逻辑有效性
你采用的SimpleRNN+TimeDistributed(Dense(steps_forward))的序列到序列结构本身是合理的,标签构造逻辑也符合训练要求:
steps_backwards=96、steps_forward=96的参数定义符合15分钟分辨率下1天的时间步对应关系- 三维标签
Y的构造逻辑,本质是让模型学习「基于输入序列的每一个时间步,输出该时间步之后96步的预测值」,训练阶段的目标是符合你要的多步预测需求的
2. 测试阶段的逻辑错误
你当前的测试取值、误差计算逻辑完全错误,没有用到模型输出的有效信息:
Y_pred的维度为(测试样本数, 96, 96),三个维度分别对应「样本序号」、「输入序列的第N个时间步」、「未来第M步的预测值」- 你取的
Y_pred[i][0][steps_forward-1]只是第i个样本的第0个输入步对应的未来第96步的单个预测值,既没有用到完整96步输入的信息,也没有拿到完整的未来96步预测结果 - 你用来对比的真值
X_test[:,0]是输入序列第一个时间步的真实值,根本不是未来第96步的真实值,误差计算完全没有参考意义
3. 修正方案
如果要实现「输入过去96步,一次性输出未来96步全量预测」的需求,有两种调整方向:
- 方案一(简单高效):去掉
return_sequences=True配置和TimeDistributed包装,直接用普通全连接层输出96个预测值:
对应标签也不需要构造三维数组,直接取每个样本对应未来96步的真实值,shape为model = keras.models.Sequential([ keras.layers.SimpleRNN(90, return_sequences=True, input_shape=[None, 2]), keras.layers.SimpleRNN(60, return_sequences=False), keras.layers.Dense(steps_forward) ])(样本数, 96)即可,测试时每个样本的输出直接就是未来96步的预测结果。 - 方案二(保留现有seq2seq结构):取每个测试样本最后一个输入步的输出作为预测结果:
# 取完整输入序列对应的未来96步预测 Y_pred = model.predict(X_test)[:, -1, :] # 对比的真值需要对应每个样本的未来96步真实值,而非输入序列内的数值
内容的提问来源于stack exchange,提问作者PeterBe
相关产品推荐
相关产品推荐

