不确定为什么我的 LSTM 神经网络会报错。似乎与输入形状有关。
这是我的神经网络架构:
from keras.models import Sequentialfrom keras.layers import LSTM, Dense, Dropoutmodel = Sequential()# 循环层model.add(LSTM(64, return_sequences=False, dropout=0.1, recurrent_dropout=0.1))# 全连接层model.add(Dense(64, activation='relu'))# 正则化的 Dropoutmodel.add(Dropout(0.5))# 输出层model.add(Dense(y_train.nunique(), activation='softmax'))# 编译模型model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
这是我如何训练它的:
history = model.fit(X_train_padded, y_train_padded, batch_size=2048, epochs=150, validation_data=(X_test_padded, y_test_padded))
这是我的输入数据的形状:
print(X_train_padded.shape, X_test_padded.shape, y_train_padded.shape, y_test_padded.shape)(98, 20196, 30) (98, 4935, 30) (98, 20196, 1) (98, 4935, 1)
这是我的 X_train_padded 的一部分:
X_train_paddedarray([[[ 2.60352379e-01, -1.66420518e-01, -3.12893162e-01, ..., -1.51210476e-01, -3.56188897e-01, -1.02761131e-01], [ 1.26103191e+00, -1.66989382e-01, -3.13025807e-01, ..., 6.61329839e+00, -3.56188897e-01, -1.02761131e-01], [ 1.04418243e+00, -1.66840157e-01, -3.12994596e-01, ..., -1.51210476e-01, -3.56188897e-01, -1.02761131e-01], ..., [ 1.27399408e+00, -1.66998426e-01, -3.13025807e-01, ..., 6.61329839e+00, -3.56188897e-01, -1.02761131e-01],
这是我得到的错误:
Epoch 1/150---------------------------------------------------------------------------ValueError Traceback (most recent call last)<ipython-input-52-52422b54faa4> in <module>----> 1 history = model.fit(X_train_padded, y_train_padded, 2 batch_size=2048, epochs=150, 3 validation_data=(X_test_padded, y_test_padded))...ValueError: Shapes (None, 20196) and (None, 12) are incompatible
由于我在使用 LSTM 层,我的输入形状是三维的。我的输出层有 12 个节点 (y_train.nunique()),因为我的输入中有 12 个不同的类别。鉴于我有 12 个类别,我在输出层使用 softmax 作为激活函数,并使用 categorical_crossentropy 作为我的损失函数。
编辑:
让我尝试更好地解释我的 数据集 :
我在处理地质井。我的样本是不同类型的沉积岩层,特征是岩石的属性(如伽马射线发射),标签是岩石类型(如石灰岩)。我的一个特征是层深度。
在这种情况下使用 LSTM 的想法,是将井深视为一个序列。使得前一个沉积层(岩石)有助于预测下一个沉积层(岩石)。
我是如何得到我的输入形状的:
我的数据集中总共有 98 口井。我分割了数据集: X_train_init, X_test_init, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
。在训练集中,样本最多的井有 20196 个样本(层)。那些样本数量不够多的井,我用零填充它们,使它们有 20196 个样本。在测试集中,样本最多的井有 4935 个样本。那些样本数量不够多的井,我用零填充它们,使它们有 4935 个样本。移除 well 特征和 depth 特征(以及其他特征)后,我总共得到了 30 个特征。我的 y_train
和 y_test
只有 1 列,表示标签。
我想我的问题实际上是如何让这个数据集在 LSTM 中工作。大多数我看到的例子都没有 98 个不同的时间序列,它们只有一个。我不太确定如何处理 98 个不同的时间序列(井)。
回答:
这是行不通的。除了批量大小之外,其他每个输入维度都应该相同。此外,你的输入维度都有些混乱。例如 –
print(X_train_padded.shape, # (98, 20196, 30)X_test_padded.shape, # (98, 4935, 30)y_train_padded.shape, # (98, 20196, 1)y_test_padded.shape) # (98, 4935, 1)
据我所见,第一个维度应该代表总样本数(在 x_train,y_train, 和 x_test,y_test 中),但在你的情况下,总样本数由第二个维度表示。第一个维度应该放在第二位。也就是说,维度应该是
print(X_train_padded.shape, # (20196, 98, 30)X_test_padded.shape, # (4935, 98, 30)y_train_padded.shape, # (20196, 98, 1)y_test_padded.shape) # (4935, 98, 1)
这样一切都会到位。你只需要查看你是如何得到错误维度的,并更改那部分内容。