'Have you experienced an error in Keras with a custom generator to handle double input (img + size) while training the model?

The goal is to categorize pottery using both images and a size. I'm using Tensorflow version 2.8.0 I created a custom generator to return ((img, size),classification) as follows:

    
    def __init__(self,input_gen1,input_gen2,
                 batch_size,
                 shuffle=False):
        self.batch_size = batch_size
        self.shuffle = shuffle
        self.gen = input_gen1
        self.measures = input_gen2

    def __len__(self):
        return len(self.gen)

    def on_epoch_end(self):
        pass

    def __getitem__(self, index):
        filenames_np = np.vectorize(os.path.basename)(np.array(self.gen.filenames[index : index + self.gen.batch_size]))
        measures_of_files = np.vectorize(self.measures.get)(filenames_np)
        return (self.gen[index][0],measures_of_files),self.gen[index][1]

and this is how the generator is used composing flow_from_directory and a dictionary filename-size

TRAINING_DIR = "/tmp/Anfore/training/"
train_datagen = ImageDataGenerator(rescale=1./255,
      zoom_range=0.2,
      horizontal_flip=True,
      fill_mode='nearest')
seed = 1
train_generator = train_datagen.flow_from_directory(TRAINING_DIR,
                                                    batch_size=64,
                                                    class_mode='categorical',
                                                    target_size=(150, 150),
                                                    seed=seed)
VALIDATION_DIR = "/tmp/Anfore/testing/"

validation_datagen = ImageDataGenerator(rescale=1./255)
validation_generator = validation_datagen.flow_from_directory(VALIDATION_DIR,
                                                              batch_size=64,
                                                              class_mode='categorical',
                                                              target_size=(150, 150))

testCustomDataGen_for_train = CustomDataGen(train_generator,dict_measures,batch_size=64)
testCustomDataGen_for_validation = CustomDataGen(validation_generator,dict_measures,batch_size=64)

The model is composed of pretrained InceptionV3 stripped of the last few layers and coupled with a simple Dense layer with Concatenate to classify the results.

weights_url = "https://storage.googleapis.com/mledu-datasets/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5"
weights_file = "inception_v3.h5"
urllib.request.urlretrieve(weights_url, weights_file)

# Instantiate the model
pre_trained_model = InceptionV3(input_shape=(150, 150, 3),
                                include_top=False,
                                weights=None)

# load pre-trained weights
pre_trained_model.load_weights(weights_file)

# freeze the layers
for layer in pre_trained_model.layers:
    layer.trainable = False

# pre_trained_model.summary()

last_layer = pre_trained_model.get_layer('mixed7')
last_output = last_layer.output
from keras.layers import *
from keras.utils.vis_utils import plot_model

model2 = Sequential()
model2.add(Dense(1, input_shape=(1,), activation="relu"))

# here I can join the 2 models
x = layers.Conv2D(128,kernel_size=(3,3),activation='relu',padding='same')(last_output)
x = layers.GlobalAveragePooling2D()(x)
mergedOut = Concatenate()([x,model2.output])
x = layers.Dense(12, activation="softmax", name="classification")(mergedOut)
model = Model([pre_trained_model.input,model2.input], x)
model.compile(optimizer='adam',
               loss='categorical_crossentropy',
               metrics=['acc'],
              run_eagerly=False)

The schema of the model is the following: enter image description here

The problem is that when I do the training

history = model.fit(
            testCustomDataGen_for_train,
            validation_data=testCustomDataGen_for_validation,
            epochs=150,
            verbose=1)

I get an error:

---------------------------------------------------------------------------
InvalidArgumentError                      Traceback (most recent call last)
<ipython-input-26-4d4e59a0e1c6> in <module>()
      3             validation_data=testCustomDataGen_for_validation,
      4             epochs=150,
----> 5             verbose=1)

1 frames
/usr/local/lib/python3.7/dist-packages/tensorflow/python/eager/execute.py in quick_execute(op_name, num_outputs, inputs, attrs, ctx, name)
     53     ctx.ensure_initialized()
     54     tensors = pywrap_tfe.TFE_Py_Execute(ctx._handle, device_name, op_name,
---> 55                                         inputs, attrs, num_outputs)
     56   except core._NotOkStatusException as e:
     57     if name is not None:

