tf.keras.layers.BatchNormalization冻结参数(bn层bug)

介绍

Keras中的 层(layer) 通常用参数trainable来控制该层的 权重是否可以更新。

在使用 keras 预训练模型时,用模型的属性trainable来控制各个层的 权重是否可以更新。

但是,tf.keras.layers.BatchNormalization不受上面的控制,即:无法通过上面2种方式冻结bn层

引发的问题

keras预训练模型中,包含bn层的,都会发生 过拟合、验证集的准确率不变 等问题,如:ResNet系列

详见:
https://www.malaoshi.top/show_1EF5JUYBib4t.html

解决方法

方法1

通过Keras的K.learning_phase冻结bn层参数

函数解释参见:
https://www.malaoshi.top/show_1EF5JTbvJ50y.html

demo代码

import tensorflow.keras.backend as K
# 冻结bn层
K.set_learning_phase(0)
# 预训练模型代码
.....
# 解冻bn层
K.set_learning_phase(1)
x = layerNp1(...)(x)
x = tf.keras.layers.BatchNormalization(...)(x)

案例:
keras resnet50过拟合导致验证集准确率不变的解决方法

方法2

tf.keras.layers.BatchNormalization的参数training,控制归一化时用的是当前Batch的均值和方差(训练模式)还是移动均值和方差(测试模式)。

代码:

x = BatchNormalization()(y, training=False)

注意

keras的不同版本,可能bn层会有不同的行为,也就是说,不要一味的使用K.set_learning_phase冻结、解冻bn层

当发现过拟合,验证集准确率不变时,再用K.set_learning_phase(0)进行测试

感谢:
https://zhuanlan.zhihu.com/p/56225304


原文出处:/show_1EF5JnCCFGcd.html