如何处理keras中多变量LSTM的多步时间序列预测

Yon*_*ang 3 time-series deep-learning lstm keras tensorflow

我正在尝试使用Keras中的多变量LSTM进行多步时间序列预测.具体来说,我最初每个时间步有两个变量(var1和var2).在这里遵循在线教程后,我决定在时间(t-2)和(t-1)使用数据来预测时间步t的var2的值.如示例数据表所示,我使用前4列作为输入,Y作为输出.我可以在这里看到我开发的代码,但我有三个问题.

   var1(t-2)  var2(t-2)  var1(t-1)  var2(t-1)  var2(t)
2        1.5       -0.8        0.9       -0.5     -0.2
3        0.9       -0.5       -0.1       -0.2      0.2
4       -0.1       -0.2       -0.3        0.2      0.4
5       -0.3        0.2       -0.7        0.4      0.6
6       -0.7        0.4        0.2        0.6      0.7
Run Code Online (Sandbox Code Playgroud)
  1. 问题1:我已经使用上述数据训练了LSTM模型.该模型在预测时间步t的var2值方面表现良好.但是,如果我想在时间步t + 1预测var2,该怎么办?我觉得很难,因为模型不能告诉我var1在时间步t的值.如果我想这样做,我应该如何修改代码来构建模型?
  2. Q2:我已经看到这个问题了很多,但我仍然感到困惑.在我的例子中,[样本,时间步长,特征] 1或2中的正确时间步长应该是多少?
  3. Q3:我刚开始学习LSTM.我在这里读到LSTM最大的优点之一就是它自己学习了时间依赖性/滑动窗口大小,为什么我们必须总是将时间序列数据转换成如上表所示的格式?

更新:LSTM结果(蓝线是训练序列,橙线是基础事实,绿色是预测) 在此输入图像描述

Dan*_*ler 7

问题1:

从你的表中,我看到你在一个序列上有一个滑动窗口,通过两个步骤制作许多较小的序列.

  • 为了预测t,您将表的第一行作为输入
  • 对于预测t + 1,您将第二行作为输入.

如果您不使用该表:请参阅问题3

问题2:

假设您正在使用该表作为输入,它显然是一个滑动窗口案例,需要两个时间步作为输入,您的timeSteps是2.

你或许应该工作,就好像var1var2在同一个序列特征:

  • input_shape = (2,2) - 两个时间步和两个功能/变量.

问题3:

我们不需要像这样制作表格或构建滑动窗口案例.这是一种可能的方法.

你的模型实际上能够学习东西并决定这个窗口本身的大小.

如果一方面您的模型能够学习长时间的依赖性,另一方面,它允许您不使用窗口,它可以学习在序列的开头和中间识别不同的行为.在这种情况下,如果您想要预测使用从中间开始的序列(不包括开头),您的模型可能就像它是开始并预测不同的行为一样.使用Windows消除了这种非常长的影响.我想,哪个更好可能取决于测试.

不使用Windows:

如果您的数据有800个步骤,请立即提供所有800个步骤进行培训.

在这里,我们需要分开两个模型,一个用于训练,另一个用于预测.在训练中,我们将利用该参数return_sequences=True.这意味着对于每个输入步骤,我们将得到一个输出步骤.

为了以后预测,我们只需要一个输出,然后我们将使用return_sequences= False.如果我们要将预测输出用作后续步骤的输入,我们将使用一个stateful=True层.

训练:

将您的输入数据整形为(1, 799, 2)1个序列,步骤从1到799.两个变量都在相同的序列中(2个特征).

让您的目标数据(Y)也成形(1, 799, 2),采取相同的步骤,从2到800.

建立一个模型return_sequences=True.您可以使用timeSteps=799,但也可以使用None(允许可变数量的步骤).

model.add(LSTM(units, input_shape=(None,2), return_sequences=True))
model.add(LSTM(2, return_sequences=True)) #it could be a Dense 2 too....
....
model.fit(X, Y, ....)
Run Code Online (Sandbox Code Playgroud)

预测:

对于预测,现在创建一个类似的模型return_sequences=False.

复制权重:

newModel.set_weights(model.get_weights())
Run Code Online (Sandbox Code Playgroud)

例如,您可以输入长度为800的形状(形状:),(1,800,2)并预测下一步:

step801 = newModel.predict(X)
Run Code Online (Sandbox Code Playgroud)

如果您想要预测更多,我们将使用这些stateful=True图层.再次使用相同的模型,现在return_sequences=False(仅在最后一个LSTM中,其他保持为True)和stateful=True(所有这些).变化input_shapebatch_input_shape=(1,None,2).

#with stateful=True, your model will never think that the sequence ended  
#each new batch will be seen as new steps instead of new sequences
#because of this, we need to call this when we want a sequence starting from zero:
statefulModel.reset_states()

#predicting
X = steps1to800 #input
step801 = statefulModel.predict(X).reshape(1,1,2)
step802 = statefulModel.predict(step801).reshape(1,1,2)
step803 = statefulModel.predict(step802).reshape(1,1,2)
    #the reshape is because return_sequences=True eliminates the step dimension   
Run Code Online (Sandbox Code Playgroud)

其实,你可以做一个单一的一切stateful=Truereturn_sequences=True模型,以两件事情护理:

  • 在训练时,reset_states()每个时代.(用手动循环训练epochs=1)
  • 从多个步骤预测时,仅将输出的最后一步作为所需结果.