首页 > 解决方案 > LSTM Keras 输入形状混淆

问题描述

我正在尝试建立一个股票价格的预测模型。根据我的阅读,LSTM 是一个很好的层。不过,我无法完全理解input_shape我的模型需要什么。

这是tail我的DataFrame

打印(x_test.shape)

然后我将数据拆分为训练/测试

labels = df['close'].values
x_train_df = df.drop(columns=['close'])
x_train, x_test, y_train, y_test = train_test_split(x_train_df.values, labels, test_size=0.2, shuffle=False)

min_max_scaler = MinMaxScaler()
x_train = min_max_scaler.fit_transform(x_train)
x_test = min_max_scaler.transform(x_test)

print('y_train', y_train.shape)
print('y_test', y_test.shape)
print('x_train', x_train.shape)
print('x_test', x_test.shape)
print(x_train)

这产生:

在此处输入图像描述

这就是我感到困惑的地方。运行这个简单的例子,我得到以下错误:

ValueError:lstm_15 层的输入 0 与层不兼容:预期 ndim=3,发现 ndim=4。收到的完整形状:[None, 1, 4026, 5]

我尝试了各种混淆的组合input_shape并得出结论,我不知道如何确定输入形状。

model = Sequential()
model.add(LSTM(32, input_shape=(1, x_train.shape[0], x_train.shape[1])))

model.compile(optimizer='adam', loss='mse', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=10)

鉴于我的数据框,我的应该是什么input_shape?我知道输入形状是batch size, timesteps, data dim. 只是不清楚如何将这些词映射到我的实际数据,因为我认为这些值实际上不是。

我刚在想:

标签: pythontensorflowkeraslstm

解决方案


首先,我认为你根本不需要 LSTM。基于 ,在df.tail()我看来,熊猫数据框的行(数据集的样本)之间没有时间依赖性。无论如何,我稍后会回到这个问题,首先是你的问题:

  1. 批次大小:批次中的元素数量。该数据集总共包含 4026 个元素。另一方面,批量大小是在单个批次中处理的元素数量。让我们假设它是 2。在这种情况下,您将拥有2013这些批次。

  2. 时间步长:等于它们之间具有时间依赖性的样本数。假设在您的数据集中,每 3 个实例构成数据序列,那么时间步长将为3. 因此,数据集中的每个样本现在都包含3测量值,因此元素的总数为1342(开始时为4026)。

  3. 数据维度:批次中每个元素的特征数量,对于每个时间步 - 在您的情况下5,假设它buy是标签并且date是时间依赖性列。

因此,单批数据的形状应该是(2, 3, 6),而整个数据集的形状应该是(1342, 3, 6)。请注意,如果我们认为您使用 LSTM 并且每个时间步之间存在时间依赖性,则这些形状是有效的。这是一个示例代码片段来验证一些东西:

# Random training data
x_train = np.random.rand(1342, 3, 6)
# Random training labels
y_train = np.random.randint(0, 2, 1342)

model = Sequential()
model.add(LSTM(32, input_shape=(3, 6)))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=2, batch_size=32)

现在,回到我之前的观点。看着df.tail(),在我看来,数据集中的样本之间没有任何时间依赖性。话虽如此,我会首先将date列转换为有意义的内容(一年中月份的单热编码,取决于月份的 4 个季节的单热编码等)。然后,我将继续使用具有二进制分类输出层的前馈神经网络,而不是构建 RNN。

至于模型,一旦你处理了所有与数据相关的东西,像这样简单的东西应该适合你:

# Random training data
x_train = np.random.rand(4026, 5)
# Random training labels
y_train = np.random.randint(0, 2, 4026)

model = Sequential()
model.add(Dense(32, activation='relu', input_dim=5))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(x_train y_train, epochs=2, batch_size=32)

希望对您有所帮助!


推荐阅读