【问题标题】:Number of test cases predicted are less than the actual test data in LSTM预测的测试用例数量少于 LSTM 中的实际测试数据
【发布时间】:2018-04-16 15:27:35
【问题描述】:

我一直在尝试使用 LSTM Keras 根据时间序列数据预测订单数量。

我将样本数据划分为训练集包含 282 条记录,而测试集包含 82 条记录。我正在使用 30 的回溯窗口 来预测测试数据的预测。

但由于某种原因,预测数据集仅包含 40 条记录,而测试数据中的预期为 71 条记录。背后的原因是什么?是导致问题的查找窗口吗?我觉得回溯窗口导致了这个问题。但是我该如何纠正呢?

保持如此高的回溯窗口很重要

def create_LSTM(trainX,testX,trainY,testY,look_back):
    model = Sequential()
    model.add(LSTM(6, input_shape=(1, look_back),activation= 'relu'))
    model.add(Dense(1))
    model.compile(loss='mean_squared_error', optimizer='RMSProp')
    model.fit(trainX, trainY, epochs=300, batch_size=4, verbose=1)
    trainpredict = model.predict(trainX,batch_size=4)
    testpredict  = model.predict(testX,batch_size=4) 
    testpredict = np.array(testpredict).reshape(len(testpredict),1)      
    print(testpredict) 
    print(len(testpredict))
    return trainpredict,testpredict

我正在使用以下函数为导致实际问题的 LSTM 创建数据。我该如何纠正它?

def create_dataset(dataset, look_back=1):
    dataX, dataY = [], []
    for i in range(len(dataset)-look_back-1):
    #for i in range(len(dataset)-look_back):
        a = dataset[i:(i+look_back), 0]
        dataX.append(a)
        dataY.append(dataset[i + look_back, 0])
    return np.array(dataX), np.array(dataY)

【问题讨论】:

  • trainXtestX 是什么形状?乍一看,您的input_shape 似乎是错误的。第一个维度表示序列长度(在您的情况下为look_back),以下维度表示实际数据形状。
  • 实际上我用来为 LSTM 创建数据的函数实际上导致了问题

标签: python keras time-series lstm


【解决方案1】:

create_dataset 的问题

当您获得 ndarray 的一个元素时,您会失去与该元素关联的排名。发生这种情况是因为如果您对单个元素感兴趣,则不需要保留维度 1

x = np.random.randn(4, 4)
print(x, x.shape)
array([[ 1.37938213, -0.10407424, -0.356567  , -1.5032779 ],
   [-0.53166922,  0.98204605, -0.62052479,  0.99265612],
   [ 0.23046477, -0.17742399,  0.38283412,  0.24104468],
   [-0.78093724,  1.06833765, -1.22112772, -0.78429717]])
(4, 4)

print(x[0:3, 0], x[0:3, 0].shape)
array([ 1.37938213, -0.53166922,  0.23046477])
(3,)

因此,当您编写 a = dataset[i:(i + look_back), 0] 时,您将获取形状为 (samples, features) 的数据集并获得形状为 (look_back,) 的块。将所有 a 添加到 dataX 后,它变成形状为 (samples, look_back) = (len(dataset) - look_back - 1, look_back) 的 ndarray。但是,LSTM 期望形状为 (samples, look_back, features),在您的情况下为 (samples, look_back, 1)

如果您将其更改为a = dataset[i:(i + look_back)],那么一切都会开始工作。然而,更好的解决方案是使用TimeseriesGenerator

from keras.preprocessing.sequence import TimeseriesGenerator

batch_size = 4
look_back = 1
features = 1

d = np.random.randn(364, features)
train = TimeseriesGenerator(d, d,
                            length=look_back,
                            batch_size=batch_size,
                            end_index=282)
test = TimeseriesGenerator(d, d,
                           length=look_back,
                           batch_size=batch_size,
                           start_index=282)

model = Sequential()
model.add(LSTM(6, input_shape=[look_back, features], activation='relu'))
model.add(Dense(1))
model.compile(loss='mse', optimizer='rmsprop')
model.fit_generator(train, epochs=1, verbose=1)
p_train = model.predict_generator(train)
p_test = model.predict_generator(test)

其他部分的进一步评论

  1. model.add(LSTM(6, input_shape=(1, look_back),activation= 'relu')) - 输入形状应符合(length, features)。在这种情况下,length == features,事情会解决的。如果您想要更大的look_back,则需要将此代码更新为input_shape=(look_back, 1)

  2. testpredict = np.array(testpredict).reshape(len(testpredict), 1) - 这是不必要的。 Model#predict 已经输出了一个 ndarray 如果你有一个单一的输出,它的形状已经是 (samples, output_units) = (len(testX), 1)

  3. LSTM(activation='relu') 在处理非常大的序列时通常会导致不稳定。将其留在tanh 中通常是个好主意。

【讨论】:

    猜你喜欢
    • 2016-03-13
    • 2019-12-12
    • 2020-01-18
    • 2021-02-28
    • 1970-01-01
    • 1970-01-01
    • 2021-03-08
    • 2013-05-18
    • 2022-01-21
    相关资源
    最近更新 更多