如何处理keras中多元LSTM中的多步时间序列预测
Posted
技术标签:
【中文标题】如何处理keras中多元LSTM中的多步时间序列预测【英文标题】:How to deal with multi step time series forecasting in multivariate LSTM in keras 【发布时间】:2018-04-04 17:03:20 【问题描述】:我正在尝试在 Keras 中使用多元 LSTM 进行多步时间序列预测。具体来说,我最初为每个时间步长有两个变量(var1 和 var2)。遵循在线教程here,我决定使用时间(t-2)和(t-1)的数据来预测时间步t var2的值。如示例数据表所示,我使用前 4 列作为输入,Y 作为输出。我开发的代码可以看到here,但是我有三个问题。
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
-
Q1:我已经用上面的数据训练了一个 LSTM 模型。这个模型做
很好地预测了时间步 t 的 var2 的值。然而,什么
如果我想在时间步 t+1 预测 var2。我觉得很难
因为模型无法告诉我 var1 在时间步 t 的值。如果我想做,我应该如何修改code来构建模型?
Q2:我看到这个问题问了很多,但我还是很困惑。在
我的例子,[样本,时间中的正确时间步长应该是多少?
步骤、特点] 1还是2?
Q3:我刚开始学习 LSTM。我有
阅读here,LSTM 的最大优势之一是它
自己学习时间依赖性/滑动窗口大小,然后
为什么我们必须总是将时间序列数据转换为像
上表?
更新:LSTM 结果(蓝线是训练序列,橙线是ground truth,绿色是预测)
【问题讨论】:
var1 和 var2 是否相互独立?您只想预测 var 2 吗?你不想预测 var 1 吗? 他们是独立的。只需将它们视为降水和土壤水分。是的,我只想预测 var1。 土壤水分不依赖于降水...你有完整的降水值序列要输入吗? 是的,我知道有一些相关性,也许是一个不好的例子。只是想简化案例。我之前的评论有错别字,我只想预测 var2。是的,我在这里有完整的月度数据序列:github.com/Yongyao/enso-forcasting/blob/master/preprocessed/… 但是 var 2 依赖于 var 1,对吧? (如果是这样,您也必须预测 var 1)。 【参考方案1】:实际上,您不能只输入原始时间序列数据,因为网络无法自然适应它。 RNN 的当前状态仍然需要您输入多个“特征”(手动或自动导出),才能正确学习有用的东西。
通常需要的先前步骤是:
-
去趋势
去季节化
缩放(标准化)
一个重要的信息来源是来自微软研究员的this post,他通过 LSTM 网络赢得了时间序列预测比赛。
还有这个帖子:CNTK - Time series Prediction
【讨论】:
【参考方案2】:问题一:
从您的表格中,我看到您在单个序列上有一个滑动窗口,用 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
)
从多个步骤进行预测时,仅将输出的最后一步作为所需结果。
【讨论】:
谢谢!这很有帮助。 (1) 对于 Q1 和 Q2,如果我使用滑动窗口并且在这种情况下 input_shape = (2,2),这是否意味着我告诉 LSTM t 步骤仅与前两个步骤相关 - t-1 和 t -2、这被称为经典的滑动窗口效应? (2)如果我接受你最后一次手动循环训练的建议,我可以重复调用 model.fit() 吗? 是的...如果使用具有 2 个步骤的滑动窗口,您的 LSTM 将只能学习 2 个步骤,而不能学习其他任何东西。 --- 在最后一个建议中,是的,model.fit(longSequence,longPrediction, epochs=1)
,但最好使用model.train_on_batch()
,不要忘记为每个循环重置状态。
我刚开始使用 LSTM。如果内存静止是由窗口大小决定的,那就意味着我不能同时拥有长内存和短内存,但是LSTM是长短期内存的缩写,是不是很奇怪?
....等等....什么??哈哈哈……我不喜欢推拉窗套……我几乎没用过。我喜欢 Q3 之类的方法。他们确实利用了 LSTM 功能。
刚刚尝试了您的建议,1) 结果表明 Keras 不支持 input_shape=(None,2) 。有人说只有 TensorFlow 支持变量输入。 2)另一件事是,如果我理解正确, stateful=True 不会影响预测(每个新预测都不会被视为新步骤),对吧?以上是关于如何处理keras中多元LSTM中的多步时间序列预测的主要内容,如果未能解决你的问题,请参考以下文章
Keras 如何处理单元格和隐藏状态(RNN、LSTM)的初始值以进行推理?