Multihead model based on DenseNet201 using Keras

115 views Asked by At

I am trying to use this notebook where we define a 3-head model based on DenseNet201. The AlexNet based works correctly but DenseNet201 throws me an error. I am a Pytorch user and have not been able to figure out the error of ValueError: Missing data for input "input_5". You passed a data dictionary with keys ['img_input']. Expected the following keys: ['input_5']. I know somewhere in the following code snippet I should have a name 'img_input' but I cannot figure it out.

class base_model():
  def __init__(self, side_dim, n_bb, n_classes, name_model):
    self.side_dim = side_dim
    self.name_model = name_model

    # base model DenseNet
    if name_model == 'DenseNet201':
      self.base_model = keras.applications.DenseNet201(
                              include_top=False,
                              input_shape=(self.side_dim, self.side_dim, 3),
                              )

      self.image_input = self.base_model.input

      self.flatten = keras.layers.Flatten()(self.base_model.layers[-2].output)

      self.BatcNorm = keras.layers.BatchNormalization()(self.flatten)

      print('Base model: DenseNet121 (7.2M params x 201 layers')

    # ----------------------------------------------------------------------
    # Add head with three different outputs to last layer of the basic model 
    # ----------------------------------------------------------------------   
    # class output 
    self.class_categorical = keras.layers.Dense((n_bb * n_classes), 
                                                activation='softmax')(self.BatcNorm)
    self.class_output = keras.layers.Reshape((n_bb, n_classes), 
                                             name='class_output')(self.class_categorical)

    # confidence output
    self.score_confidence = keras.layers.Dense((n_bb), 
                                               name='score_confidence', 
                                               activation='tanh')(self.BatcNorm)

    # bounding boxes coordinate output
    self.score_coords = keras.layers.Dense((n_bb * 4), 
                                           name='score_coords')(self.BatcNorm)

The error is thrown when I run the following:

# let's start our training
train_history = myModel.fit({'img_input': X_train}, 
                    {'class_output': class_target, 
                     'score_confidence': target_confidence, 
                     'score_coords': target_coords},
                    epochs=N_ep, 
                    validation_data=({'img_input': X_val}, 
                                     {'class_output': Val_class, 
                                      'score_confidence': Val_confidence, 
                                      'score_coords': Val_coords}), 
                    batch_size=Batchs, 
                    initial_epoch = init_ep, 
                    verbose=1,
                    callbacks=[callbacks, 
                               tensorboard_callback])

In the AlexNet based network, the input name is changed directly but I do not know how to do it for the DenseNet201.

Can you please help me?

1

There are 1 answers

1
Lescurel On BEST ANSWER

The issue is that your input node does not have the same name as the dictionary key holding your input.

You can create your input layer before hand wit the right name, and pass it to the DenseNet201 function as the input tensor.

self.image_input = keras.Input((self.side_dim, self.side_dim, 3), name="img_input")
self.base_model = keras.applications.DenseNet201(
                          include_top=False,
                          input_tensor=self.image_input,
                          )

Another option is to get the name of the input right in your dictionary by using the name of the input node:

myModel.fit({myModel.input.name: X_train}, 
            {'class_output': class_target, 
            'score_confidence': target_confidence, 
            'score_coords': target_coords})

A final option is to skip using a dictionary all together, given that you have a single input:

myModel.fit(X_train, 
            {'class_output': class_target, 
            'score_confidence': target_confidence, 
            'score_coords': target_coords})