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]

查看:892
本文介绍了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]

我已经在这个网站和google上寻找解决方案已有几个小时了,但我无法为此找到合适的答案,或者我无法针对类似问题实施解决方案.

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网络期望此格式的三维输入:

(n_samples, time_steps, features)

有两种主要方法可以解决此问题.

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

1.您输入的是2D

您需要将输入内容转换为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)

以下是再现和解决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)

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

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