LayerNormalization 类tf_keras.layers.LayerNormalization(
axis=-1,
epsilon=0.001,
center=True,
scale=True,
beta_initializer="zeros",
gamma_initializer="ones",
beta_regularizer=None,
gamma_regularizer=None,
beta_constraint=None,
gamma_constraint=None,
**kwargs
)
Layer normalization 层 (Ba et al., 2016)。
独立地规范化批次中每个示例的上一层的激活,而不是像 Batch Normalization 那样跨批次进行。即,它应用一个变换,使每个示例内的平均激活保持接近 0,激活标准差保持接近 1。
给定一个张量 inputs,会在 axis 指定的轴上计算矩(均值和方差)并执行归一化。
示例
>>> data = tf.constant(np.arange(10).reshape(5, 2) * 10, dtype=tf.float32)
>>> print(data)
tf.Tensor(
[[ 0. 10.]
[20. 30.]
[40. 50.]
[60. 70.]
[80. 90.]], shape=(5, 2), dtype=float32)
>>> layer = tf.keras.layers.LayerNormalization(axis=1)
>>> output = layer(data)
>>> print(output)
tf.Tensor(
[[-1. 1.]
[-1. 1.]
[-1. 1.]
[-1. 1.]
[-1. 1.]], shape=(5, 2), dtype=float32)
请注意,在 Layer Normalization 中,归一化发生在每个示例 *内部* 的轴上,而不是跨批次的不同示例。
如果启用了 scale 或 center,该层将通过与可训练变量 gamma 进行广播来缩放归一化后的输出,并通过与可训练变量 beta 进行广播来居中输出。gamma 默认为一个全 1 的张量,beta 默认为一个全 0 的张量,因此在训练开始之前,居中和缩放操作相当于无操作。
因此,在启用了缩放和居中后,归一化方程如下:
令一个小型批次的中间激活为 inputs。
对于 inputs 中的每个样本 x_i 及其 k 个特征,我们计算样本的均值和方差
mean_i = sum(x_i[j] for j in range(k)) / k
var_i = sum((x_i[j] - mean_i) ** 2 for j in range(k)) / k
然后计算一个归一化后的 x_i_normalized,包括一个小的 epsilon 用于数值稳定性。
x_i_normalized = (x_i - mean_i) / sqrt(var_i + epsilon)
最后,x_i_normalized 将通过 gamma 和 beta 进行线性变换,它们是学习到的参数
output_i = x_i_normalized * gamma + beta
gamma 和 beta 将跨越 axis 中指定的 inputs 的轴,并且输入形状的这部分必须完全定义。
例如
>>> layer = tf.keras.layers.LayerNormalization(axis=[1, 2, 3])
>>> layer.build([5, 20, 30, 40])
>>> print(layer.beta.shape)
(20, 30, 40)
>>> print(layer.gamma.shape)
(20, 30, 40)
请注意,其他层归一化实现可能会选择将 gamma 和 beta 定义在与归一化轴不同的轴集上。例如,Group Normalization (Wu et al. 2018) 当 group size 为 1 时,等同于 Layer Normalization,它会在高度、宽度和通道上进行归一化,并且 gamma 和 beta 只跨越通道维度。因此,此 Layer Normalization 实现将不匹配 group size 设置为 1 的 Group Normalization 层。
参数
-1 是输入的最后一个维度。默认为 -1。beta 的偏移量添加到归一化张量。如果为 False,则忽略 beta。默认为 True。gamma。如果为 False,则不使用 gamma。当下一层是线性的(例如 nn.relu)时,可以禁用此选项,因为缩放将由下一层完成。默认为 True。gamma 权重的可选约束。默认为 None。输入形状
任意。当将此层用作模型中的第一层时,使用关键字参数 input_shape(整数元组,不包括样本轴)。
输出形状
与输入形状相同。
参考