使用Keras进行预训练神经网络微调。如何冻结批量归一化?

3

所以我没有用tf.keras编写我的代码,根据这篇预训练NN微调的教程:https://keras.io/guides/transfer_learning/#freezing-layers-understanding-the-trainable-attribute ,当我设置参数时,需要在调用预训练模型时将training=False,以便在稍后解冻进行微调时,批归一化不会破坏我的模型。但是在keras中该如何实现呢?(请记住:我没有在tf.keras中编写它)。 在keras中是否需要这样做呢?

代码:

def baseline_model():
    pretrained_model = Xception(include_top=False, weights="imagenet")

    for layer in pretrained_model.layers:
        layer.trainable = False

    general_input = Input(shape=(256, 256, 3))

    x = pretrained_model(general_input,training=False)
    x = GlobalAveragePooling2D()(x)
...

调用 model = baseline_model() 时,出现了错误。
TypeError: call() got an unexpected keyword argument 'training'

我要怎样才能做到最好呢?我尝试将所有内容重写为tf.keras,但是当我尝试这样做时,随处出现错误...

编辑:我的keras版本是2.3.1,tensorflow版本是2.2.0。

1个回答

1

在进行了一些额外的研究后,我修改了之前的答案:
我阅读了一些资料,发现当BatchNorm层被冻结时,它的行为有些诡异。这是一个很好的讨论帖:github.com/keras-team/keras/issues/7085 看起来training=false参数是正确冻结BatchNorm层所必需的,并且在Keras 2.1.3中添加了该参数,所以我建议您确保您的Keras/TF版本更高。


所以你说微调似乎有效?即预训练模型中的批量归一化层在解冻和重新训练时不被更新/破坏模型? - jackbauer
正确。一旦您执行此操作:layer.trainable = False,它将冻结所述层中的所有权重,并且不再可训练。您可以通过运行 model.summary() 以后检查它 - 它应该显示整个模型的可训练和不可训练参数数量。 - Karol Żak
是的,但在微调时,我会将layer.trainable = True设置为一些或全部层? - jackbauer
是的,你需要这样做。关于BatchNorm,我进行了一些阅读,似乎在冻结时BatchNorm层的行为有些诡计。这是一个很好的讨论帖子:https://github.com/keras-team/keras/issues/7085 看起来training=false参数是在Keras 2.1.3中添加的,因此请确保您的Keras/TF版本是最新的。 - Karol Żak
我的Keras版本是2.3.1,TensorFlow版本是2.2.0,所以上述代码应该可以工作。或者我需要以不同的方式将其设置为False吗? - jackbauer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接