Search code examples
machine-learningkerasdeep-learningneural-networkgoogle-colaboratory

Changing one model automatically Changes another in keras


(this is my first question ever!) I am working in google colab. I fine tuned a Resnet50 model in keras and saved the weights. Now, later during testing, I loaded the model weights like this:

res50 = keras.applications.ResNet50(weights= None, include_top=False, input_shape=(image_size, image_size, 3))

# Create the model
model = Sequential()

model.add(res50)

model.add(Flatten())
model.add(Dense(100, activation='relu'))
model.add(Dropout(0.5))#0.75
model.add(Dense(1, activation='sigmoid'))#softmax #to Sigmoid

model.summary()

new_model = model    
new_model.load_weights('/content/drive/My Drive/model_weights.hdf5')

model.compile(
    optimizer=keras.optimizers.Adam(1e-4),#1e-6
    loss="binary_crossentropy",
    metrics=["accuracy"],
)

Notice in last block, I compiled 'model', not 'new_model'. Yet I see that 'new_model' also becomes compiled. Further, I noticed that the weights of "model" are also updated, not just 'new_model'. Basically making any change to either changes the other. Why is this happening? Is this the right way to load the weights? I have very basic understanding of programming. Please help.


Solution

  • The problem here is that you are assigning to new_model a pointer to model, so basically new_model and model are referencing to the same variable.

    You could solve this by creating an auxiliary function that generates a new model with the required structure:

    def make_model(base_model):
        model = Sequential()
        model.add(base_model)
        model.add(Flatten())
        model.add(Dense(100, activation='relu'))
        model.add(Dropout(0.5))#0.75
        model.add(Dense(1, activation='sigmoid'))#softmax #to Sigmoid
        return model
    

    Finally:

    res50 = keras.applications.ResNet50(weights= None, include_top=False, input_shape=(image_size, image_size, 3))
    
    # Create the model
    new_model = make_model(base_model=res50)
    
    new_model.summary()
      
    new_model.load_weights('/content/drive/My Drive/model_weights.hdf5')
    
    new_model.compile(
        optimizer=keras.optimizers.Adam(1e-4),#1e-6
        loss="binary_crossentropy",
        metrics=["accuracy"],
    )
    

    In this way, if you need to create additional models in the future with the loaded weights of another model, you'll just need to do:

    new_future_model = make_model(new_base_model)