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
)
层归一化层 (Ba 等人,2016)。
独立地对每个批次中的给定示例进行前一层激活的归一化,而不是像批归一化那样跨批次进行归一化。即应用一个转换,使每个示例内的平均激活值接近 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)
请注意,对于层归一化,归一化发生在每个示例中的轴 *内*,而不是跨批次中的不同示例。
如果启用了 scale
或 center
,则该层将通过将归一化输出与可训练变量 gamma
进行广播来缩放归一化输出,并通过与可训练变量 beta
进行广播来使输出居中。gamma
将默认为一个全为 1 的张量,而 beta
将默认为一个全为 0 的张量,这样在训练开始之前,居中和缩放都是无操作的。
因此,在启用缩放和居中时,归一化方程如下所示
令小批次的中间激活为 inputs
。
对于 inputs
中具有 k
个特征的每个样本 x_i
,我们计算样本的均值和方差
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
将跨越 inputs
中 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
。例如,组归一化 (Wu 等人,2018),其组大小为 1,对应于一个跨高度、宽度和通道进行归一化的层归一化,并且 gamma
和 beta
仅跨越通道维度。因此,此层归一化实现将与组大小设置为 1 的组归一化层不匹配。
参数
-1
是输入中的最后一个维度。默认为 -1
。beta
的偏移量添加到归一化张量中。如果为 False,则忽略 beta
。默认为 True
。gamma
。如果为 False,则不使用 gamma
。当下一层是线性层(例如 nn.relu
)时,可以禁用此选项,因为缩放将由下一层完成。默认为 True
。输入形状
任意。在将此层用作模型中的第一层时,使用关键字参数 input_shape
(整数元组,不包括样本轴)。
输出形状
与输入形状相同。
参考文献