使用 Keras LSTM 进行多步超前时间序列预测的多个输出
Multiple outputs for multi step ahead time series prediction with Keras LSTM
在类似 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])
其中 y1
和 y2
与 y
(500, 5) 具有相同的维度。但是我收到以下错误:
"Error when checking target: expected dense_4 to have 3 dimensions, but got array with shape (500, 5)".
y1
和y2
应该如何整形?或者我应该使用不同的网络结构吗?
在评论之后,我无法 post 阅读代码:
如果你想在 2 个输出上训练你的网络,保持架构接近你 posted 的第二个网络之一,但使用 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 网络,但这会使计算量增加一倍。
另一种选择是让 LSTM 直接输出多个值。基本思想是在第二个 LSTM 层中保留 return_sequence=True
的第一个模型。这里的问题是,如果你想保留 7 个时间步长作为输入而只得到 5 个作为输出,你需要在第一个 LSTM 层和输出层之间的某处切分你的张量,这样你就可以将输出时间步长减少到 5。问题是keras中没有实现slice
层。 This 是一个可以切片的自定义图层。另外,从理论上讲,我不确定这种架构是否有效。
最后一点:您可以转置层而不是切片,使用密集来减少所需的尺寸,然后转回原始尺寸,或者类似地使用 Flatten -> Dense 和 reshape。这两个选项都会给你一个有效的架构(意味着 keras 将编译和适合),但在这两种情况下你都会弄乱时间维度,这是不可取的。
希望对您有所帮助
在类似 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])
其中 y1
和 y2
与 y
(500, 5) 具有相同的维度。但是我收到以下错误:
"Error when checking target: expected dense_4 to have 3 dimensions, but got array with shape (500, 5)".
y1
和y2
应该如何整形?或者我应该使用不同的网络结构吗?
在评论之后,我无法 post 阅读代码:
如果你想在 2 个输出上训练你的网络,保持架构接近你 posted 的第二个网络之一,但使用 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 网络,但这会使计算量增加一倍。
另一种选择是让 LSTM 直接输出多个值。基本思想是在第二个 LSTM 层中保留 return_sequence=True
的第一个模型。这里的问题是,如果你想保留 7 个时间步长作为输入而只得到 5 个作为输出,你需要在第一个 LSTM 层和输出层之间的某处切分你的张量,这样你就可以将输出时间步长减少到 5。问题是keras中没有实现slice
层。 This 是一个可以切片的自定义图层。另外,从理论上讲,我不确定这种架构是否有效。
最后一点:您可以转置层而不是切片,使用密集来减少所需的尺寸,然后转回原始尺寸,或者类似地使用 Flatten -> Dense 和 reshape。这两个选项都会给你一个有效的架构(意味着 keras 将编译和适合),但在这两种情况下你都会弄乱时间维度,这是不可取的。
希望对您有所帮助