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

时间:2017-12-01 15:36:20

标签: time-series keras lstm multi-step multipleoutputs

在类似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?或者我应该为网络设置不同的结构?

1 个答案:

答案 0 :(得分:0)

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

如果你想训练你的网络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个网络,就像你提出的第一个网络一样,但这会使计算工作量增加一倍。

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

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

希望这个帮助