简体   繁体   中英

keras fit_generator doesn't work as expected

I am currently trying to get the fit_generator to work with my generator but this somehow does not work that well..

Here is an example:

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()

Is this generator made correctly?..

because i am getting error message:

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)

Which I don't understand because it gets one same with 33 inputs? so why cant it read it?

edit:

Here with list:

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()

which gives me error message:

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'

Assuming this is a case of using fit_generator() on a model with multiple inputs which may have different shapes, the following custom generator example for two inputs per sample might be of help:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM