【问题标题】:Remove top layer from pre-trained model, transfer learning, tensorflow (load_model)从预训练模型中移除顶层,迁移学习,张量流(load_model)
【发布时间】:2022-01-14 13:00:36
【问题描述】:

我已经预训练了一个包含两个类的模型(我自己保存的模型),我想将其用于迁移学习来训练一个包含六个类的模型。 我已将预训练模型加载到新的训练脚本中:

base_model = tf.keras.models.load_model("base_model_path")

如何移除顶层/头层(conv1D 层)?

我看到在 keras 中可以使用 base_model.pop(),而对于 tf.keras.applications 可以简单地使用 include_top=false 但是在使用 tf.keras 和 load_model 时有类似的东西吗?

(我尝试过这样的事情:

for layer in base_model.layers[:-1]:
    layer.trainable = False`

然后将其添加到新模型中(?),但我不确定如何继续)

感谢您的帮助!

【问题讨论】:

    标签: python tensorflow keras tf.keras transfer-learning


    【解决方案1】:

    你可以试试这样的:

    基本模型由一个简单的Conv1D 网络组成,其输出层有两个类:

    import tensorflow as tf
    
    samples = 100
    timesteps = 5
    features = 2
    classes = 2
    dummy_x, dummy_y = tf.random.normal((100, 5, 2)), tf.random.uniform((100, 1), maxval=2, dtype=tf.int32)
    
    base_model = tf.keras.Sequential()
    base_model.add(tf.keras.layers.Conv1D(32, 3, activation='relu', input_shape=(5, 2)))
    base_model.add(tf.keras.layers.GlobalMaxPool1D())
    base_model.add(tf.keras.layers.Dense(32, activation='relu'))
    base_model.add( tf.keras.layers.Dense(classes, activation='softmax'))
    
    base_model.compile(optimizer='adam', loss = tf.keras.losses.SparseCategoricalCrossentropy())
    print(base_model.summary())
    base_model.fit(dummy_x, dummy_y, batch_size=16, epochs=1)
    base_model.save("base_model")
    base_model = tf.keras.models.load_model("base_model")
    
    Model: "sequential_8"
    _________________________________________________________________
     Layer (type)                Output Shape              Param #   
    =================================================================
     conv1d_31 (Conv1D)          (None, 3, 32)             224       
                                                                     
     global_max_pooling1d_13 (Gl  (None, 32)               0         
     obalMaxPooling1D)                                               
                                                                     
     dense_17 (Dense)            (None, 32)                1056      
                                                                     
     dense_18 (Dense)            (None, 2)                 66        
                                                                     
    =================================================================
    Total params: 1,346
    Trainable params: 1,346
    Non-trainable params: 0
    _________________________________________________________________
    None
    7/7 [==============================] - 0s 3ms/step - loss: 0.6973
    INFO:tensorflow:Assets written to: base_model/assets
    

    新模型也是由一个简单的Conv1D 网络组成,但有一个包含六个类的输出层。它还包含base_model 的所有层,除了第一个Conv1D 层和最后一个输出层:

    classes = 6
    dummy_x, dummy_y = tf.random.normal((100, 5, 2)), tf.random.uniform((100, 1), maxval=6, dtype=tf.int32)
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Conv1D(64, 3, activation='relu', input_shape=(5, 2)))
    model.add(tf.keras.layers.Conv1D(32, 2, activation='relu'))
    for layer in base_model.layers[1:-1]: # Skip first and last layer
      model.add(layer)
    model.add(tf.keras.layers.Dense(classes, activation='softmax'))
    model.compile(optimizer='adam', loss = tf.keras.losses.SparseCategoricalCrossentropy())
    print(model.summary())
    model.fit(dummy_x, dummy_y, batch_size=16, epochs=1)
    
    Model: "sequential_9"
    _________________________________________________________________
     Layer (type)                Output Shape              Param #   
    =================================================================
     conv1d_32 (Conv1D)          (None, 3, 64)             448       
                                                                     
     conv1d_33 (Conv1D)          (None, 2, 32)             4128      
                                                                     
     global_max_pooling1d_13 (Gl  (None, 32)               0         
     obalMaxPooling1D)                                               
                                                                     
     dense_17 (Dense)            (None, 32)                1056      
                                                                     
     dense_19 (Dense)            (None, 6)                 198       
                                                                     
    =================================================================
    Total params: 5,830
    Trainable params: 5,830
    Non-trainable params: 0
    _________________________________________________________________
    None
    7/7 [==============================] - 0s 3ms/step - loss: 1.8069
    <keras.callbacks.History at 0x7f90c87a3c50>
    

    【讨论】:

    • 非常感谢!如果我只跳过旧模型的最后一层,你知道我如何将输入形状定义/添加到新模型中吗? base_model = tf.keras.models.load_model("base_model_path") new_model = tf.keras.Sequential() for idx, layer in enumerate(base_model.layers[:-1]): layer._name = layer.name + str( idx) layer.trainable = False new_model.add(layer) new_model.add(tf.keras.layers.Dense(6, activation='softmax')
    • 您现在的问题是什么?我的回答没有回答你的问题吗?
    • 是的,您的回答确实回答了我的问题,非常感谢您的帮助!当我尝试训练我的新模型时,我遇到了一个新错误,这似乎是输入形状的问题。由于我没有更改模型的第一层,因此我不确定如何定义输入形状,就像您在添加到新模型的第一层中所做的那样。
    • 您想将基本模型中的输入形状用于新模型吗?
    • 是的,很抱歉,我意识到这里的代码可能太多了,所以我自己再试一次。再次感谢您的帮助!
    猜你喜欢
    • 2020-11-30
    • 1970-01-01
    • 2020-05-21
    • 2018-09-24
    • 2022-11-10
    • 2021-04-17
    • 1970-01-01
    • 2021-01-18
    • 1970-01-01
    相关资源
    最近更新 更多