python - ValueError : 层 lstm 的输入 0 与层不兼容:预期 ndim=3,发现 ndim=2。收到的完整形状:[无,18]
问题描述
我是 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。收到的完整形状:[无,18]
我在这个网站和谷歌上搜索了几个小时的解决方案,但我无法找到正确的答案,或者我无法为类似问题实施解决方案。
谢谢你的任何提示。
解决方案
LSTM 网络需要这种格式的三维输入:
(n_samples, time_steps, features)
这可能是一个问题,主要有两种方式。
- 您的输入是 2D
- 您已经堆叠(多个)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)
推荐阅读
- amazon-web-services - Amazon Deepracer:传感器和参数
- javascript - Vue 尝试设置 boostrap 主题似乎不起作用
- r - 如何在 R 中创建移动平均模型?
- java - 来自同一 TDB 数据集的不同命名模型上的 ConcurrentModificationException
- python - 有没有办法加快 pyspark 中列的最大值?
- sql - sql查询结果重复
- windows - 如何根据其属性删除cmd中的图像?
- python - 如何处理对错误类别给出较高置信度的结果很少的文本分类模型?
- swift - 根据特定类别将来自用户输入的数据存储到单独的表格场景中
- flutter - 如何舍入 DropdownButton 列表的边缘?