2024年4月18日发(作者:)
layernorm() 函数
LayerNorm(Layer Normalization)函数,也叫层归一化,是一种用于深度神经网络
的归一化方法。它是由 Jimmy Lei Ba, Jamie Ryan Kiros 和 Geoffrey E. Hinton 在 2016
年提出的。在此之前,深度神经网络常常使用 BatchNorm(Batch Normalization)方法进
行归一化。下面将详细介绍 LayerNorm 函数的原理以及使用方法。
1.层归一化的原理
层归一化与 BatchNorm 的主要区别在于数据的统计量计算方式,BatchNorm 是以
batch 为单位,对每个 batch 中的数据点的均值和方差进行计算,再进行归一化处理。
而 LayerNorm 是以每个样本(即输入数据的每一个特征点)为单位,对这些特征点的均值
和方差进行计算,再进行归一化处理。
具体而言,假设输入的数据为 X,X 的形状为 (batch_size, num_features)。然后对
X 的每个特征点(即每个 num_features 维度上的值)求均值和标准差。我们使用下面的
公式实现 LayerNorm:
$$text{LayerNorm}(X_i) = frac{X_i - mu}{sigma + epsilon}$$
其中,$X_i$ 为第 i 个特征点,$mu$ 为均值,$sigma$ 为标准差,
$epsilon$ 为一个很小的常量以避免除以 0。这里需要注意的是,对于每个特征点而言,
它都由多个样本共同组成,因此需要对这些样本对应的特征点取平均值和方差。
接下来,我们可以对归一化后的数据进行缩放和平移,使其回到原来的范围:
其中,$gamma_i$ 是缩放因子,$beta_i$ 是偏移量。这两个参数可以学习得到。
由于 LayerNorm 是以每个样本为单位进行归一化,因此它能够传递单个样本的信息,
相对于 BatchNorm 更加适合用于处理连接紧密的循环神经网络(如 LSTM)或卷积神经网
络中的情况,可以避免 BatchNorm 由于误差累积导致输出不准确的问题。
orm 的实现
我们假设输入数据为 X,X 的形状为 (batch_size, num_features)。在计算
$mu$ 和 $sigma$ 时,我们需要对 X 的不同维度进行计算。因此,我们需要定义一个
轴来指定统计量的维度,这个轴通常是最后一个维度,即 axis=-1。不过,为了保证函数
的通用性,我们可以接受其他的轴参数。
```
def layernorm(X, gamma, beta, eps=1e-5, axis=-1):
# 在 axis 轴上计算均值和标准差
mean = (axis=axis, keepdims=True)
var = (axis=axis, keepdims=True)
# 归一化
X_normed = (X - mean) / (var + eps)
# 缩放和平移
Y = gamma * X_normed + beta
return Y, X_normed, mean, var
```
其中,X 是输入数据,gamma 和 beta 是缩放因子和偏移量,eps 是一个很小的常量
用于避免除以 0。函数的输出为归一化后的数据 $Y$,以及用于后续计算的一些中间结果
$X_{normed}$、$mu$ 和 $sigma$。
我们可以使用 PyTorch 来实现 LayerNorm。以经典的 MNIST 手写数字识别为例,下
面的代码实现了一个包含两个隐藏层的全连接神经网络,并使用 LayerNorm 进行归一
化:
```
from torch import nn
from torch import optim
from torchvision import datasets, transforms
from import DataLoader
def forward(self, x):
x = (-1, 784)
x = 1((1(x)))
x = 2((2(x)))
x = 3(x)
return x
在上面的代码中,我们首先定义了一个包含两个隐藏层的神经网络(Net 类),并使
用 LayerNorm 对每个隐藏层进行归一化。然后,我们使用 PyTorch 自带的 MNIST 数据
集进行训练。在输出层,我们使用交叉熵作为损失函数。最后,我们使用 Adam 优化器对
网络进行训练。
在训练结束后,我们可以使用 PyTorch 内置的测试函数对网络进行测试,代码如下
所示:
在使用 LayerNorm 进行归一化的情况下,经过 10 个 epoch 的训练,准确率能够达
到 0.98 左右。


发布评论