使用 Keras LSTM 进行多步提前时间序列预测的多个输出

Posted

技术标签:

【中文标题】使用 Keras LSTM 进行多步提前时间序列预测的多个输出【英文标题】:Multiple outputs for multi step ahead time series prediction with Keras LSTM 【发布时间】:2018-05-15 18:06:33 【问题描述】:

按照类似的question,我遇到了一个问题,我需要在 3 个不同的时间序列之前预测很多步。我设法生成了一个网络,将 3 个时间序列的过去 7 个值作为输入,预测其中一个的 5 个未来值。输入 x 具有以下维度:

(500, 7, 3): 500 samples, 7 past time steps, 3 variables/time series) 

目标y 具有以下维度:

(500, 5): 500 samples, 5 future time steps

LSTM 网络定义为:

model = Sequential()
model.add(LSTM(input_dim=3, output_dim=10,  return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(50))
model.add(Dropout(0.2))
model.add(Dense(input_dim=10, output_dim=7))
model.add(Activation('linear'))
model.compile(loss='mae', optimizer='adam')

如果我现在想预测 2 个时间序列的值怎么办?

我尝试了以下代码:

inputs = Input(shape=(7,3)) # 7 past steps and variables
m = Dense(64,activation='linear')(inputs)
m = Dense(64,activation='linear')(m)
outputA = Dense(1,activation='linear')(m)
outputB = Dense(1,activation='linear')(m)

m = Model(inputs=[inputs], outputs=[outputA, outputB])
m.compile(optimizer='adam', loss='mae')
m.fit(x,[y1,y2])

y1y2 的维度与 y (500, 5) 相同。但我收到以下错误:

"Error when checking target: expected dense_4 to have 3 dimensions, but got array with shape (500, 5)".

我应该如何重塑y1y2?或者我应该为网络设置不同的结构?

【问题讨论】:

您使用 (7,3) 作为输入形状,但与第一个示例不同,您没有使用 LSTM,如 documentation 中所述,它将输入张量的维度从3 到 2。要使此模型正常工作,您必须在输出层之前添加 LSTM(使用 return_sequence=False)或展平层 我添加了一个扁平层:flat = Flatten()(m) ; outputA = Dense(ahead,activation='linear')(flat) ; outputB = Dense(ahead,activation='linear')(flat)。现在它确实训练了,但是为什么现在网络的训练速度更快了? @gionni 这个网络:inputs = Input(shape=(7,6)) d1 = Dropout(0.2)(inputs) m = Dense(50,activation='linear')(d1) d2 = Dropout(0.2)(m) flat = Flatten()(d2) outputA = Dense(ahead,activation='linear')(flat) outputB = Dense(ahead,activation='linear')(flat) m = Model(inputs=[inputs], outputs=[outputA, outputB]) m.compile(optimizer='adam', loss='mae') 是否等同于我的第一个示例中的网络? 关于第一条评论:它更快,因为你没有 LSTM 层,它训练起来很慢,而 Flatten 层只是对输入张量进行重塑。同样,对于第二条评论,它不会相同,因为您没有 LSTM 层。 谢谢。 LSTM 层可以有多个输出吗?我的意思是,我可以重复使用我的第一个网络吗? (抱歉,对 LSTM 来说是全新的)。 【参考方案1】:

在评论之后,我无法发布可读代码:

如果您想在 2 个输出上训练您的网络,保持架构接近您发布的第二个网络之一,但使用 LSTM,这应该可以:

from keras.layers import Input, Dense, Dropout, LSTM

inputs = Input(shape=(7,3)) # 7 past steps and variables
m = LSTM(10,  return_sequences=True)(inputs)
m = Dropout(0.2)(m)
m = LSTM(50)(m)
m = Dropout(0.2)(m)
outputA = Dense(5, activation='linear')(m)
outputB = Dense(5, activation='linear')(m)

m = Model(inputs=[inputs], outputs=[outputA, outputB])
m.compile(optimizer='adam', loss='mae')
m.fit(x,[y1,y2])

请注意,如果您预测的 2 个时间序列中的时间相关性相似,此架构将提供良好的结果,因为您将使用相同的 LSTM 层来处理这两个层,并在最后一层进行拆分,这将是对每个时间序列的结果进行微调。另一种选择是像您建议的第一个一样使用 2 net,但这会使计算量加倍。

另一种选择是让 LSTM 直接输出多个值。基本思想是将您的第一个模型与return_sequence=True 保留在第二个 LSTM 层中。这里的问题是,如果您想保留 7 个时间步长作为输入而只获得 5 个作为输出,则需要在第一个 LSTM 层和输出层之间的某个位置对张量进行切片,以便将输出时间步长减少到 5 个。问题是 keras 中没有实现 slice 层。 This 是一个可以切片的自定义层。从理论上讲,我也不确定这种架构是否有效。

最后一点:您可以转置图层,而不是切片,使用密集来减少所需的尺寸,然后转置回原始尺寸,或者类似地使用 Flatten -> Dense 和 reshape。这两个选项都会给你一个有效的架构(这意味着 keras 将编译和适应),但在这两种情况下你都会弄乱时间维度,这是不可取的。

希望有帮助

【讨论】:

感谢@gionni 的详尽评论。我认为您的第一个解决方案更适合我的需求(对 keras 不太熟悉,我是新手)。我会尝试使用它,看看它是否能给我很好的预测。

以上是关于使用 Keras LSTM 进行多步提前时间序列预测的多个输出的主要内容,如果未能解决你的问题,请参考以下文章

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

Keras每一步的多步LSTM批量训练分类

如何为LSTM Keras中的多步和多变量准备时间序列数据

Keras LSTM:如何预测超越验证与预测?

使用带有 LSTM 的预训练 word2vec 进行单词生成

Keras 中的多步多元时间序列分类