InvalidArgumentError: Graph execution error:
Detected at node 'gradient_tape/model_7/concatenate_9/ConcatOffset' defined at (most recent call last):
    File "/usr/lib/python3.7/runpy.py", line 193, in _run_module_as_main
      "__main__", mod_spec)
    File "/usr/lib/python3.7/runpy.py", line 85, in _run_code
      exec(code, run_globals)
    File "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py", line 16, in <module>
      app.launch_new_instance()
    File "/usr/local/lib/python3.7/dist-packages/traitlets/config/application.py", line 846, in launch_instance
      app.start()
    File "/usr/local/lib/python3.7/dist-packages/ipykernel/kernelapp.py", line 499, in start
      self.io_loop.start()
    File "/usr/local/lib/python3.7/dist-packages/tornado/platform/asyncio.py", line 132, in start
      self.asyncio_loop.run_forever()
    File "/usr/lib/python3.7/asyncio/base_events.py", line 541, in run_forever
      self._run_once()
    File "/usr/lib/python3.7/asyncio/base_events.py", line 1786, in _run_once
      handle._run()
    File "/usr/lib/python3.7/asyncio/events.py", line 88, in _run
      self._context.run(self._callback, *self._args)
    File "/usr/local/lib/python3.7/dist-packages/tornado/platform/asyncio.py", line 122, in _handle_events
      handler_func(fileobj, events)
    File "/usr/local/lib/python3.7/dist-packages/tornado/stack_context.py", line 300, in null_wrapper
      return fn(*args, **kwargs)
    File "/usr/local/lib/python3.7/dist-packages/zmq/eventloop/zmqstream.py", line 452, in _handle_events
      self._handle_recv()
    File "/usr/local/lib/python3.7/dist-packages/zmq/eventloop/zmqstream.py", line 481, in _handle_recv
      self._run_callback(callback, msg)
    File "/usr/local/lib/python3.7/dist-packages/zmq/eventloop/zmqstream.py", line 431, in _run_callback
      callback(*args, **kwargs)
    File "/usr/local/lib/python3.7/dist-packages/tornado/stack_context.py", line 300, in null_wrapper
      return fn(*args, **kwargs)
    File "/usr/local/lib/python3.7/dist-packages/ipykernel/kernelbase.py", line 283, in dispatcher
      return self.dispatch_shell(stream, msg)
    File "/usr/local/lib/python3.7/dist-packages/ipykernel/kernelbase.py", line 233, in dispatch_shell
      handler(stream, idents, msg)
    File "/usr/local/lib/python3.7/dist-packages/ipykernel/kernelbase.py", line 399, in execute_request
      user_expressions, allow_stdin)
    File "/usr/local/lib/python3.7/dist-packages/ipykernel/ipkernel.py", line 208, in do_execute
      res = shell.run_cell(code, store_history=store_history, silent=silent)
    File "/usr/local/lib/python3.7/dist-packages/ipykernel/zmqshell.py", line 537, in run_cell
      return super(ZMQInteractiveShell, self).run_cell(*args, **kwargs)
    File "/usr/local/lib/python3.7/dist-packages/IPython/core/interactiveshell.py", line 2718, in run_cell
      interactivity=interactivity, compiler=compiler, result=result)
    File "/usr/local/lib/python3.7/dist-packages/IPython/core/interactiveshell.py", line 2822, in run_ast_nodes
      if self.run_code(code, result):
    File "/usr/local/lib/python3.7/dist-packages/IPython/core/interactiveshell.py", line 2882, in run_code
      exec(code_obj, self.user_global_ns, self.user_ns)
    File "<ipython-input-26-4d4e59a0e1c6>", line 5, in <module>
      verbose=1)
    File "/usr/local/lib/python3.7/dist-packages/keras/utils/traceback_utils.py", line 64, in error_handler
      return fn(*args, **kwargs)
    File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1384, in fit
      tmp_logs = self.train_function(iterator)
    File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1021, in train_function
      return step_function(self, iterator)
    File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1010, in step_function
      outputs = model.distribute_strategy.run(run_step, args=(data,))
    File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1000, in run_step
      outputs = model.train_step(data)
    File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 863, in train_step
      self.optimizer.minimize(loss, self.trainable_variables, tape=tape)
    File "/usr/local/lib/python3.7/dist-packages/keras/optimizer_v2/optimizer_v2.py", line 531, in minimize
      loss, var_list=var_list, grad_loss=grad_loss, tape=tape)
    File "/usr/local/lib/python3.7/dist-packages/keras/optimizer_v2/optimizer_v2.py", line 583, in _compute_gradients
      grads_and_vars = self._get_gradients(tape, loss, var_list, grad_loss)
    File "/usr/local/lib/python3.7/dist-packages/keras/optimizer_v2/optimizer_v2.py", line 464, in _get_gradients
      grads = tape.gradient(loss, var_list, grad_loss)
Node: 'gradient_tape/model_7/concatenate_9/ConcatOffset'
All dimensions except 1 must match. Input 1 has shape [64 1] and doesn't match input 0 with shape [28 128].
     [[{{node gradient_tape/model_7/concatenate_9/ConcatOffset}}]] [Op:__inference_train_function_37647]

Maybe I'm too much of a newbie but I don't get the sense of the error. Can anybody give me a hint on where I can intervene to address the issue?

The colab notebook is here: https://colab.research.google.com/drive/17nIpC4OUy5gk0AnVhwNawfel4-HjS_h4?usp=sharing

Any help is warmly welcome



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source