How do I combine two keras generator functions

keras fit generator
imagedatagenerator
keras generator multiple inputs
keras multiprocessing generator
keras audio data generator
directoryiterator keras
text data generator keras
keras use_multiprocessing

I am trying to implement a Siamese network in Keras and I want to apply image transformations to the 2 input images using Keras Image Data Generators. As per the example in the docs- https://keras.io/preprocessing/image/, I've tried to implement it like this-

datagen_args = dict(rotation_range=10,
                    width_shift_range=0.1,
                    height_shift_range=0.1,
                    horizontal_flip=True)

in_gen1 = ImageDataGenerator(**datagen_args)
in_gen2 = ImageDataGenerator(**datagen_args)

train_generator = zip(in_gen1, in_gen2)

model.fit(train_generator.flow([pair_df[:, 0,::],pair_df[:, 1,::]],
                          y_train,batch_size=16), epochs, verbose = 1)

But this code throws this error:

TypeError: zip argument #1 must support iteration

I've tried using itertools.izip as suggested in Keras - Generator for large dataset of Images and Masks but this throws the same error.

How do I resolve this?

EDIT: In case anyone is interested, this worked finally-

datagen_args = dict(
    featurewise_center=False,
    rotation_range=10,
    width_shift_range=0.1,
    height_shift_range=0.1,
    horizontal_flip=True)

in_gen1 = ImageDataGenerator(**datagen_args)
in_gen2 = ImageDataGenerator(**datagen_args)

in_gen1 = in_gen1.flow(pair_df[:, 0,::], y_train, batch_size = 16, shuffle = False)
in_gen2 = in_gen2.flow(pair_df[:, 1,::], y_train, batch_size = 16, shuffle = False)

for e in range(epochs):
    batches = 0
    for x1, x2 in itertools.izip(in_gen1,in_gen2):
    # x1, x2 are tuples returned by the generator, check whether targets match
        assert sum(x1[1] != x2[1]) == 0  
        model.fit([x1[0], x2[0]], x1[1], verbose = 1)
        batches +=1
        if(batches >= len(pair_df)/16):
            break

Using zip() to combine generators leads to generation of an infinite iterator. Use this instead:

def combine_generator(gen1, gen2):
    while True:
        yield(next(gen1), next(gen2))

Modified code would look something like this:

datagen_args = dict(rotation_range=10,
                    width_shift_range=0.1,
                    height_shift_range=0.1,
                    horizontal_flip=True)

in_gen1 = ImageDataGenerator(**datagen_args)
in_gen2 = ImageDataGenerator(**datagen_args)

def combine_generator(gen1, gen2):
    while True:
        yield(next(gen1), next(gen2))

train_generator = combine_generator(in_gen1, in_gen2)

model.fit(train_generator.flow([pair_df[:, 0,::],pair_df[:, 1,::]],
                          y_train,batch_size=16), epochs, verbose = 1)

See this thread for further reference.

How to merge two DirectoryIterator? · Issue #9969 · keras-team , My question is whether it's possible to merge\combine train_generator with validation_generator to a single generator that contains images from  The Keras fit_generator function Figure 2: The Keras .fit_generator function allows for data augmentation and data generators. For small, simplistic datasets it’s perfectly acceptable to use Keras’ .fit function. These datasets are often not very challenging and do not require any data augmentation. However, real-world datasets are rarely


You need to first convert them to something iterable using the flow method.

Try the following:

datagen_args = dict(rotation_range=10,
                    width_shift_range=0.1,
                    height_shift_range=0.1,
                    horizontal_flip=True)

in_gen1 = ImageDataGenerator(**datagen_args)
in_gen2 = ImageDataGenerator(**datagen_args)

gen1_flow = in_gen1.flow(X_train[:,0, ::],y_train, batch_size=16)
gen2_flow = in_gen2.flow(X_train[:,1, ::],y_train, batch_size=16)

train_generator = zip(gen1_flow, gen2_flow)

model.fit_generator(train_generator,
                    steps_per_epoch=len(X_train)/16,
                    epochs=epochs)

How to merge two layers which have two different python generators , I was wondering if you can merge two layers, each of which has a different python generator as input. I have checked the example on Keras  Use instead layers from `keras.layers.merge`, e.g. `add`, `concatenate`, etc. ----- TypeError Traceback (most recent call last) <ipython-input-18-0b2a968dbcfd> in <module>() 115 # CONACTENATE the ends of RGB & NIR 116 multi_modal = Sequential() --> 117 multi_modal.add(Merge([rgb_model, nir_model], mode='concat')) 118 #concat = Merge([pool_rgb1, pool_nir1],mode='concat') 119 # Deconvolution Layers /home/captain_jack/.local/lib/python2.7/site-packages/keras/legacy/layers.pyc in __init__(self


While the answers provided work well, if you want to place yourself in a thread-safe multiprocessing fitting, you need to implement a Sequence that will merge the 2 generators.

from keras.utils import  Sequence


class MergedGenerators(Sequence):
    def __init__(self, *generators):
        self.generators = generators
        # TODO add a check to verify that all generators have the same length

    def __len__(self):
        return len(self.generators[0])

    def __getitem__(self, index):
        return [generator[index] for generator in self.generators]

datagen_args = dict(
    featurewise_center=False,
    rotation_range=10,
    width_shift_range=0.1,
    height_shift_range=0.1,
    horizontal_flip=True)

in_gen1 = ImageDataGenerator(**datagen_args)
in_gen2 = ImageDataGenerator(**datagen_args)

in_gen1 = in_gen1.flow(pair_df[:, 0,::], y_train, batch_size = 16, shuffle = False)
in_gen2 = in_gen2.flow(pair_df[:, 1,::], y_train, batch_size = 16, shuffle = False)

train_merged_generator = MergedGenerators(in_gen1, in_gen2)

model.fit(train_merged_generator, epochs, verbose=1, use_multiprocessing=True)

I think in this case it doesn't make much of a difference since the data is already in memory. This would have to be tested.

tf.keras.preprocessing.image.ImageDataGenerator, brightness_range, Tuple or list of two floats. The function should take one argument: one image (Numpy tensor with rank 3), and should output a Numpy tensor with the same combine generators into one which yields image and masks Data generator. Now, let's go through the details of how to set the Python class DataGenerator, which will be used for real-time data feeding to your Keras model. First, let's write the initialization function of the class.


Custom Keras Generators, The idea behind using a Keras generator is to get batches of input and corresponding output on the Step 2 : Define a function to get output : For instance I have two different feature sets (A & B) and I want to use CNN for A and LSTM for B and combine their learned representations before feeding it to FC layer. Is it possible and how do I do it with Keras? Should I use two different fit functions? But then how do I use predict? model.fit(train_A, trainY) model.fit(train_B, trainY)


Keras data augmentation with multiple inputs, Using keras functional API to concatenate the angle input and convolutional Create a standard keras ImageDataGenerator, and then use a helper is the function that merges our two generators # We use the exact same  Combining the dataset generator and in-place augmentation. By default, Keras’ ImageDataGenerator class performs in-place/on-the-fly data augmentation, meaning that the class: Accepts a batch of images used for training. Takes this batch and applies a series of random transformations to each image in the batch.


Creating custom data generator for training Deep Learning Models , Chapter-2: Writing a generator function to read your data that can be fed for training an image classifier in Keras. Chapter-3: Writing generator  I have built a model which constists of two branches which are then merged into a single one. For the training of the model I would like to use the ImageGenerator to augement the image data, but don't know how to make work for the mixed