2016-07-02 56 views
13

Sto installando una rete convoluzionale completa su alcuni dati di immagine per la segmentazione semantica usando Keras. Tuttavia, sto avendo alcuni problemi di sovralimentazione. Non ho tanti dati e voglio fare l'aumento dei dati. Tuttavia, dal momento che voglio fare una classificazione in pixel, ho bisogno di qualsiasi tipo di incremento, come salti mortali, rotazione e turni, da applicare sia alle immagini delle caratteristiche che alle immagini delle etichette. Idealmente mi piacerebbe utilizzare Keras ImageDataGenerator per le trasformazioni al volo. Tuttavia, per quanto posso dire, non è possibile eseguire trasformazioni equivalenti su entrambi i dati delle funzioni e delle etichette.Data incremento Image Generatore di dati Keras Segmentazione semantica

Qualcuno sa se questo è il caso e in caso contrario, qualcuno ha qualche idea? Altrimenti, userò altri strumenti per creare un set di dati più grande e lo inserirò tutto in una volta.

Grazie!

+1

Ho avuto esattamente lo stesso problema, ho anche pensato di ImageDataGenerator e non ho trovato alcuna soluzione. - – FiReTiTi

+0

Posso chiedere quale strumento hai utilizzato per questo processo per assicurarti che le stesse trasformazioni siano state applicate a entrambe le funzioni e ai dati? – TSW

+3

Puoi farlo con la stessa facilità creando il tuo generatore di lotti dove si aumentano gli input/output allo stesso modo e poi si chiama 'model.train_on_batch'. Assicurati di mescolare i dati tu stesso dato che normalmente questo è curato da' model.fit'. –

risposta

8

Ci sono lavori per estendere ImageDataGenerator per essere più flessibile esattamente per questo tipo di casi (vedi per esempio this issue on Github).

Inoltre, come menzionato da Mikael Rousson nei commenti, è possibile creare facilmente la propria versione di ImageDataGenerator autonomamente, sfruttando al contempo molte delle sue funzioni integrate per renderlo più semplice. Ecco un codice di esempio che ho usato per un problema di riduzione dell'immagine, in cui utilizzo colture random + rumore addizionale per generare coppie di immagini pulite e rumorose al volo. Potresti facilmente modificarlo per aggiungere altri tipi di ingrandimenti. Dopo di che, è possibile utilizzare Model.fit_generator per allenarsi utilizzando questi metodi.

from keras.preprocessing.image import load_img, img_to_array, list_pictures 

def random_crop(image, crop_size): 
    height, width = image.shape[1:] 
    dy, dx = crop_size 
    if width < dx or height < dy: 
     return None 
    x = np.random.randint(0, width - dx + 1) 
    y = np.random.randint(0, height - dy + 1) 
    return image[:, y:(y+dy), x:(x+dx)] 

def image_generator(list_of_files, crop_size, to_grayscale=True, scale=1, shift=0): 
    while True: 
     filename = np.random.choice(list_of_files) 
     try: 
      img = img_to_array(load_img(filename, to_grayscale)) 
     except: 
      return 
     cropped_img = random_crop(img, crop_size) 
     if cropped_img is None: 
      continue 
     yield scale * cropped_img - shift 
def corrupted_training_pair(images, sigma): 
    for img in images: 
     target = img 
     if sigma > 0: 
      source = img + np.random.normal(0, sigma, img.shape)/255.0 
     else: 
      source = img 
     yield (source, target) 
def group_by_batch(dataset, batch_size): 
    while True: 
     try: 
      sources, targets = zip(*[next(dataset) for i in xrange(batch_size)]) 
      batch = (np.stack(sources), np.stack(targets)) 
      yield batch 
     except: 
      return 
def load_dataset(directory, crop_size, sigma, batch_size): 
    files = list_pictures(directory) 
    generator = image_generator(files, crop_size, scale=1/255.0, shift=0.5) 
    generator = corrupted_training_pair(generator, sigma) 
    generator = group_by_batch(generator, batch_size) 
    return generator 

È quindi possibile utilizzare quanto sopra in questo modo:

train_set = load_dataset('images/train', (patch_height, patch_width), noise_sigma, batch_size) 
val_set = load_dataset('images/val', (patch_height, patch_width), noise_sigma, batch_size) 
model.fit_generator(train_set, samples_per_epoch=batch_size * 1000, nb_epoch=nb_epoch, validation_data=val_set, nb_val_samples=1000) 
+0

Cosa fa la funzione di flusso durante l'utilizzo di generatori di dati in Keras? –

+2

La funzione di flusso è per la creazione di un generatore di dati dalla directory di file o array di numpy.Tuttavia, questo non ha nulla con questa domanda, o la mia risposta: ti suggerisco di aprire una nuova domanda con il tuo problema esatto e non come un commento su una risposta a una domanda non correlata –

6

Sì, è possibile. Ecco un esempio dei documenti di Keras. Comprimi insieme due generatori seminato con gli stessi semi e il fit_generator. https://keras.io/preprocessing/image/

# we create two instances with the same arguments 
data_gen_args = dict(featurewise_center=True, 
        featurewise_std_normalization=True, 
        rotation_range=90., 
        width_shift_range=0.1, 
        height_shift_range=0.1, 
        zoom_range=0.2) 
image_datagen = ImageDataGenerator(**data_gen_args) 
mask_datagen = ImageDataGenerator(**data_gen_args) 

# Provide the same seed and keyword arguments to the fit and flow methods seed = 1 
image_datagen.fit(images, augment=True, seed=seed) 
mask_datagen.fit(masks, augment=True, seed=seed) 

image_generator = image_datagen.flow_from_directory(
    'data/images', 
    class_mode=None, 
    seed=seed) 

mask_generator = mask_datagen.flow_from_directory(
    'data/masks', 
    class_mode=None, 
    seed=seed) 

# combine generators into one which yields image and masks 
train_generator = zip(image_generator, mask_generator) 

model.fit_generator(
    train_generator, 
    samples_per_epoch=2000, 
    nb_epoch=50) 
+1

ig e bloccato quando provo a chiuderli insieme, hai un'idea? 'train_generator = zip (image_generator, mask_generator)' limite di memoria o esecuzione infinita – olix20

+1

usa invece itertools.izip(), che ti dà la versione del generatore di zip() – dgorissen