keras fit_generator не работает должным образом
В настоящее время я пытаюсь заставить fit_generator работать с моим генератором, но это как-то не очень хорошо работает...
Вот пример:
import numpy as np
from keras.utils import np_utils
from keras import metrics
import keras
from keras.models import Sequential
from keras.optimizers import SGD
from keras.layers.core import Dense, Activation, Lambda, Reshape,Flatten
from keras.layers import Conv1D,Conv2D,MaxPooling2D, MaxPooling1D, Reshape
from keras.utils import np_utils
from keras.models import Model
from keras.layers import Input, Dense
from keras.layers import Dropout
from keras import backend as K
from keras.callbacks import ReduceLROnPlateau
from keras.callbacks import CSVLogger
from keras.callbacks import EarlyStopping
from keras.models import load_model
def generator(batch_size):
global train_input
train_input = np.random.randint(5,size=(5000,33,45,8,3))
global train_output
train_output = np.random.randint(5,size=(5000,15))
global train_input_concat
train_input_concat = np.empty((0,33,45,8,3))
while True:
for input in train_input:
input = np.expand_dims(input,axis=0)
train_input_concat = np.append(train_input_concat,input,axis=0)
print train_input_concat.shape
print input.shape
raw_input("something")
if (batch_size) == train_input_concat.shape[0]:
output_train_set = train_output[:batch_size,:]
train_output = np.delete(train_output,np.s_[:batch_size],axis=0)
train_output_set = np_utils.to_categorical(output_train_set,145)
train_input_set = train_input_concat
del train_input_concat
train_input_concat = np.empty((0,33,45,8,3))
print train_input_set.shape
print train_output_set.shape
print train_output.shape
raw_input("Something yield")
yield train_input_set,train_output_set
def model3():
stride = 2
dim = 40
total_frames_with_deltas = 45
total_frames = 15
window_height = 8
splits = ((40-8)+1)/1
kernel_number = 150#int(math.ceil(splits))
list_of_input = [Input(shape = (total_frames_with_deltas,window_height,3)) for i in range(splits)]
list_of_conv_output = []
list_of_max_out = []
for i in range(splits):
list_of_conv_output.append(Conv2D(filters = kernel_number , kernel_size = (15,6))(list_of_input[i]))
list_of_max_out.append((MaxPooling2D(pool_size=((2,2)))(list_of_conv_output[i])))
merge = keras.layers.concatenate(list_of_max_out)
print merge.shape
reshape = Reshape((total_frames,-1))(merge)
dense1 = Dense(units = 1000, activation = 'relu', name = "dense_1")(reshape)
dense2 = Dense(units = 1000, activation = 'relu', name = "dense_2")(dense1)
dense3 = Dense(units = 145 , activation = 'softmax', name = "dense_3")(dense2)
#dense4 = Dense(units = 1, activation = 'linear', name = "dense_4")(dense3)
model = Model(inputs = list_of_input , outputs = dense3)
model.compile(loss="categorical_crossentropy", optimizer="SGD" , metrics = [metrics.categorical_accuracy])
reduce_lr=ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=3, verbose=1, mode='auto', epsilon=0.001, cooldown=0)
stop = EarlyStopping(monitor='val_loss', min_delta=0, patience=5, verbose=1, mode='auto')
print model.summary()
raw_input("okay?")
hist_current = model.fit_generator(generator(1),
steps_per_epoch=1,
epochs = 10,
verbose = 2,
validation_data = None)
model3()
Этот генератор сделан правильно?..
потому что я получаю сообщение об ошибке:
Traceback (most recent call last):
File "test_generator.py", line 90, in <module>
model3()
File "test_generator.py", line 89, in model3
validation_data = None)
File "/usr/local/lib/python2.7/dist-packages/keras/legacy/interfaces.py", line 87, in wrapper
return func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1876, in fit_generator
class_weight=class_weight)
File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1614, in train_on_batch
check_batch_axis=True)
File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1295, in _standardize_user_data
exception_prefix='model input')
File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 100, in _standardize_input_data
'Found: array with shape ' + str(data.shape))
ValueError: The model expects 33 input arrays, but only received one array. Found: array with shape (1, 33, 45, 8, 3)
Что я не понимаю, потому что он получает один и тот же с 33 входами? так почему он не может это прочитать?
редактировать:
Здесь со списком:
import numpy as np
from keras.utils import np_utils
from keras import metrics
import keras
from keras.models import Sequential
from keras.optimizers import SGD
from keras.layers.core import Dense, Activation, Lambda, Reshape,Flatten
from keras.layers import Conv1D,Conv2D,MaxPooling2D, MaxPooling1D, Reshape
from keras.utils import np_utils
from keras.models import Model
from keras.layers import Input, Dense
from keras.layers import Dropout
from keras import backend as K
from keras.callbacks import ReduceLROnPlateau
from keras.callbacks import CSVLogger
from keras.callbacks import EarlyStopping
from keras.models import load_model
def generator(batch_size):
global train_input
train_input = np.random.randint(5,size=(5000,33,45,8,3))
global train_output
train_output = np.random.randint(5,size=(5000,15))
global train_input_concat
train_input_concat = np.empty((0,33,45,8,3))
while True:
for input in train_input:
input = np.expand_dims(input,axis=0)
train_input_concat = np.append(train_input_concat,input,axis=0)
print train_input_concat.shape
print input.shape
raw_input("something")
if (batch_size) == train_input_concat.shape[0]:
output_train_set = train_output[:batch_size,:]
train_output = np.delete(train_output,np.s_[:batch_size],axis=0)
train_output_set = np_utils.to_categorical(output_train_set,145)
train_input_set = train_input_concat
del train_input_concat
train_input_concat = np.empty((0,33,45,8,3))
print train_input_set.shape
print train_output_set.shape
print train_output.shape
input_list = np.split(train_input_set,33,axis=1)
print len(input_list)
yield ({'train_input': input_list},{'labels':train_output_set})
def model3():
stride = 2
dim = 40
total_frames_with_deltas = 45
total_frames = 15
window_height = 8
splits = ((40-8)+1)/1
kernel_number = 150#int(math.ceil(splits))
list_of_input = [Input(shape = (total_frames_with_deltas,window_height,3)) for i in range(splits)]
list_of_conv_output = []
list_of_max_out = []
for i in range(splits):
list_of_conv_output.append(Conv2D(filters = kernel_number , kernel_size = (15,6))(list_of_input[i]))
list_of_max_out.append((MaxPooling2D(pool_size=((2,2)))(list_of_conv_output[i])))
merge = keras.layers.concatenate(list_of_max_out)
print merge.shape
reshape = Reshape((total_frames,-1))(merge)
dense1 = Dense(units = 1000, activation = 'relu', name = "dense_1")(reshape)
dense2 = Dense(units = 1000, activation = 'relu', name = "dense_2")(dense1)
dense3 = Dense(units = 145 , activation = 'softmax', name = "dense_3")(dense2)
#dense4 = Dense(units = 1, activation = 'linear', name = "dense_4")(dense3)
model = Model(inputs = list_of_input , outputs = dense3)
model.compile(loss="categorical_crossentropy", optimizer="SGD" , metrics = [metrics.categorical_accuracy])
reduce_lr=ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=3, verbose=1, mode='auto', epsilon=0.001, cooldown=0)
stop = EarlyStopping(monitor='val_loss', min_delta=0, patience=5, verbose=1, mode='auto')
print model.summary()
raw_input("okay?")
hist_current = model.fit_generator(generator(1),
steps_per_epoch=1,
epochs = 10,
verbose = 2,
validation_data = None)
model3()
что дает мне сообщение об ошибке:
Traceback (most recent call last):
File "test_generator.py", line 93, in <module>
model3()
File "test_generator.py", line 92, in model3
validation_data = None)
File "/usr/local/lib/python2.7/site-packages/keras/legacy/interfaces.py", line 88, in wrapper
return func(*args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/keras/engine/training.py", line 1868, in fit_generator
batch_size = list(x.values())[0].shape[0]
AttributeError: 'list' object has no attribute 'shape'
1 ответ
Предполагая, что это случай использования fit_generator() в модели с несколькими входами, которые могут иметь разные формы, может помочь следующий пример пользовательского генератора для двух входов на выборку:
def data_gen(input1_shape, input2_shape, batch_size):
while True:
input1_batch = []
input2_batch = []
labels_batch = []
for i in range(batch_size):
# Assume inp1 and inp2 are two inputs for a sample
val = np.random.randint(0, 100)
inp1 = np.full(input1_shape, val)
inp2 = np.full(input2_shape, val)
# Get label
labels_batch.append(np.random.choice([0, 1]))
# Parallel lists for each input
input1_batch.append(inp1)
input2_batch.append(inp2)
# Yield the accumulated batch
yield [input1_batch, input2_batch], labels_batch