本页面提供了 labml_nn 仓库中实现的归一化技术的概述。归一化层是深度神经网络中必不可少的组件,通过控制层输入的分布来帮助稳定和加速训练。本文档涵盖了批量归一化 (Batch Normalization) 和层归一化 (Layer Normalization) 的实现细节、数学基础和使用模式。
归一化技术解决了内部协变量偏移的问题——即网络激活分布在训练过程中随网络参数更新而变化的现象。通过稳定这些分布,归一化层改善了梯度流动,并能以更高的学习率实现更快的训练。
来源: labml_nn/normalization/batch_norm/__init__.py14-27 labml_nn/normalization/layer_norm/__init__.py10-34
批量归一化 (BatchNorm) 对批次维度上的激活进行归一化,确保每个层的输入在整个训练过程中具有一致的分布。
BatchNorm 通过对每个特征独立地进行归一化来解决内部协变量偏移问题,使其在小批次中具有零均值和单位方差。对于给定特征,归一化计算公式为:
$$\hat{x}^{(k)} = \frac{x^{(k)} - \mathbb{E}[x^{(k)}]}{\sqrt{Var[x^{(k)}] + \epsilon}}$$
其中
归一化后,输出使用可学习参数进行缩放和偏移
$$y^{(k)} = \gamma^{(k)} \hat{x}^{(k)} + \beta^{(k)}$$
其中
这些参数允许网络在必要时恢复原始表示。
来源: labml_nn/normalization/batch_norm/__init__.py29-89
BatchNorm 类实现了批量归一化,包含以下关键组件:
主要参数
channels: 特征/通道的数量eps: 用于数值稳定的小常数momentum: 指数移动平均的参数affine: 是否使用可学习的缩放和偏移参数track_running_stats: 是否跟踪运行均值和方差在训练期间,均值和方差是从小批次中计算出来的。该实现还维护均值和方差的指数移动平均值以供推理。归一化是在批次维度上执行的,对于 4D 输入(如图像),也在高度和宽度维度上执行。
来源: labml_nn/normalization/batch_norm/__init__.py103-207
根据输入形状,BatchNorm 在不同维度上进行归一化
对于 4D 输入 (B × C × H × W) - 在批次、高度和宽度维度上进行归一化:$$\text{BN}(X) = \gamma \frac{X - \underset{B, H, W}{\mathbb{E}}[X]}{\sqrt{\underset{B, H, W}{Var}[X] + \epsilon}} + \beta$$
对于 2D 输入 (B × C) - 在批次维度上进行归一化:$$\text{BN}(X) = \gamma \frac{X - \underset{B}{\mathbb{E}}[X]}{\sqrt{\underset{B}{Var}[X] + \epsilon}} + \beta$$
对于 3D 输入 (B × C × L) - 在批次和序列长度维度上进行归一化:$$\text{BN}(X) = \gamma \frac{X - \underset{B, L}{\mathbb{E}}[X]}{\sqrt{\underset{B, L}{Var}[X] + \epsilon}} + \beta$$
来源: labml_nn/normalization/batch_norm/__init__.py107-128
层归一化 (LayerNorm) 通过对特征维度而不是批次维度进行归一化,解决了 BatchNorm 的一些局限性。
BatchNorm 存在一些局限性
层归一化提供了一种更简单的替代方案,适用于更广泛的设置。
来源: labml_nn/normalization/layer_norm/__init__.py13-29
LayerNorm 类实现了层归一化,其结构如下:
主要参数
normalized_shape: 元素的形状(批次除外)eps: 用于数值稳定的小常数elementwise_affine: 是否使用可学习的逐元素缩放和偏移参数与 BatchNorm 不同,LayerNorm 为每个样本独立地计算特征维度上的均值和方差。这使其更适用于小批次大小或可变序列长度的场景,这在自然语言处理 (NLP) 任务中很常见。
来源: labml_nn/normalization/layer_norm/__init__.py43-131
根据输入形状,LayerNorm 在不同维度上进行归一化
对于 2D 输入 (B × C) - 在特征维度上进行归一化:$$\text{LN}(X) = \gamma \frac{X - \underset{C}{\mathbb{E}}[X]}{\sqrt{\underset{C}{Var}[X] + \epsilon}} + \beta$$
对于 3D 输入 (L × B × C) - 在特征维度上进行归一化:$$\text{LN}(X) = \gamma \frac{X - \underset{C}{\mathbb{E}}[X]}{\sqrt{\underset{C}{Var}[X] + \epsilon}} + \beta$$
对于 4D 输入 (B × C × H × W) - 在特征、高度和宽度维度上进行归一化:$$\text{LN}(X) = \gamma \frac{X - \underset{C, H, W}{\mathbb{E}}[X]}{\sqrt{\underset{C, H, W}{Var}[X] + \epsilon}} + \beta$$
来源: labml_nn/normalization/layer_norm/__init__.py47-69
下图说明了 BatchNorm 和 LayerNorm 在归一化维度上的主要区别
来源: labml_nn/normalization/batch_norm/__init__.py107-128 labml_nn/normalization/layer_norm/__init__.py47-69
下图展示了两种归一化技术的实现架构
来源: labml_nn/normalization/batch_norm/__init__.py103-207 labml_nn/normalization/layer_norm/__init__.py43-131
归一化层通常放置在线性层或卷积层之后、激活函数之前。下图说明了一种常见的模式
.train() 或 .eval() 以在训练和推理模式之间切换。来源: labml_nn/normalization/batch_norm/__init__.py74-90
来源: labml_nn/normalization/layer_norm/__init__.py30-34
| 归一化 | 典型应用 | 优点 | 局限性 |
|---|---|---|---|
| BatchNorm | CNN、视觉任务 | - 减少内部协变量偏移 - 在视觉任务中应用广泛且效果良好 - 使网络对初始化不那么敏感 | - 需要运行统计数据 - 在小批次中效果不佳 - 在分布式设置中复杂 |
| LayerNorm | RNN、Transformer、NLP 任务 | - 在小批次中表现良好 - 对于序列的实现更简单 - 无需运行统计数据 | - 可能不适用于所有 CNN 架构 |
来源: labml_nn/normalization/batch_norm/__init__.py9-94 labml_nn/normalization/layer_norm/__init__.py9-34
BatchNorm 和 LayerNorm 都是稳定神经网络训练的重要技术。虽然 BatchNorm 在批次维度上进行归一化,并且一直是视觉任务中的主导选择,但 LayerNorm 在特征维度上进行归一化,并已成为自然语言处理 (NLP) 任务(尤其是在 Transformer 架构中)的标准。理解它们的区别和适当的使用场景对于设计高效的神经网络至关重要。
此仓库中的实现提供了两种技术的清晰、带注释的实现,可以进行研究以理解其内部工作原理。