Keras:LSTM神经网络中错误的输入形状 [英] Keras: Wrong Input Shape in LSTM Neural Network

查看:99
本文介绍了Keras:LSTM神经网络中错误的输入形状的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试训练LSTM递归神经网络以进行序列分类.

我的数据具有以下formart:

Input: [1,5,2,3,6,2, ...] -> Output: 1
Input: [2,10,4,6,12,4, ...] -> Output: 1
Input: [4,1,7,1,9,2, ...] -> Output: 2
Input: [1,3,5,9,10,20, ...] -> Output: 3
.
.
.

所以基本上我想提供一个序列作为输入,并获取一个整数作为输出.

每个输入序列的长度= 2000个浮点数,我有大约1485个样本用于训练

输出只是1到10的整数

这是我试图做的:

# Get the training numpy 2D array for the input (1485X 2000). 
# Each element is an input sequence of length 2000
# eg: [ [1,2,3...], [4,5,6...], ... ]
x_train = get_training_x() 

# Get the training numpy 2D array for the outputs (1485 X 1). 
# Each element is an integer output for the corresponding input from x_train
# eg: [ 1, 2, 3, ...]
y_train = get_training_y()

# Create the model
model = Sequential()
model.add(LSTM(100, input_shape=(x_train.shape)))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())
model.fit(x_train, y_train, nb_epoch=3, batch_size=64)

我收到以下错误:

Error when checking input: expected lstm_1_input to have 3 dimensions, but got array with shape (1485, 2000)

我尝试改用它:

model.add(LSTM(100, input_shape=(1485, 1, 2000)))

但是这次又出现了另一个错误:

ValueError: Input 0 is incompatible with layer lstm_1: expected ndim=3, found ndim=4

谁能解释我的输入形状是什么?我在做什么错了?

谢谢

解决方案

鉴于输入和输出的格式,您可以使用官方 Keras顺序模型指南(具有多个LSTM示例)

Keras示例(查找带有lstm的名字)

I am trying to train an LSTM recurrent neural network, for sequence classification.

My data has the following formart:

Input: [1,5,2,3,6,2, ...] -> Output: 1
Input: [2,10,4,6,12,4, ...] -> Output: 1
Input: [4,1,7,1,9,2, ...] -> Output: 2
Input: [1,3,5,9,10,20, ...] -> Output: 3
.
.
.

So basically I want to provide a sequence as an input and get an integer as an output.

Each input sequence has length = 2000 float numbers, and I have around 1485 samples for training

The output is just an integer from 1 to 10

This is what I tried to do:

# Get the training numpy 2D array for the input (1485X 2000). 
# Each element is an input sequence of length 2000
# eg: [ [1,2,3...], [4,5,6...], ... ]
x_train = get_training_x() 

# Get the training numpy 2D array for the outputs (1485 X 1). 
# Each element is an integer output for the corresponding input from x_train
# eg: [ 1, 2, 3, ...]
y_train = get_training_y()

# Create the model
model = Sequential()
model.add(LSTM(100, input_shape=(x_train.shape)))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())
model.fit(x_train, y_train, nb_epoch=3, batch_size=64)

I get the following error:

Error when checking input: expected lstm_1_input to have 3 dimensions, but got array with shape (1485, 2000)

I tried using this instead:

model.add(LSTM(100, input_shape=(1485, 1, 2000)))

But got the another error this time:

ValueError: Input 0 is incompatible with layer lstm_1: expected ndim=3, found ndim=4

Can anyone explain what is my input shape? and what am I doing wrong?

Thanks

解决方案

Given the format of your input and output, you can use parts of the approach taken by one of the official Keras examples. More specifically, since you are not creating a binary classifier, but rather predicting an integer, you can use one-hot encoding to encode y_train using to_categorical().

# Number of elements in each sample
num_vals = x_train.shape[1]

# Convert all samples in y_train to one-hot encoding
y_train = to_categorical(y_train)

# Get number of possible values for model inputs and outputs
num_x_tokens = np.amax(x_train) + 1
num_y_tokens = y_train.shape[1]

model = Sequential()
model.add(Embedding(num_x_tokens, 100))
model.add(LSTM(100))
model.add(Dense(num_y_tokens, activation='sigmoid'))

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

model.fit(x_train, y_train,
              batch_size=64,
              epochs=3)

The num_x_tokens in the code above would be the maximum size of the element in one of your input samples (e.g. if you have two samples [1, 7, 2] and [3, 5, 4] then num_x_tokens is 7). If you use numpy you can find this with np.amax(x_train). Similarly, num_y_tokens is the number of categories you have in y_train.

After training, you can run predictions using the code below. Using np.argmax effectively reverses to_categorical in this configuration.

model_out = model.predict(x_test)
model_out = np.argmax(model_out, axis=1)

You can import to_categorical using from keras.utils import to_categorical, Embedding using from keras.layers import Embedding, and numpy using import numpy as np.

Also, you don't have to do print(model.summary()). model.summary() is enough to print out the summary.

EDIT

If it is the case that the input is of the form [[0.12, 0.31, ...], [0.22, 0.95, ...], ...] (say, generated with x_train = np.random.rand(num_samples, num_vals)) then you can use x_train = np.reshape(x_train, (num_samples, num_vals, 1)) to change the shape of the array to input it into the LSTM layer. The code to train the model in that case would be:

num_samples = x_train.shape[0]
num_vals    = x_train.shape[1] # Number of elements in each sample

# Reshape for what LSTM expects
x_train = np.reshape(x_train, (num_samples, num_vals, 1))
y_train = to_categorical(y_train)

# Get number of possible values for model outputs
num_y_tokens = y_train.shape[1]

model = Sequential()
model.add(LSTM(100, input_shape=(num_vals, 1)))
model.add(Dense(num_y_tokens, activation='sigmoid'))

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

model.fit(x_train, y_train,
              batch_size=64,
              epochs=3)

The num_vals is the length of each sample array in x_train. np.reshape(x_train, (num_samples, num_vals, 1)) changes each sample from [0.12, 0.31, ...] form to [[0.12], [0.31], ...] form, which is the shape that LSTM then takes (input_shape=(num_vals, 1)). The extra 1 seems strange in this case, but it is necessary to add an extra dimension to the input for the LSTM since it expects each sample to have at least two dimensions, typically called (timesteps, data_dim), or in this case (num_vals, 1).

To see how else LSTMs are used in Keras you can refer to:

Keras Sequential model guide (has several LSTM examples)

Keras examples (look for *.py files with lstm in their name)

这篇关于Keras:LSTM神经网络中错误的输入形状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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