【问题标题】:How to deal with multi step time series forecasting in multivariate LSTM in keras如何处理keras中多元LSTM中的多步时间序列预测
【发布时间】: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
  1. Q1:我已经用上面的数据训练了一个 LSTM 模型。这个模型做 很好地预测了时间步 t 的 var2 的值。然而,什么 如果我想在时间步 t+1 预测 var2。我觉得很难 因为模型无法告诉我 var1 在时间步 t 的值。如果我想做,我应该如何修改code来构建模型?
  2. Q2:我看到这个问题问了很多,但我还是很困惑。在 我的例子,[样本,时间中的正确时间步长应该是多少? 步骤、特点] 1还是2?
  3. 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)。

标签: tensorflow deep-learning time-series keras lstm


【解决方案1】:

实际上,您不能只输入原始时间序列数据,因为网络无法自然适应它。 RNN 的当前状态仍然需要您输入多个“特征”(手动或自动导出),才能正确学习有用的东西。

通常需要的先前步骤是:

  1. 去趋势
  2. 去季节化
  3. 缩放(标准化)

一个重要的信息来源是来自微软研究员的this post,他通过 LSTM 网络赢得了时间序列预测比赛。

还有这个帖子:CNTK - Time series Prediction

【讨论】:

    【解决方案2】:

    问题一:

    从您的表格中,我看到您在单个序列上有一个滑动窗口,用 2 个步骤制作了许多较小的序列。

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

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

    问题2:

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

    您可能应该将var1var2 视为相同顺序的特征:

    • 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=Truereturn_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 不会影响预测(每个新预测都不会被视为新步骤),对吧?
    猜你喜欢
    • 2021-09-08
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 2020-06-29
    • 1970-01-01
    相关资源
    最近更新 更多