简体   繁体   中英

Keras Transfer-Learning setting layers.trainable to True has no effect

I want to f.netune efficien.net using tf.keras (tensorflow 2.3) but i cannot change the training status of layers properly. My model looks like this:

data_augmentation_layers = tf.keras.Sequential([
 keras.layers.experimental.preprocessing.RandomFlip("horizontal_and_vertical"),
 keras.layers.experimental.preprocessing.RandomRotation(0.8)])

efficientnet = EfficientNetB3(weights="imagenet", include_top=False,
                                input_shape=(*img_size, 3))

#Setting to not trainable as described in the standard keras FAQ
efficientnet.trainable = False

inputs = keras.layers.Input(shape=(*img_size, 3))
augmented = augmentation_layers(inputs)
base = efficientnet(augmented, training=False)
pooling = keras.layers.GlobalAveragePooling2D()(base)
outputs = keras.layers.Dense(5, activation="softmax")(pooling)

model = keras.Model(inputs=inputs, outputs=outputs)

model.compile(loss="categorical_crossentropy", optimizer=keras_opt, metrics=["categorical_accuracy"])

This is done so that my random weights on the custom top wont destroy the weights asap.

    Model: "functional_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_2 (InputLayer)         [(None, 512, 512, 3)]     0         
_________________________________________________________________
sequential (Sequential)      (None, 512, 512, 3)       0         
_________________________________________________________________
efficientnetb3 (Functional)  (None, 16, 16, 1536)      10783535  
_________________________________________________________________
global_average_pooling2d (Gl (None, 1536)              0         
_________________________________________________________________
dense (Dense)                (None, 5)                 7685      
=================================================================
Total params: 10,791,220
Trainable params: 7,685
Non-trainable params: 10,783,535

Everything seems to work until this point. I train my model for 2 epochs and then i want to start fine-tuning the efficien.net base. Thus i call

for l in model.get_layer("efficientnetb3").layers:
  if not isinstance(l, keras.layers.BatchNormalization):
    l.trainable = True

model.compile(loss="categorical_crossentropy", optimizer=keras_opt, metrics=["categorical_accuracy"])

I recompiled and print the summary again to see that the number of non-trainable weights remained the same. Also fitting does not bring better results that keeping frozen.

 dense (Dense)                (None, 5)                 7685      
    =================================================================
    Total params: 10,791,220
    Trainable params: 7,685
    Non-trainable params: 10,783,535

Ps: I also tried efficien.net3.trainable = True but this also had no effect.

Could it be that it has something to do with the fact that i'm using a sequential and a functional model at the same time?

For me the problem was using sequential API for part of the model. When I change to sequential, my model.sumary() displayed all the sublayers and it was possible to set some of them as trainable and others not.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM