【问题标题】:Warning for input shape in LSTM modelLSTM 模型中输入形状的警告
【发布时间】:2022-11-11 00:21:53
【问题描述】:

我有每小时用电量的时间序列数据,长度为(17544, 1),格式如下:

[[17.6]
 [38.2]
 [39.4]
 ...
 [46. ]
 [44. ]
 [40.2]]

我的目标是使用过去 7 天的数据作为输入,即 24*7=168,并预测接下来 24 小时的用电量。

我正在使用以下脚本来准备数据集以进行训练和测试:

# Split into training/test sets
train_size = int(len(data) * 0.7)
val_size = int(len(data) * 0.2)
train, val, test = data[:train_size], data[train_size:(train_size + val_size)], data[(train_size + val_size):]

# Prepare the data in a format required for LSTM (samples, timesteps, features)

def Create_Dataset(df, lookback=1, prediction_horizon=1):
    X, Y = [], []
    for i in range(lookback, len(df)-lookback):
        X.append(df[i-lookback : i, 0])
        Y.append(df[i : i + prediction_horizon, 0])
    return np.array(X), np.array(Y)

lookback = 7 * 24
prediction_horizon = 24
X_train, Y_train = Create_Dataset(train, lookback, prediction_horizon)
X_val, Y_val = Create_Dataset(val, lookback, prediction_horizon)
X_test, Y_test   = Create_Dataset(test, lookback, prediction_horizon)

X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))
X_val = np.reshape(X_val, (X_val.shape[0], X_val.shape[1], 1))
X_test  = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))

该模型具有以下形式:

model = Sequential()
model.add(LSTM(64, input_shape=(X_train.shape[1], X_train.shape[2])))
model.add(Dropout(0.2))
model.add(Dense(prediction_horizon))

model.compile(optimizer='adam', loss='mean_squared_error', metrics=['mean_absolute_error'])

我已经成功地训练了模型,我需要使用外部数据对其进行验证。我希望通过提供以下长度为(168, 1) 的输入:

[[17.6]
 [38.2]
 [39.4]
 ...
 [46.9]
 [48.6]
 [46.1]]

我将得到 24 个预测点的输出,但我得到的输出形状为 (168,24) 和以下警告:

WARNING:tensorflow:Model was constructed with shape (None, 168, 1) for input KerasTensor(type_spec=TensorSpec(shape=(None, 168, 1), dtype=tf.float32, name='lstm_3_input'), name='lstm_3_input', description="created by layer 'lstm_3_input'"), but it was called on an input with incompatible shape (None, 1, 1).

知道这里有什么问题吗?

【问题讨论】:

  • 第一印象:有状态与无状态?使用 LSTM 之类的有状态网络,您可以一次持续提供一个输入。 Keras 有一个“无状态”简化,它从零状态开始,然后在内部循环 N 个输入。因此,从外部看来,您一次提供了所有 N 个输入。
  • @MSalters如果我想使用这个模型进行实时预测,即使用过去 168 小时作为输入并预测接下来的 24 小时,然后在 1 小时后使用过去 168 小时作为输入并预测接下来的 24 小时等我应该使用哪一个?无状态还是有状态?

标签: python numpy keras deep-learning lstm


【解决方案1】:

在 Keras 中,LSTM 采用具有形状的 3D 输入[批次、时间步长、特征].在 Keras 批处理中通常显示为没有任何因为它可能会有所不同(您可以在警告中看到这一点)。您的时间步长为 168,特征为 1,因为您唯一的特征是一个值。我认为问题在于您输入的 (168,1) 没有 3D 形状。我的猜测是你可能在某个地方重塑它,它变成(168,1,1)。否则,馈送 2D 形状应该给出错误而不是警告。然后它变得好像你有一批 168 而不是 1。 这就是为什么它说你的输入是(None,1,1)。因此,您只需将输入重塑为 (1,168,1)。

总结问题,您的输入必须是一个 3D 张量,其形状为[批次、时间步长、特征].如果您有一个具有 2D 形状的样本,您只需将其重塑为 (1,168,1)。

最后我要提到的一件事是,您正在一次预测接下来的 24 小时(在密集层中)。通常我们一次预测一步。预测多个值有点违背 LSTM 的目的。通常在一次预测之后,我们将 LSTM 的输出输入到自身中,就好像它是一个正确的值一样。 不幸的是,我不确定如何在 Keras 中实现它,但我将添加一个伪代码来描述总体思路。

out, state = lstm(input.reshape(1,168,1)) 
for i in range(24): 
    out,state = lstm(out,state)

在这里,您在下一个时间步将 LSTM 的输出提供给它自己。你也必须给它状态。 LSTM 具有在每个时间步中传递和更改的状态。(LSTM 使用它来通过时间传递信息)。循环中的每个输出张量将对应于每小时的预测。您可以查看Andrej Karpathy's famous blog post 以获得更好的想法。在该博客中,类似的想法用于构建基于单个字母生成脚本的网络。它是字符级语言模型部分。这个想法几乎是一样的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-26
    • 2016-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    相关资源
    最近更新 更多