evaluating two inputs and one output model tensorflow

Issue

I am trying to evaluate a model with 2 inputs and 1 output, each input goes to separate pretrained model and then the output from both the models get averaged. I am using the same data for both the inputs.

test_dir = 'D:\Graduation_project\Damage type not collected'



test_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255,)




test_set = test_datagen.flow_from_directory(test_dir,
                                            class_mode = 'categorical',
                                            batch_size = 16, 
                                            target_size=(150,150))

test_set1 = test_datagen.flow_from_directory(test_dir,
                                            class_mode = 'categorical',
                                            batch_size = 16, 
                                            target_size=(150,150))

loading first model and renaming the layers

def load_dense_model():
    densenet = tf.keras.models.load_model('D:\Graduation_project\saved models\damage_type_model.h5', compile=False)
    
    for i, layer in enumerate(densenet.layers):
        layer._name = 'Densenet_layer' + str(i)
    return densenet
 

loading second model

def load_vgg19_model():
    vgg19 = tf.keras.models.load_model('D:\Graduation_project\saved models\damage_type_VGG19.h5', compile=False)
     
    return vgg19

creating ensemble model

def ensamble_model(first_model, second_model):
    densenet = first_model()
    vgg19 = second_model()

    output_1 = densenet.get_layer('Densenet_layer613')
    output_2 = vgg19.get_layer('dense_4')
    
    avg = tf.keras.layers.Average()([output_1.output, output_2.output])
    
    
    model = Model(inputs=[densenet.input, vgg19.input], outputs=avg)
    
    return model

METRICS = [ 
     'accuracy',
      tf.metrics.TruePositives(name='tp'),
      tf.metrics.FalsePositives(name='fp'),
      tf.metrics.TrueNegatives(name='tn'),
      tf.metrics.FalseNegatives(name='fn'), 
      tf.metrics.Precision(name='precision'),
      tf.metrics.Recall(name='recall'),
      tfa.metrics.F1Score(name='F1_Score', num_classes=5),
      tfa.metrics.MultiLabelConfusionMatrix(num_classes=5)
 
]

model = ensamble_model(load_dense_model, load_vgg19_model)

compiling and evaluating the model

model.compile(optimizer = 'adam' , loss ='binary_crossentropy', 
                  metrics = 'accuracy')

model.evaluate({'Densenet_layer0':test_set1, 'input_2':test_set})

evaluate() fails to run

ValueError: Failed to find data adapter that can handle input: (<class 'dict'> containing {"<class 'str'>"} keys and {"<class 'tensorflow.python.keras.preprocessing.image.DirectoryIterator'>"} values), <class 'NoneType'> 

Solution

My guess is that your model complaining because you are feeding a dict/list of iterators that yield an image each, instead of feeding an iterator that yields the image twice (once for each model).

What would happen if you wrap your DirectoryIterator on a generator that can feed the data correctly?

def gen_itertest(test_dir):
    test_set = test_datagen.flow_from_directory(test_dir,
                                            class_mode = 'categorical',
                                            batch_size = 16, 
                                            target_size=(150,150))
    for i in range(len(test_set)):
         x = test_set.next()
         yield [x[0], x[0]], x[1] # Twice the input, only once the label

and then you can feed this to the evaluate

testset = gen_itertest('D:\Graduation_project\Damage type not collected')
result = model.evaluate(testset)

I am not sure this will work but because you haven’t provide us with a minimal, reproducible example, I am not going to do one to test it.

Answered By – Albert Alonso

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published