title: NotImplementedError: `fit_generator` is not yet enabled for Model subclasses
body: <p>I am trying to build a vehicle damage detection model following the blogpost<br />
  <a href="https://narender-reddy.medium.com/car-body-damage-detection-u-net-u-net-implementation-a-case-study-759b408e2c1f" rel="nofollow noreferrer">https://narender-reddy.medium.com/car-body-damage-detection-u-net-u-net-implementation-a-case-study-759b408e2c1f</a> with my own dataset (also annotated with the VIA Tool).
  I used the Modified Unet Architecture, which is defined as follows:</p>
  <pre><code>
  # Modified u-net model
  class EncoderBlock(tf.keras.Model):
    def __init__(self, filter_size):
      # initilize instance variables
      super(EncoderBlock, self).__init__()
      self.filter_size = filter_size
      # define layers
      self.layer_1 = layers.Activation('relu')
      self.layer_2 = layers.SeparableConv2D(self.filter_size, 3, padding='same')
      self.layer_3 = layers.BatchNormalization()
  
      self.layer_4 = layers.Activation('relu')
      self.layer_5 = layers.SeparableConv2D(self.filter_size, 3, padding='same')
      self.layer_6 = layers.BatchNormalization()
  
      self.layer_7 = layers.MaxPooling2D(3, strides=2, padding='same')
  
      # project residual
      self.residual_layer = layers.Conv2D(self.filter_size, 1, strides=2, padding='same')
    def call(self, inputs):
      x = self.layer_1(inputs)
      x = self.layer_2(x)
      x = self.layer_3(x)
      x = self.layer_4(x)
      x = self.layer_5(x)
      x = self.layer_6(x)
      x = self.layer_7(x)
      residual = self.residual_layer(inputs)
      x = layers.add([x, residual])
      return x
  
  class DecoderBlock(tf.keras.Model):
    def __init__(self, filter_size):
      # initilize instance variables
      super(DecoderBlock, self).__init__()
      self.filter_size = filter_size
      # define layers
      self.layer_1 = layers.Activation('relu')
      self.layer_2 = layers.Conv2DTranspose(self.filter_size, 3, padding='same')
      self.layer_3 = layers.BatchNormalization()
  
      self.layer_4 = layers.Activation('relu')
      self.layer_5 = layers.Conv2DTranspose(self.filter_size, 3, padding='same')
      self.layer_6 = layers.BatchNormalization()
  
      self.layer_7 = layers.UpSampling2D(2)
  
      # project residual
      self.residual_layer_1 = layers.UpSampling2D(2)
      self.residual_layer_2 = layers.Conv2D(filter_size, 1, padding='same')
    def call(self, inputs):
      x = self.layer_1(inputs)
      x = self.layer_2(x)
      x = self.layer_3(x)
      x = self.layer_4(x)
      x = self.layer_5(x)
      x = self.layer_6(x)
      x = self.layer_7(x)
      residual = self.residual_layer_1(inputs)
      residual = self.residual_layer_2(residual)
  
      x = layers.add([x, residual])
      return x
  
  class UnetModel(tf.keras.Model):
    def __init__(self, output_channels, dynamic=True):
      # initilize instance variables
      super(UnetModel, self).__init__()
      self.output_channels = output_channels
      
      self.entry_block_1 = layers.Conv2D(32, 3, input_shape=(128, 128, 3),strides=2, padding='same')
      self.entry_block_2 = layers.BatchNormalization()
      self.entry_block_3 = layers.Activation('relu')
  
      self.encoder_block_1 = EncoderBlock(64)
      self.encoder_block_2 = EncoderBlock(128)
      self.encoder_block_3 = EncoderBlock(256)
  
      self.decoder_block_1 = DecoderBlock(256)
      self.decoder_block_2 = DecoderBlock(128)
      self.decoder_block_3 = DecoderBlock(64)
      self.decoder_block_4 = DecoderBlock(32)
  
      self.output_layer = layers.Conv2D(
          output_channels, 3, activation='sigmoid', padding='same')
      
    def call(self, inputs):
      
      
      x = self.entry_block_1(inputs)
      x = self.entry_block_2(x)
      x = self.entry_block_3(x)
      x = self.encoder_block_1(x)
      x = self.encoder_block_2(x)
      x = self.encoder_block_3(x)
      x = self.decoder_block_1(x)
      x = self.decoder_block_2(x)
      x = self.decoder_block_3(x)
      x = self.decoder_block_4(x)
      x = self.output_layer(x)
      return x
  </code></pre>
  <p>Because my dataset is limited, I used a the ImageDataGenerator() and tried to run the model with fit_generator:</p>
  <pre><code>model = UnetModel(OUTPUT_CHANNELS)
  optimizer = tf.keras.optimizers.Adam(lr=1e-3)
  model.compile(optimizer=optimizer, loss=sm.losses.dice_loss, metrics=[dice_coef])
  model_history = model.fit_generator(train_generator, epochs=EPOCHS,
                            steps_per_epoch=STEPS_PER_EPOCH,
                            validation_steps=VALIDATION_STEPS,
                            validation_data=val_generator,
                            callbacks=[DisplayCallback()])
  </code></pre>
  <p>Somehow I keep getting the Error:</p>
  <pre><code>NotImplementedError: `fit_generator` is not yet enabled for Model subclasses
  </code></pre>
  <p>I use tensorflow-gpu version 1.7.1 and keras version 2.1.0 .</p>
  <p>EDIT:</p>
  <p>The code for the data generators is as follows:</p>
  <pre><code>from keras.preprocessing import image
  
  # Creating the training Image and Mask generator
  image_datagen = image.ImageDataGenerator(shear_range=0.5, rotation_range=50, zoom_range=0.2, width_shift_range=0.2, height_shift_range=0.2, fill_mode='reflect')
  mask_datagen = image.ImageDataGenerator(shear_range=0.5, rotation_range=50, zoom_range=0.2, width_shift_range=0.2, height_shift_range=0.2, fill_mode='reflect')
  
  # Keep the same seed for image and mask generators so they fit together
  
  image_datagen.fit(X_train[:int(X_train.shape[0]*0.9)], augment=True, seed=seed)
  mask_datagen.fit(Y_train[:int(Y_train.shape[0]*0.9)], augment=True, seed=seed)
  
  x=image_datagen.flow(X_train[:int(X_train.shape[0]*0.9)],batch_size=BATCH_SIZE,shuffle=True, seed=seed)
  y=mask_datagen.flow(Y_train[:int(Y_train.shape[0]*0.9)],batch_size=BATCH_SIZE,shuffle=True, seed=seed)
  
  
  
  # Creating the validation Image and Mask generator
  image_datagen_val = image.ImageDataGenerator()
  mask_datagen_val = image.ImageDataGenerator()
  
  image_datagen_val.fit(X_train[int(X_train.shape[0]*0.9):], augment=True, seed=seed)
  mask_datagen_val.fit(Y_train[int(Y_train.shape[0]*0.9):], augment=True, seed=seed)
  
  x_val=image_datagen_val.flow(X_train[int(X_train.shape[0]*0.9):],batch_size=BATCH_SIZE,shuffle=True, seed=seed)
  y_val=mask_datagen_val.flow(Y_train[int(Y_train.shape[0]*0.9):],batch_size=BATCH_SIZE,shuffle=True, seed=seed)
  
  train_generator = zip(x, y)
  val_generator = zip(x_val, y_val)
  </code></pre>
  <p>EDIT2:
  I also tried the following for a workaround (@Yefet's suggestion):</p>
  <pre><code>image_datagen = image.ImageDataGenerator(shear_range=0.5, rotation_range=50, zoom_range=0.2, width_shift_range=0.2, height_shift_range=0.2, fill_mode='reflect')
  
  train_datagen=image_datagen.flow(X_train[:int(X_train.shape[0]*0.9)], Y_train[:int(Y_train.shape[0]*0.9)] ,batch_size=BATCH_SIZE,shuffle=True, seed=seed)
  
  # Creating the validation Image and Mask generator
  image_datagen_val = image.ImageDataGenerator()
  
  val_datagen=image_datagen_val.flow(X_train[:int(X_train.shape[0]*0.9)], Y_train[:int(Y_train.shape[0]*0.9)] ,batch_size=BATCH_SIZE,shuffle=True, seed=seed)
  </code></pre>
  <p>with</p>
  <pre><code>model.fit(train_generator, epochs=EPOCHS,
                            steps_per_epoch=STEPS_PER_EPOCH,
                            validation_steps=VALIDATION_STEPS,
                            validation_data=val_generator,
                            callbacks=[DisplayCallback()])
  </code></pre>
  <p>but I get  <code>ValueError: Please provide as model inputs either a single array or a list of arrays. You passed: x=&lt;keras.preprocessing.image.NumpyArrayIterator object at 0x7f9907f74438&gt;</code>.
  Thanks in advance!</p>