ValueError : 层 lstm 的输入 0 与层不兼容:预期 ndim=3,发现 ndim=2.收到的完整形状:[无,18] [英] ValueError : Input 0 of layer lstm is incompatible with the layer: expected ndim=3, found ndim=2. Full shape received: [None, 18]

查看:42
本文介绍了ValueError : 层 lstm 的输入 0 与层不兼容:预期 ndim=3,发现 ndim=2.收到的完整形状:[无,18]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Keras 的新手,我正在尝试构建一个供个人使用/未来学习的模型.我刚开始使用 python,我想出了这段代码(在视频和教程的帮助下).我有 16324 个实例的数据,每个实例包含 18 个特征和 1 个因变量.

I'm new with Keras and I'm trying to build a model for personal use/future learning. I've just started with python and I came up with this code (with help of videos and tutorials). I have a data of 16324 instances, each instance consists of 18 features and 1 dependent variable.

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]

ValueError: Input 0 of layer lstm is incompatible with the layer: expected ndim=3, found ndim=2. Full shape received: [None, 18]

我在这个网站和谷歌上搜索了几个小时的解决方案,但我无法找到正确的答案,或者我无法为类似问题实施解决方案.

I was searching for solution on this site and on google for few hours now and I was not able to find proper answer for this or I was not able to implement the solution for similar problem.

感谢您的建议.

推荐答案

LSTM 网络需要三维输入这种格式:

An LSTM network expects three dimensional input of this format:

(n_samples, time_steps, features)

造成问题的主要方式有两种.

  1. 您的输入是二维的
  2. 您堆叠了(多个)LSTM 层

1.您的输入是二维的

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

You need to turn your input to 3D.

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

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

Then, specify the right input shape in the first layer:

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

2.您已经堆叠了 LSTM 层

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

By default, LSTM layers will not return sequences, i.e., they will return 2D output. This means that the second LSTM layer will not have the 3D input it needs. To address this, you need to set the return_sequences=True:

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

以下是重现和解决二维输入问题的方法:

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)

这篇关于ValueError : 层 lstm 的输入 0 与层不兼容:预期 ndim=3,发现 ndim=2.收到的完整形状:[无,18]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