1

使用 LSTM 和 Keras,我构建了一个简单的时间序列预测模型,其工作原理如下:假设我有过去 10 个时间段的数据(标准化并准备好训练),该模型可以预测前两个时间段的值。

我的数据形状类似于:

X = [[[1,2,3,4,5,6,7,8,9,10],[2,3,4,5,6,7,8,9,10,11],[3 ,4,5,6,7,8,9,10,11,12]]]

Y = [[11,12],[12,13],[14,15]]

该模型由一个具有 rnn_size 个节点的 LSTM 层和一个 dropout 层组成。

    model = Sequential()

    model.add(LSTM(rnn_size,
    batch_input_shape=(batch_size, X.shape[1], 
    X.shape[2]),stateful=True,dropout=dropout))

    model.add(Dropout(dropout)) 
    model.add(Dense(y.shape[1]))
    adam_optimizer = keras.optimizers.Adam(clipvalue=5)
    model.compile(loss='mean_squared_error', optimizer=adam_optimizer)
    history = model.fit(X, y, batch_size=batch_size, epochs=nb_epoch, 
                    verbose=2, validation_split=0.1,shuffle=False)
    #################################    
    # Predict
    result = scaler.inverse_transform(
              model.predict_on_batch(test_values[start_date:end_date]
              .values.reshape(1, 1, -1)))

问题是时间段 t+1 的预测值(如图所示)似乎与时间段 t 的值略有不同。

这是(正常)行为吗?如果没有,我该如何克服它?

我认为我对 LSTM 的工作原理有一个相对较好的理解,但是我无法解决这个特定的问题。

编辑1:

我编辑了代码以使用无状态网络配置,并按照 Daniel 的建议编辑了形状。然而问题依然存在。奇怪的是,验证损失(MSE)总是低于训练损失。

编辑2:

根据Marcin 的要求添加的其余代码

之前未向模型显示的测试数据集的实际值与预测值

验证损失小于训练损失!(小波动是因为 Dropout )

4

1 回答 1

0

为了让 LSMT 理解序列,它必须具有如下输入形状(batch,timeSteps,featuresPerStep)

所以,X.shape必须是(batch,10,1)

[[[1],[2],[3],[4],[5],[6],[7],[8],[9],[10]],
 [[2],[3],...........................,[11]],
 [........................................]]

对于创建 LSTM 层,如果不使用,则不需要传递批次大小stateful=True(仅当第二个 bach 中的序列是第一个批次中的序列的续集时才使用此选项)。对于这种滑动窗口案例,您不能将序列拼接在一起。每个序列都是单独的。

LSTM(rnn_size,input_shape=(X.shape[1],X.shape[2]))

这两个变化(X 形和有状态)可能会显着改变您的结果。

于 2017-09-14T17:21:26.830 回答