Search code examples
pythontensorflow2.0tf.kerastransfer-learningpre-trained-model

Error Pop Out while Add Layers from Pre-Trained Model


I am trying to fine-tune a pre-trained time-series model with 12 dimension physiological signals as inputs, yet, my dataset is only one dimension. Therefore, I built the first conv1d layer and set the weight from the pre-trained model. After that, I add the rest parts from the pre-trained model. But, an error popout and says the dimension mismatch.

Here are the details of my code and error:

#Load Whole Model and Weight of the First Conv1d Layer
BaseModel =  keras.models.load_model('model.hdf5')
input_w = BaseModel.layers[1].get_weights()[0]
input_w_1_lead = input_w[:,1,:].reshape(input_w.shape[0], 1, input_w.shape[2])

#Creat the Input and First Conv1d Layer
model = tf.keras.Sequential([
    keras.Input(shape=(4096, 1), dtype=np.float32, name='signal'),
    keras.layers.Conv1D(64, 16, padding='same', 
                        use_bias=False, name='conv1d_1',),
    ])

#Set the Weight from Pre-Trained Model
model.layers[0].set_weights([input_w_1_lead])

#Add the Rest Parts from Pre-Trained Model
for layer in BaseModel.layers[2:]:
    model.add(layer)

#And here is the error:
ValueError: Exception encountered when calling layer "add_1" (type Add).

A merge layer should be called on a list of inputs. Received: inputs=Tensor("Placeholder:0", shape=(None, 256, 128), dtype=float32) (not a list of tensors)

Call arguments received by layer "add_1" (type Add):
  • inputs=tf.Tensor(shape=(None, 256, 128), dtype=float32)

Then, I looked into the details of my code and found out that I could only add layers until the 11th one.

test_model = tf.keras.Sequential()

for layer in BaseModel.layers[:11]:
    #Not work if I set BaseModel.layers[:12]
    test_model.add(layer)

With model.summary(), dimension information seems missing after the pooling layer. Here are the outputs for both BaseModel.summary() and test_model.summary():

BaseModel

enter image description here

test_model

enter image description here

However, I couldn't find the solution.


Solution

  • Dear All,

    I figure out an alternative solution for my task. I modified the model's input and output layers from source code. Then set the weight from source model.

    Here is the solution code:

    'Load Pre-Trained Model to Get Weight'
    
    BaseModel =  keras.models.load_model('model.hdf5')
    input_w = BaseModel.layers[1].get_weights()[0]
    input_w_1_lead = input_w[:,1,:].reshape(input_w.shape[0], 1, input_w.shape[2])
    BaseModel.summary()
    
    'Build the Fine-Tuned Model'
    
    model = get_model(1)
    model.layers[1].set_weights([input_w_1_lead])
    
    'Load Weight from Source Model'
    for i in range(2, len(BaseModel.layers) -1):
        model.layers[i].set_weights(BaseModel.layers[i].get_weights())
    
    'Check the Weight is Equal to Source Code'
    for i in range(2, len(BaseModel.layers) -1):
        if np.allclose(
                BaseModel.layers[i].get_weights(),
                model.layers[i].get_weights()) is False:
            print('this way is no correct')
    

    Ta-da! It's work and nothing printed in the console.