Keras:LSTM 神经网络中的错误输入形状
Keras: Wrong Input Shape in LSTM Neural Network
我正在尝试训练 LSTM 递归神经网络,用于序列分类。
我的数据格式如下:
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
.
.
.
所以基本上我想提供一个序列作为输入并得到一个整数作为输出。
每个输入序列有 length = 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
谁能解释一下我的输入形状是什么?我做错了什么?
谢谢
尝试将您的训练数据重塑为:
x_train=x_train.reshape(x_train.shape[0], 1, x_train.shape[1])
input_shape=(None, x_train.shape[1], 1)
,其中None
是批量大小,x_train.shape[1]
是每个特征序列的长度,1
是每个特征长度。 (不确定 Sequential
模型是否需要批量)。
然后将您的数据重塑为 x_train = x_train.reshape(-1, x_train.shape[1], 1)
。
给定您的输入和输出格式,您可以使用官方 Keras examples 之一采用的部分方法。更具体地说,由于您不是在创建二元分类器,而是在预测一个整数,因此您可以使用 one-hot 编码来使用 to_categorical()
.
编码 y_train
# 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)
上面代码中的 num_x_tokens
将是输入样本之一中元素的最大大小(例如,如果您有两个样本 [1, 7, 2]
和 [3, 5, 4]
,则 num_x_tokens
是 7
)。如果您使用 numpy
,您可以使用 np.amax(x_train)
找到它。同样,num_y_tokens
是您在 y_train
.
中的类别数
训练后,您可以使用下面的代码 运行 进行预测。在此配置中使用 np.argmax
有效地反转 to_categorical
。
model_out = model.predict(x_test)
model_out = np.argmax(model_out, axis=1)
您可以使用 from keras.utils import to_categorical
导入 to_categorical
,使用 from keras.layers import Embedding
导入 Embedding
,使用 import numpy as np
.
导入 numpy
另外,您不必 print(model.summary())
。 model.summary()
足以打印出摘要。
编辑
如果输入的形式是 [[0.12, 0.31, ...], [0.22, 0.95, ...], ...]
(例如,用 x_train = np.random.rand(num_samples, num_vals)
生成),那么您可以使用 x_train = np.reshape(x_train, (num_samples, num_vals, 1))
将数组的形状更改为输入到 LSTM 层。在这种情况下训练模型的代码为:
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)
num_vals
是x_train
中每个样本数组的长度。 np.reshape(x_train, (num_samples, num_vals, 1))
将每个样本从 [0.12, 0.31, ...]
形式更改为 [[0.12], [0.31], ...]
形式,这是 LSTM 然后采用的形状 (input_shape=(num_vals, 1)
)。在这种情况下,额外的 1
看起来很奇怪,但是有必要向 LSTM 的输入添加一个额外的维度,因为它期望每个样本至少有两个维度,通常称为 (timesteps, data_dim)
,或者在这种情况 (num_vals, 1)
.
要了解 LSTM 在 Keras 中的其他用途,您可以参考:
Keras Sequential model guide(有几个 LSTM 示例)
Keras examples(查找名称中包含 lstm
的 *.py
文件)
我正在尝试训练 LSTM 递归神经网络,用于序列分类。
我的数据格式如下:
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
.
.
.
所以基本上我想提供一个序列作为输入并得到一个整数作为输出。
每个输入序列有 length = 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
谁能解释一下我的输入形状是什么?我做错了什么?
谢谢
尝试将您的训练数据重塑为:
x_train=x_train.reshape(x_train.shape[0], 1, x_train.shape[1])
input_shape=(None, x_train.shape[1], 1)
,其中None
是批量大小,x_train.shape[1]
是每个特征序列的长度,1
是每个特征长度。 (不确定 Sequential
模型是否需要批量)。
然后将您的数据重塑为 x_train = x_train.reshape(-1, x_train.shape[1], 1)
。
给定您的输入和输出格式,您可以使用官方 Keras examples 之一采用的部分方法。更具体地说,由于您不是在创建二元分类器,而是在预测一个整数,因此您可以使用 one-hot 编码来使用 to_categorical()
.
y_train
# 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)
上面代码中的 num_x_tokens
将是输入样本之一中元素的最大大小(例如,如果您有两个样本 [1, 7, 2]
和 [3, 5, 4]
,则 num_x_tokens
是 7
)。如果您使用 numpy
,您可以使用 np.amax(x_train)
找到它。同样,num_y_tokens
是您在 y_train
.
训练后,您可以使用下面的代码 运行 进行预测。在此配置中使用 np.argmax
有效地反转 to_categorical
。
model_out = model.predict(x_test)
model_out = np.argmax(model_out, axis=1)
您可以使用 from keras.utils import to_categorical
导入 to_categorical
,使用 from keras.layers import Embedding
导入 Embedding
,使用 import numpy as np
.
另外,您不必 print(model.summary())
。 model.summary()
足以打印出摘要。
编辑
如果输入的形式是 [[0.12, 0.31, ...], [0.22, 0.95, ...], ...]
(例如,用 x_train = np.random.rand(num_samples, num_vals)
生成),那么您可以使用 x_train = np.reshape(x_train, (num_samples, num_vals, 1))
将数组的形状更改为输入到 LSTM 层。在这种情况下训练模型的代码为:
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)
num_vals
是x_train
中每个样本数组的长度。 np.reshape(x_train, (num_samples, num_vals, 1))
将每个样本从 [0.12, 0.31, ...]
形式更改为 [[0.12], [0.31], ...]
形式,这是 LSTM 然后采用的形状 (input_shape=(num_vals, 1)
)。在这种情况下,额外的 1
看起来很奇怪,但是有必要向 LSTM 的输入添加一个额外的维度,因为它期望每个样本至少有两个维度,通常称为 (timesteps, data_dim)
,或者在这种情况 (num_vals, 1)
.
要了解 LSTM 在 Keras 中的其他用途,您可以参考:
Keras Sequential model guide(有几个 LSTM 示例)
Keras examples(查找名称中包含 lstm
的 *.py
文件)