Search code examples
imagekerastensorflow2.0prepend

How do I prepend a sequential model to a pretrained model in Keras?


I want to put a 4-layer dense network in front of a pretrained model like nasnet_mobile. I have tried this several different ways, but they all give headaches (aka errors). What is the way to do this in keras+tensorflow2 that works?

Thoughts:

  • Is there some "flag" where I have to specify the output of the Dense as integer, or picture?
  • Is there some "flag" in the pretrained model where I have to allow it to connect?
  • Do I need to manually make a clone of the pretrained, load it with pretrained weights, and then try one of the above; perhaps the pretrained are a different class than the created? (update) If I'm copying, is there an easy way to make sure I get the structure the same so that when I have set_weights(get_weights(…)) it doesn't error?

  • None of the above...

CODE:

#LIBRARIES
import numpy as np
from tensorflow import keras
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import Dense, Reshape, Conv2D, MaxPool2D , Flatten, Input


my_input_shape = (224,224,3)

#DENSE MODEL
my_inputs = Input(shape=my_input_shape)

hidden_1 = Dense(units=8, activation='relu')(my_inputs)


#make the output layer
hidden_2= Dense(units=np.product(my_input_shape), 
                           activation='sigmoid')(hidden_1)

transformed = keras.layers.Reshape(my_input_shape,)(hidden_2)  

dense_model = Model(inputs=my_inputs, outputs=transformed)

#PRETRAINED MODEL
pretrained_model = keras.applications.nasnet.NASNetMobile(weights = 'imagenet', 
                                                            include_top = False,
                                                            input_shape=my_input_shape)

#Option 1
combined_model_1 = keras.applications.nasnet.NASNetMobile(weights = 'imagenet', 
                                                            include_top = False,
                                                            input_tensor=transformed)

#Option 2
combined_model_2 = Model(inputs=dense_model.input, outputs=pretrained_model.output)

#Option 3a
combined_model_3a = keras.applications.nasnet.NASNetMobile(weights = 'imagenet', 
                                                            include_top = False,
                                                            input_tensor=my_input_shape)(dense_model)
#Option 3b
combined_model_3b = keras.applications.nasnet.NASNetMobile(weights = 'imagenet', 
                                                            include_top = False)(dense_model)

#Option 4
combined_model_4 = keras.applications.nasnet.NASNetMobile(weights = 'imagenet', 
                                                            include_top = False,
                                                            input_tensor=dense_model)

Problem:
Given the above code, I want to daisy-chain the Dense model in front of the pretrained model. I want to feed an image into dense, have it propagate through dense, then be the input to the pretrained, and go through the pretrained.


Solution

  • Why not just do this:

    inp = Input(shape=my_input_shape)
    x = dense_model(inp)
    x = pretrained_model(x)
    
    final_model = Model(inp, x)