python 中 kera LSTM 网络的模型拟合和维度大小错误
Model fit and dimension size error for kera LSTM network in python
您好,我一直在使用 Keras 在 python 中开发 LSTM 网络。我为我的训练和测试集创建了一个一维数组。当我尝试拟合模型时出现以下错误:
ValueError:检查输入时出错:预期 lstm_31_input 有 3 个维度,但得到形状为 (599, 1)
的数组
我试过调整维度和添加(展平)层的大小。 None 的这项工作。我的代码如下:
#Setup
import pandas as pd
import numpy as np
from numpy import array, zeros, newaxis
from numpy import argmax
from keras.layers.core import Dense, Activation, Dropout
from keras.preprocessing import sequence
from keras.models import Sequential
from keras.layers import Dense, Embedding, Flatten
from keras.layers import LSTM
#Used to ignore warning about some of the tensor command being depracated
#Code from:
#
#import warnings
#with warnings.catch_warnings():
# warnings.simplefilter("ignore")
"""
#Allow use of modules from the Common_Functions Folder
import sys
sys.path.append('../_Common_Functions')
import Hello_World as helloWorld
"""
#Creates dataset of random numbers
#import numpy as np
from random import random
def generateDatset(n):
val = np.array([])
typ = np.array([])
for i in range (1, n):
val = np.append(val, round(random()*10, 2))
if val[i-1] < 3 or val[i-1] > 7:
typ = np.append(typ, 'm')
else:
typ = np.append(typ, 'f')
return val, typ
# Encode the output labels
def lable_encoding(gender_series):
labels = np.empty((0, 2))
for i in gender_series:
if i == 'm':
labels = np.append(labels, [[1,0]], axis=0)
else:
labels = np.append(labels, [[0,1]], axis=0)
return labels
#Gets dataset in proper format for this program
val, typ = generateDatset(1000)
df = pd.DataFrame( {"first_name": val[:], "gender": typ[:]} )
# Split dataset in 60% train, 20% test and 20% validation
train, validate, test = np.split(df.sample(frac=1), [int(.6*len(df)), int(.8*len(df))])
# Convert both the input names as well as the output lables into the discussed machine readable vector format
train_x = np.asarray(train.first_name)
#train_x = np.reshape(train_x, train_x.shape + (1,))
#train_x = np.reshape(train_x, (train_x.shape[0], 1, train_x.shape[1]))
train_y = lable_encoding(train.gender)
#train_y = np.reshape(train_y, train_y.shape + (1,))
#train_y = np.reshape(train_y, (train_y.shape[0], 1, train_y.shape[1]))
validate_x = np.asarray(validate.first_name)
#validate_x = np.reshape(validate_x, validate_x.shape + (1,))
validate_y = lable_encoding(validate.gender)
#validate_y = np.reshape(validate_y, validate_y.shape + (1,))
test_x = np.asarray(test.first_name)
#test_x = np.reshape(test_x, test_x.shape + (1,))
test_y = lable_encoding(test.gender)
#test_x = np.reshape(test_x, test_x.shape + (1,))
"""
The number of hidden nodes can be determined by the following equation:
Nh = (Ns/ (alpha * Ni + No ) )
Where Ni --> number of input neurons
No --> number of output neurons
Ns --> number of samples
alph --> scaling factor
Alternatively the following equation can be used:
Nh = (2/3)*(Ni + No)
As a not this equation is simpler but may not provide the best performance
"""
#Set a value for the scaling factor.
#This typically ranges between 2 and 10
alpha = 8
hidden_nodes = int(np.size(train_x) / (alpha * ((len(df.columns)-1)+ 4)))
input_length = train_x.shape # Length of the character vector
output_labels = 2 # Number of output labels
from keras import optimizers
# Build the model
print('Building model...')
model = Sequential()
#print(train_x.shape)
#
df = np.expand_dims(df, axis=2)
model.add(LSTM(hidden_nodes, return_sequences=True, input_shape=(599, 1)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(units=output_labels))
model.add(Activation('softmax'))
sgd = optimizers.SGD(lr=0.5, clipnorm=10.)
model.compile(loss='categorical_crossentropy', optimizer= sgd, metrics=['acc'])
#
batch_size=1000
#x = train_x[..., newaxis, newaxis]
#x.shape
#y = train_y[..., newaxis, newaxis]
#y.shape
model.fit(train_x, train_y, batch_size=batch_size, epochs=10)
#http://45.76.113.195/?questions/46616674/expected-ndim-3-found-ndim-2-how-to-feed-sparse-matrix-to-lstm-layer-in-keras
input_shape=(599, 1)
指定一个样本的形状。
在这里你的训练批量大小是 599,一个样本的形状是 1。由于第一层是 LSTM 层,它需要 3 维输入(batch_size,number_of_time_stamps_of_a_sample,diamentionality_of_one_time_stamp).但是我们没有在input_shape中提到批量大小。所以LSTM层的输入形状应该是
input_shape=(number_of_time_stamps_of_a_sample,diamentionality_of_one_time_stamp)
所以你应该
1)将input_shape=(599, 1)
替换为input_shape=(1, 1)
2)在训练之前添加下面这行train_x=train_x.reshape(599,1,1)
更清楚的请参考我上传的video ;-)
您好,我一直在使用 Keras 在 python 中开发 LSTM 网络。我为我的训练和测试集创建了一个一维数组。当我尝试拟合模型时出现以下错误:
ValueError:检查输入时出错:预期 lstm_31_input 有 3 个维度,但得到形状为 (599, 1)
的数组我试过调整维度和添加(展平)层的大小。 None 的这项工作。我的代码如下:
#Setup
import pandas as pd
import numpy as np
from numpy import array, zeros, newaxis
from numpy import argmax
from keras.layers.core import Dense, Activation, Dropout
from keras.preprocessing import sequence
from keras.models import Sequential
from keras.layers import Dense, Embedding, Flatten
from keras.layers import LSTM
#Used to ignore warning about some of the tensor command being depracated
#Code from:
#
#import warnings
#with warnings.catch_warnings():
# warnings.simplefilter("ignore")
"""
#Allow use of modules from the Common_Functions Folder
import sys
sys.path.append('../_Common_Functions')
import Hello_World as helloWorld
"""
#Creates dataset of random numbers
#import numpy as np
from random import random
def generateDatset(n):
val = np.array([])
typ = np.array([])
for i in range (1, n):
val = np.append(val, round(random()*10, 2))
if val[i-1] < 3 or val[i-1] > 7:
typ = np.append(typ, 'm')
else:
typ = np.append(typ, 'f')
return val, typ
# Encode the output labels
def lable_encoding(gender_series):
labels = np.empty((0, 2))
for i in gender_series:
if i == 'm':
labels = np.append(labels, [[1,0]], axis=0)
else:
labels = np.append(labels, [[0,1]], axis=0)
return labels
#Gets dataset in proper format for this program
val, typ = generateDatset(1000)
df = pd.DataFrame( {"first_name": val[:], "gender": typ[:]} )
# Split dataset in 60% train, 20% test and 20% validation
train, validate, test = np.split(df.sample(frac=1), [int(.6*len(df)), int(.8*len(df))])
# Convert both the input names as well as the output lables into the discussed machine readable vector format
train_x = np.asarray(train.first_name)
#train_x = np.reshape(train_x, train_x.shape + (1,))
#train_x = np.reshape(train_x, (train_x.shape[0], 1, train_x.shape[1]))
train_y = lable_encoding(train.gender)
#train_y = np.reshape(train_y, train_y.shape + (1,))
#train_y = np.reshape(train_y, (train_y.shape[0], 1, train_y.shape[1]))
validate_x = np.asarray(validate.first_name)
#validate_x = np.reshape(validate_x, validate_x.shape + (1,))
validate_y = lable_encoding(validate.gender)
#validate_y = np.reshape(validate_y, validate_y.shape + (1,))
test_x = np.asarray(test.first_name)
#test_x = np.reshape(test_x, test_x.shape + (1,))
test_y = lable_encoding(test.gender)
#test_x = np.reshape(test_x, test_x.shape + (1,))
"""
The number of hidden nodes can be determined by the following equation:
Nh = (Ns/ (alpha * Ni + No ) )
Where Ni --> number of input neurons
No --> number of output neurons
Ns --> number of samples
alph --> scaling factor
Alternatively the following equation can be used:
Nh = (2/3)*(Ni + No)
As a not this equation is simpler but may not provide the best performance
"""
#Set a value for the scaling factor.
#This typically ranges between 2 and 10
alpha = 8
hidden_nodes = int(np.size(train_x) / (alpha * ((len(df.columns)-1)+ 4)))
input_length = train_x.shape # Length of the character vector
output_labels = 2 # Number of output labels
from keras import optimizers
# Build the model
print('Building model...')
model = Sequential()
#print(train_x.shape)
#
df = np.expand_dims(df, axis=2)
model.add(LSTM(hidden_nodes, return_sequences=True, input_shape=(599, 1)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(units=output_labels))
model.add(Activation('softmax'))
sgd = optimizers.SGD(lr=0.5, clipnorm=10.)
model.compile(loss='categorical_crossentropy', optimizer= sgd, metrics=['acc'])
#
batch_size=1000
#x = train_x[..., newaxis, newaxis]
#x.shape
#y = train_y[..., newaxis, newaxis]
#y.shape
model.fit(train_x, train_y, batch_size=batch_size, epochs=10)
#http://45.76.113.195/?questions/46616674/expected-ndim-3-found-ndim-2-how-to-feed-sparse-matrix-to-lstm-layer-in-keras
input_shape=(599, 1)
指定一个样本的形状。
在这里你的训练批量大小是 599,一个样本的形状是 1。由于第一层是 LSTM 层,它需要 3 维输入(batch_size,number_of_time_stamps_of_a_sample,diamentionality_of_one_time_stamp).但是我们没有在input_shape中提到批量大小。所以LSTM层的输入形状应该是
input_shape=(number_of_time_stamps_of_a_sample,diamentionality_of_one_time_stamp)
所以你应该
1)将input_shape=(599, 1)
替换为input_shape=(1, 1)
2)在训练之前添加下面这行train_x=train_x.reshape(599,1,1)
更清楚的请参考我上传的video ;-)