如何为 LSTM 中的新预测添加先前的预测?

数据挖掘 lstm 预言
2022-02-20 01:16:41

我正在尝试在这样的大数据序列上训练模型[0.2 0.1 0.1 ..... 0.4 0.8]我创建长度为 60 的 X 向量作为输入,Y 缩放器数字作为标签(这意味着 LSTM 读取前 60 个数字作为输入(X_train 中的一行),第 61 个数字作为输出标签(y_train 中的行))。

model = Sequential()
model.add(LSTM(units = 50, return_sequences = True , input_shape = (X_train.shape[1], 1)))
model.add(Dense(units = 1))
model.compile(optimizer = 'adam', loss = 'mean_squared_error')
model.fit(X_train, y_train, epochs = 100, batch_size = 32)

和:

X_train.shape = (1000,60,1) ,       y_train.shape = (1000,)

到这里还可以,但问题出在预测部分。我想做的是创建一个 (60*1) 输入向量并用它来预测我序列中的下一个数字。然后将新的预测数字添加到我的序列中以预测下一个数字(第二个预测数字),依此类推。为了这个目标,我创建了一个新模型,从以前的模型中检索权重,然后只给 new_model 提供一个 (60*1) 向量来预测下一个数字。然后将预测的数字添加到序列中,并将输入向量向右移动一个数字(使用新的预测数字进行下一个数字预测)。

new_model = Sequential()
new_model.add(LSTM(units = 50, return_sequences = True , input_shape = (1 , 60 , 1 )))
new_model.add(Dense(1))
old_weights = model.get_weights()
new_model.set_weights(old_weights)
new_model.compile(optimizer = 'adam', loss = 'mean_squared_error')

inputs = []
for i in range(10):
    inputs = dataset_total[len(dataset_total) - 60:].values
    inputs = np.reshape(inputs, (1 , 60, 1))
    predicted = new_model.predict(inputs)
    inputs.append(predicted)

但我得到的是这样的错误:

ValueError: Input 0 is incompatible with layer lstm_61: expected
ndim=3, found ndim=4

我不知道如何解决这个问题!

这里也有一个类似但没有相关的答案(澄清): 如何用 Keras 预测时间范围的未来值?

1个回答

对于您的问题,Keras 告诉您输入向量有 4 个维度,这是无效的,因为对于 LSTM 模型,您需要一个具有 (batch_size,num_time_steps,feature_space_dimension) 的输入向量。检查输入向量的形状,您可能会使用 reshape 运算符添加额外的 1 维

另一件事是您采用的方法,这可能是有效的,但通常这个问题是用特定类型的模型来解决的:序列到序列模型,使用 LSTM 编码器-解码器架构。

这个模型试图预测一个序列

Y=[x(t=1),x(t=2),...,x(t=t+N)]

从一系列先前的值

X=[x(t=0),x(t=1),...,x(t=tM)]

请注意,每个序列中的样本数可以不同

在这些模型中,输入序列X 被送入 LSTM 编码器,该编码器捕捉其动态,创建一个新的上下文特征向量F. 然后将这个新的特征向量作为初始状态馈送到 LSTM 解码器,然后,预测y^(t)细胞时间t用作单元格时间的输入t+1生成预测值y^(t+1)

一个关键区别是,Seq2seq 模型应该比您的方法更有效,因为它通过一次模型运行来执行 N 个未来值的预测。如果您尝试这种方法并将其与您的方法进行比较,可能会很有趣

您可以在此处访问此类模型的 Keras 教程