数值错误: lstm层的输入与该层不兼容:期望的维度为3,但发现维度为2。完整形状为:[无,18]。

3

我是Keras的新手,正在尝试构建一个个人使用/未来学习的模型。我刚开始接触Python,并借助视频和教程编写了以下代码。我的数据集包含16324个实例,每个实例包含18个特征和1个因变量。

import pandas as pd
import os
import time
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, LSTM, BatchNormalization
from tensorflow.keras.callbacks import TensorBoard, ModelCheckpoint

EPOCHS = 10
BATCH_SIZE = 64
NAME = f"-TEST-{int(time.time())}"

df = pd.read_csv("EntryData.csv", names=['1SH5', '1SHA', '1SA5', '1SAA', '1WH5', '1WHA', '2SA5', '2SAA', '2SH5', '2SHA', '2WA5', '2WAA', '3R1', '3R2', '3R3', '3R4', '3R5', '3R6', 'Target'])

df_val = 14554 

validation_df = df[df.index > df_val]
df = df[df.index <= df_val]

train_x = df.drop(columns=['Target'])
train_y = df[['Target']]
validation_x = validation_df.drop(columns=['Target'])
validation_y = validation_df[['Target']]

model = Sequential()
model.add(LSTM(128, input_shape=(train_x.shape[1:]), return_sequences=True))
model.add(Dropout(0.2))
model.add(BatchNormalization())

model.add(LSTM(128, return_sequences=True))
model.add(Dropout(0.1))
model.add(BatchNormalization())

model.add(LSTM(128))
model.add(Dropout(0.2))
model.add(BatchNormalization())

model.add(Dense(32, activation='relu'))
model.add(Dropout(0.2))

model.add(Dense(2, activation='softmax'))

opt = tf.keras.optimizers.Adam(lr=0.001, decay=1e-6)

model.compile(loss='sparse_categorical_crossentropy',
              optimizer=opt,
              metrics=['accuracy'])

tensorboard = TensorBoard(log_dir=f'logs/{NAME}')

filepath = "RNN_Final-{epoch:02d}-{val_acc:.3f}"  
checkpoint = ModelCheckpoint("models/{}.model".format(filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max')) # saves only the best ones

history = model.fit(
    train_x, train_y,
    batch_size=BATCH_SIZE,
    epochs=EPOCHS,
    validation_data=(validation_x, validation_y),
    callbacks=[tensorboard, checkpoint],)

score = model.evaluate(validation_x, validation_y, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

model.save("models/{}".format(NAME))

在以下代码中:

model.add(LSTM(128, input_shape=(train_x.shape[1:]), return_sequences=True))

出现了错误:

ValueError: lstm层的输入0与该层不兼容:预期ndim=3,而发现ndim=2。接收到的完整形状为:[None,18]

我已经在这个网站和谷歌上搜索了几个小时,但是我没有找到合适的答案,或者我无法实现类似问题的解决方案。

感谢您提供任何提示。


以下是如何仅使用numpy从2D数据创建3D序列的方法:https://dev59.com/7loU5IYBdhLWcg3w5pua#62570576 - Marco Cerliani
1个回答

17

一个 LSTM 网络需要以下格式的三维输入:

(n_samples, time_steps, features)

这会有两个主要问题。

  1. 您的输入是2D
  2. 您使用了堆叠(多个)LSTM层

1. 您的输入是2D

您需要将输入转换为3D。

x = x.reshape(len(x), 1, x.shape[1])
# or
x = np.expand_dims(x, 1)

然后,在第一层中指定正确的输入形状:

LSTM(64, input_shape=(x.shape[1:]))

2. 您有堆叠的LSTM层

默认情况下,LSTM层将不会返回序列,也就是说,它们将返回2D输出。这意味着第二个LSTM层将没有需要的3D输入。为了解决这个问题,您需要设置return_sequences=True

tf.keras.layers.LSTM(8, return_sequences=True),
tf.keras.layers.LSTM(8)

以下是如何重现和解决2D输入问题的方法:

import tensorflow as tf
import numpy as np

x = np.random.rand(100, 10)
# x = np.expand_dims(x, 1) # uncomment to solve the problem
y = np.random.randint(0, 2, 100)

model = tf.keras.Sequential([
    tf.keras.layers.LSTM(8),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

model.compile(optimizer='adam',
              loss='binary_crossentropy',
              metrics=['accuracy'])

history = model.fit(x, y, validation_split=0.1)

以下是如何重现和解决堆叠LSTM层问题的步骤:

import tensorflow as tf
import numpy as np

x = np.random.rand(100, 1, 10)
y = np.random.randint(0, 2, 100)

model = tf.keras.Sequential([
    tf.keras.layers.LSTM(8), # use return_sequences=True to solve the problem
    tf.keras.layers.LSTM(8),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

model.compile(optimizer='adam',
              loss='binary_crossentropy',
              metrics=['accuracy'])

history = model.fit(x, y, validation_split=0.1)

1
现在出现了这个错误:AttributeError: 'DataFrame'对象没有'reshape'属性。 - Sly Shark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接