问题一:
从您的表格中,我看到您在单个序列上有一个滑动窗口,用 2 个步骤制作了许多较小的序列。
- 为了预测 t,您将表格的第一行作为输入
- 为了预测 t+1,您将第二行作为输入。
如果您不使用表格:请参阅问题 3
问题2:
假设您使用该表作为输入,显然它是一个滑动窗口案例,需要两个时间步作为输入,您的 timeSteps 为 2。
您可能应该将var1 和var2 视为相同顺序的特征:
-
input_shape = (2,2) - 两个时间步长和两个特征/变量。
问题3:
我们不需要制作这样的桌子或构建滑动窗口案例。这是一种可能的方法。
您的模型实际上能够学习并决定此窗口本身的大小。
如果一方面您的模型能够学习长时间依赖,允许您不使用窗口,另一方面,它可以学习识别序列开始和中间的不同行为。在这种情况下,如果您想使用从中间开始的序列(不包括开头)进行预测,您的模型可能会像开头一样工作并预测不同的行为。使用窗户可以消除这种长期的影响。我猜哪个更好可能取决于测试。
不使用窗口:
如果您的数据有 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, ....)
预测:
为了预测,创建一个类似的模型,现在使用return_sequences=False。
复制权重:
newModel.set_weights(model.get_weights())
例如,您可以输入长度为 800 的输入(形状:(1,800,2))并预测下一步:
step801 = newModel.predict(X)
如果你想预测更多,我们将使用stateful=True 层。再次使用相同的模型,现在使用 return_sequences=False(仅在最后一个 LSTM 中,其他保持 True)和 stateful=True(全部)。将input_shape 更改为batch_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
实际上,您可以使用单个 stateful=True 和 return_sequences=True 模型完成所有操作,只需处理两件事:
- 训练时,
reset_states() 用于每个 epoch。 (使用手动循环训练和epochs=1)
- 从多个步骤进行预测时,仅将输出的最后一步作为所需结果。