Keras 2 API 文档 / 层 API / 归一化层 / 批量归一化层

批量归一化层

[源]

BatchNormalization

tf_keras.layers.BatchNormalization(
    axis=-1,
    momentum=0.99,
    epsilon=0.001,
    center=True,
    scale=True,
    beta_initializer="zeros",
    gamma_initializer="ones",
    moving_mean_initializer="zeros",
    moving_variance_initializer="ones",
    beta_regularizer=None,
    gamma_regularizer=None,
    beta_constraint=None,
    gamma_constraint=None,
    synchronized=False,
    **kwargs
)

对其输入进行归一化的层。

批量归一化应用一种转换,使输出均值保持接近 0,输出标准差保持接近 1。

重要的是,批量归一化在训练和推理期间的工作方式不同。

训练期间(即使用 fit() 或调用层/模型时带有参数 training=True),该层使用当前批输入的均值和标准差对其输出进行归一化。也就是说,对于每个被归一化的通道,该层返回 gamma * (batch - mean(batch)) / sqrt(var(batch) + epsilon) + beta,其中

  • epsilon 是一个小的常数(可在构造函数参数中配置)
  • gamma 是一个学习到的缩放因子(初始化为 1),通过向构造函数传递 scale=False 可以禁用。
  • beta 是一个学习到的偏移因子(初始化为 0),通过向构造函数传递 center=False 可以禁用。

推理期间(即使用 evaluate()predict() 或调用层/模型时带有参数 training=False(这是默认值)),该层使用训练期间见过的批次的均值和标准差的移动平均值对其输出进行归一化。也就是说,它返回 gamma * (batch - self.moving_mean) / sqrt(self.moving_var+epsilon) + beta

self.moving_meanself.moving_var 是非训练变量,每次层在训练模式下被调用时都会更新,更新方式如下

  • moving_mean = moving_mean * momentum + mean(batch) * (1 - momentum)
  • moving_var = moving_var * momentum + var(batch) * (1 - momentum)

因此,该层仅在推理期间对其输入进行归一化,但前提是它已经在与推理数据具有相似统计信息的数据上进行过训练

当设置了 synchronized=True 并且此层在 tf.distribute 策略中使用时,每个训练步骤都会有一个 allreduce 调用来聚合所有副本上的批统计信息。在未指定任何分布式策略进行模型训练时,设置 synchronized 没有影响。

示例用法

strategy = tf.distribute.MirroredStrategy()

with strategy.scope():
  model = tf.keras.Sequential()
  model.add(tf.keras.layers.Dense(16))
  model.add(tf.keras.layers.BatchNormalization(synchronized=True))

参数

  • axis:整数,指定需要归一化的轴(通常是特征轴)。例如,在 data_format="channels_first"Conv2D 层之后,在 BatchNormalization 中设置 axis=1
  • momentum:移动平均的动量。
  • epsilon:添加到方差中的一个很小的浮点数,用于避免除零错误。
  • center:如果为 True,则将 beta 的偏移量添加到归一化张量中。如果为 False,则忽略 beta
  • scale:如果为 True,则乘以 gamma。如果为 False,则不使用 gamma。当下一层是线性层(例如 nn.relu)时,可以禁用此选项,因为缩放将由下一层完成。
  • beta_initializer:beta 权重的初始化器。
  • gamma_initializer:gamma 权重的初始化器。
  • moving_mean_initializer:移动均值的初始化器。
  • moving_variance_initializer:移动方差的初始化器。
  • beta_regularizer:beta 权重的可选正则化器。
  • gamma_regularizer:gamma 权重的可选正则化器。
  • beta_constraint:beta 权重的可选约束。
  • gamma_constraint:gamma 权重的可选约束。
  • synchronized:如果为 True,在分布式训练策略中,每个训练步骤都会同步跨所有设备的全局批统计信息(均值和方差)。如果为 False,每个副本使用其自身的本地批统计信息。仅在 tf.distribute 策略中使用时相关。

调用参数

  • inputs:输入张量(任意阶数)。
  • training:Python 布尔值,指示层应在训练模式还是推理模式下工作。
    • training=True:该层将使用当前输入批次的均值和方差对其输入进行归一化。
    • training=False:该层将使用训练期间学到的移动统计信息(均值和方差)对其输入进行归一化。

输入形状

任意。当此层作为模型的第一层使用时,请使用关键字参数 input_shape(整数元组,不包括样本轴)。

输出形状

与输入形状相同。

参考文献

关于在 BatchNormalization 层上设置 layer.trainable = False

设置 layer.trainable = False 的含义是冻结该层,即其内部状态在训练期间不会改变:其可训练权重在 fit()train_on_batch() 期间不会更新,并且其状态更新不会运行。

通常,这不一定意味着该层在推理模式下运行(这通常由调用层时可以传递的 training 参数控制)。“冻结状态”和“推理模式”是两个独立的概念。

然而,对于 BatchNormalization 层,在该层上设置 trainable = False 意味着该层随后将在推理模式下运行(这意味着它将使用移动均值和移动方差来归一化当前批次,而不是使用当前批次的均值和方差)。

此行为是在 TensorFlow 2.0 中引入的,以便在 convnet 微调用例中,layer.trainable = False 可以产生最常期望的行为。

请注意:- 在包含其他层的模型上设置 trainable 将递归地设置所有内层中的 trainable 值。- 如果在模型上调用 compile() 后更改了 trainable 属性的值,则新值在该模型上需要再次调用 compile() 后才会生效。