【问题标题】:Tensorflow - how to unfreeze only specific layer?Tensorflow - 如何仅解冻特定层?
【发布时间】:2021-05-27 09:51:19
【问题描述】:

我正在使用这样的预训练模型:

base_model = keras.applications.Xception(
    weights='imagenet',
    input_shape=(150,150,3),
    include_top=False
)

然后我冻结所有层:

base_model.trainable = False

现在,我只想解冻,比如说最底层。 当我做base_model.summary() 时,底部是这样的:

所以,假设我想解冻block14_sepconv2 层。 我愿意:

my_layer = base_model.get_layer('block14_sepconv2')
my_layer.trainable = True

summary() 仍然显示,Trainable params: 0 我做错了什么?如何只解冻几个最低层?

有趣的是,当我第一次做base_model.trainable = True,然后我从顶部冻结层时,可训练的参数数量实际上发生了变化。但它对我来说并不直观,主要不是不可理解。

【问题讨论】:

    标签: tensorflow keras deep-learning neural-network conv-neural-network


    【解决方案1】:

    这是解冻特定图层的一种方法。我们选择相同的模型和一些层(例如block14_sepconv2)。目的是解冻这些层并使其余层冻结

    from tensorflow import keras
    
    base_model = keras.applications.Xception(
        weights='imagenet',
        input_shape=(150,150,3),
        include_top=False
    )
    
    # free all layer except the desired layers
    # which is in [ ... ]
    for layer in base_model.layers:
        if layer.name not in ['block14_sepconv2', 'block13_sepconv1']:
            layer.trainable = False
        
        if layer.trainable:
            print(layer.name)
    
    block14_sepconv2
    block13_sepconv1
    

    计算可训练和不可训练的变量。

    import tensorflow.keras.backend as K
    import numpy as np 
    
    trainable_count = np.sum([K.count_params(w) \
                              for w in base_model.trainable_weights])
    non_trainable_count = np.sum([K.count_params(w) \
                                  for w in base_model.non_trainable_weights])
    print('Total params: {:,}'.format(trainable_count + non_trainable_count))
    print('Trainable params: {:,}'.format(trainable_count))
    print('Non-trainable params: {:,}'.format(non_trainable_count))
    
    Total params: 20,861,480
    Trainable params: 3,696,088
    Non-trainable params: 17,165,392
    

    仅供参考,每次冻结或解冻层时不要忘记重新编译模型 (model.compile(...))。

    【讨论】:

    • 好的!奇怪的是,它不能反过来工作:就像我一样 - 冻结所有并解冻特定。您能否也发布一个循环版本,我们在其中访问和解冻特定数量的较低层?我试图这样做:base_model.layers[-10:]
    • 实际上循环非常简单,但我不明白,为什么当我执行 [-10:] 时显示 15M 可训练参数,而使用 [-15:] 时显示更少 - 13M
    • 我已将您的标题从 freeze word 更改为 unfreeze,因为在您的问题中,您提到要解冻该特定图层。
    • 关于循环,我不明白你的担心,你想冻结/解冻层的范围,例如第 5 层到第 10 层吗?
    • 关于微调。我只想微调 5 个低层,然后用微调的 10 个低层检查性能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-25
    • 2020-03-15
    • 2011-06-07
    • 1970-01-01
    • 2021-09-24
    • 1970-01-01
    相关资源
    最近更新 更多