web-dev-qa-db-fra.com

Utilisez un générateur pour Keras model.fit_generator

À l'origine, j'avais essayé d'utiliser la syntaxe generator lors de l'écriture d'un générateur personnalisé pour la formation d'un modèle Keras. Alors j'ai yielded de __next__. Cependant, lorsque j'essayerais de former mon mode avec model.fit_generator, j'obtiendrais une erreur que mon générateur n'était pas un itérateur. Le correctif consistait à changer yield en return, ce qui nécessitait également de modifier la logique de __next__ pour suivre l'état. C'est assez lourd comparé à laisser yield faire le travail pour moi.

Existe-t-il un moyen de faire fonctionner cela avec yield? J'aurai besoin d'écrire plusieurs autres itérateurs qui devront avoir une logique très maladroite si je dois utiliser une instruction return.

5
doogFromMT

Je ne peux pas vous aider à déboguer votre code car vous ne l'avez pas posté, mais j'ai abrégé un générateur de données personnalisé que j'ai écrit pour un projet de segmentation sémantique que vous pouvez utiliser comme modèle:

def generate_data(directory, batch_size):
    """Replaces Keras' native ImageDataGenerator."""
    i = 0
    file_list = os.listdir(directory)
    while True:
        image_batch = []
        for b in range(batch_size):
            if i == len(file_list):
                i = 0
                random.shuffle(file_list)
            sample = file_list[i]
            i += 1
            image = cv2.resize(cv2.imread(sample[0]), INPUT_SHAPE)
            image_batch.append((image.astype(float) - 128) / 128)

        yield np.array(image_batch)

Usage:

model.fit_generator(
    generate_data('~/my_data', batch_size),
    steps_per_Epoch=len(os.listdir('~/my_data')) // batch_size)
13
Jessica Alan

J'ai récemment joué avec les générateurs pour Keras et j'ai finalement réussi à préparer un exemple. Il utilise des données aléatoires, alors essayer d’enseigner NN dessus n’a aucun sens, mais c’est une bonne illustration de l’utilisation d’un générateur Python pour Keras.

Générer des données

import numpy as np
import pandas as pd
data = np.random.Rand(200,2)
expected = np.random.randint(2, size=200).reshape(-1,1)

dataFrame = pd.DataFrame(data, columns = ['a','b'])
expectedFrame = pd.DataFrame(expected, columns = ['expected'])

dataFrameTrain, dataFrameTest = dataFrame[:100],dataFrame[-100:]
expectedFrameTrain, expectedFrameTest = expectedFrame[:100],expectedFrame[-100:]

Générateur

def generator(X_data, y_data, batch_size):

  samples_per_Epoch = X_data.shape[0]
  number_of_batches = samples_per_Epoch/batch_size
  counter=0

  while 1:

    X_batch = np.array(X_data[batch_size*counter:batch_size*(counter+1)]).astype('float32')
    y_batch = np.array(y_data[batch_size*counter:batch_size*(counter+1)]).astype('float32')
    counter += 1
    yield X_batch,y_batch

    #restart counter to yeild data in the next Epoch as well
    if counter >= number_of_batches:
        counter = 0

Modèle Keras

from keras.datasets import mnist
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten, Reshape
from keras.layers.convolutional import Convolution1D, Convolution2D, MaxPooling2D
from keras.utils import np_utils


 model = Sequential()
 model.add(Dense(12, activation='relu', input_dim=dataFrame.shape[1]))
 model.add(Dense(1, activation='sigmoid'))


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

 #Train the model using generator vs using the full batch
 batch_size = 8

 model.fit_generator(generator(dataFrameTrain,expectedFrameTrain,batch_size), epochs=3,steps_per_Epoch = dataFrame.shape[0]/batch_size, validation_data=generator(dataFrameTest,expectedFrameTest,batch_size*2),validation_steps=dataFrame.shape[0]/batch_size*2)

 #without generator
 #model.fit(x = np.array(dataFrame), y = np.array(expected), batch_size = batch_size, epochs = 3)

Sortie

Epoch 1/3
25/25 [==============================] - 3s - loss: 0.7297 - acc: 0.4750 - 
val_loss: 0.7183 - val_acc: 0.5000
Epoch 2/3
25/25 [==============================] - 0s - loss: 0.7213 - acc: 0.3750 - 
val_loss: 0.7117 - val_acc: 0.5000
Epoch 3/3
25/25 [==============================] - 0s - loss: 0.7132 - acc: 0.3750 - 
val_loss: 0.7065 - val_acc: 0.5000
4
Vaasha

C'est la façon dont je l'ai implémenté pour lire des fichiers de toute taille . Et cela fonctionne comme un charme.

import pandas as pd

hdr=[]
for i in range(num_labels+num_features):
    hdr.append("Col-"+str(i)) # data file do not have header so I need to
                              # provide one for pd.read_csv by chunks to work

def tgen(filename):
    csvfile = open(filename)
    reader = pd.read_csv(csvfile, chunksize=batch_size,names=hdr,header=None)
    while True:
    for chunk in reader:
        W=chunk.values        # labels and features
        Y =W[:,:num_labels]   # labels 
        X =W[:,num_labels:]   # features
        X= X / 255            # any required transformation
        yield X, Y
    csvfile = open(filename)
    reader = pd.read_csv(csvfile, chunksize=batchz,names=hdr,header=None)

Le dos dans la main j'ai

nval=number_of_validation_samples//batchz
ntrain=number_of_training_samples//batchz
ftgen=tgen("training.csv")
fvgen=tgen("validation.csv")

history = model.fit_generator(ftgen,
                steps_per_Epoch=ntrain,
                validation_data=fvgen,
                validation_steps=nval,
                epochs=number_of_epochs,
                callbacks=[checkpointer, stopper],
                verbose=2)
0
agcala