Search code examples
pythonmachine-learningkerasensemble-learningimage-classification

Is there a way to ensemble two keras (h5) models trained for same classes


I have trained two keras models with different datasets for same class labels. How could I ensemble the models keras_model.h5 and keras_model2.h5 together and make another keras model say keras_ensemble.h5. I have tried referring various internet sources but not luck. Can someone help me with the code for ensembling it? Here are the models I've trained

Please assist me through this.Thank you.

Edit: This was my code which i was able to get through with the help of the one who responded to my question Frightera

 import tensorflow.keras
    import tensorflow as tf
    from PIL import Image, ImageOps
    import numpy as np
    
    # Disable scientific notation for clarity
    np.set_printoptions(suppress=True)
    
    # Load the model
    keras_model = tensorflow.keras.models.load_model('keras_model.h5', compile=False)
    keras_model._name = 'model1'
    keras_model2 = tensorflow.keras.models.load_model('keras_model2.h5', compile=False)
    keras_model2._name = 'model2'
    models = [keras_model, keras_model2]
    #model_input = tf.keras.Input(shape=(125, 125, 3))
    model_input = tf.keras.Input(shape=(224, 224, 3))
    model_outputs = [model(model_input) for model in models]
    ensemble_output = tf.keras.layers.Average()(model_outputs)
    ensemble_model = tf.keras.Model(inputs=model_input, outputs=ensemble_output)

EDIT How do i get the keras ensemble model in h5 format??


Solution

  • You can average-ensemble them like this:

    models = [keras_model, keras_model2]
    model_input = tf.keras.Input(shape=(125, 125, 3))
    model_outputs = [model(model_input) for model in models]
    ensemble_output = tf.keras.layers.Average()(model_outputs)
    ensemble_model = tf.keras.Model(inputs=model_input, outputs=ensemble_output)
    

    enter image description here


    Edit: If you want to create weighted ensemble you can create a custom layer like this:

    class WeightedAverageLayer(tf.keras.layers.Layer):
        def __init__(self, w1, w2, **kwargs):
            super(WeightedAverageLayer, self).__init__(**kwargs)
            self.w1 = w1
            self.w2 = w2
    
        def call(self, inputs):
            return self.w1 * inputs[0] + self.w2 * inputs[1]
    

    So the output layer should look like this:

    ensemble_output = WeightedAverageLayer(0.6, 0.4)(model_outputs)
    

    Here, first model's output is scaled with a factor of 0.6. Same thing applies for the second model, with a factor of 0.4.

    Note: WeightedAverageLayer(0.5, 0.5) will be identical to tf.keras.layers.Average().