文章目录
一、前言
冻结 Batch Normalization 层(BN 层)是深度学习训练过程中常用的一种技巧,特别是在迁移学习或 微调(fine-tuning) 时。冻结 BN 层意味着在训练过程中不更新 BN 层的参数(如均值、方差、缩放和偏移参数)。
二、BN 层的基本工作原理
Batch Normalization 的作用是对每个 mini-batch 内的数据进行归一化,使其均值接近 0,方差接近 1。它有以下参数:
-
可学习参数:
- γ(缩放参数)
- β(偏移参数)
-
统计参数:
- running_mean(滑动平均均值)
- running_var(滑动平均方差)
在训练过程中:
- BN 层会计算每个 mini-batch 的均值和方差,并更新全局的 running_mean 和 running_var。
- 同时,γ 和 β 也会参与梯度更新。
三、冻结 BN 层的作用
- 稳定训练过程
- 在小批量数据或微调阶段: BN 层对每个 batch 计算统计量(均值、方差),但如果 batch size 很小,这些统计量可能不稳定,导致模型训练波动较大。冻结 BN 层可以防止这种不稳定。
- 保持原有模型的统计信息
- 在迁移学习中: 预训练模型的 BN 层已经在大规模数据集上学习到了较好的 running_mean 和 running_var。冻结它们可以保留这些信息,避免在新的小数据集上被破坏。
- 减少计算开销
- 冻结 BN 层意味着在前向传播时,不需要重新计算新的均值和方差。这在训练时可以提高计算效率。
- 防止过拟合
- 在某些场景中,BN 层的动态调整可能导致模型对当前数据集过于敏感,冻结它们可以减少过拟合风险。
四、冻结 BN 层的方法
在 PyTorch 中,你可以通过以下方法冻结 BN 层:
def freeze_bn(model):
for layer in model.modules():
if isinstance(layer, nn.BatchNorm2d) or isinstance(layer, nn.BatchNorm1d):
layer.eval() # 切换到 eval 模式,固定 running_mean 和 running_var
for param in layer.parameters():
param.requires_grad = False # 冻结 γ 和 β
在调用训练循环之前,运行 freeze_bn(model) 就能冻结所有 BN 层。
五、总结
冻结 BN 层的主要作用是提高训练稳定性、保持预训练统计信息,特别适合小数据集或微调场景。这种策略有助于防止 BN 层在新数据上产生不稳定的统计信息,从而保持模型的泛化能力。
附录:对于LayerNorm层(一般不冻结,仅对比了解)
1. LayerNorm(层归一化)冻结的作用与区别
LayerNorm 基本原理:
Layer Normalization(层归一化)对输入数据的每个样本进行归一化,而不是像 Batch Normalization(BN)那样对整个 mini-batch 归一化。
- 计算过程: 对每个样本(在每个通道维度)计算均值和方差,并对其进行归一化:
LayerNorm ( x ) = γ x − μ σ + ϵ + β \text{LayerNorm}(x) = \gamma \frac{x - \mu}{\sigma + \epsilon} + \beta LayerNorm(x)=γσ+ϵx−μ+β
其中:
- μ \mu μ 和 σ \sigma σ 是单个样本在通道维度上的均值和标准差。
- γ \gamma γ 和 β \beta β 是可学习的缩放和偏移参数。
LayerNorm 与 BatchNorm 的主要区别:
-
归一化维度不同:
- BN: 对每个 mini-batch 的每个通道进行归一化,依赖 batch size。
- LN: 对每个样本独立归一化,不受 batch size 影响。
-
应用场景不同:
- BN: 通常用于卷积神经网络(CNN)。
- LN: 常用于自然语言处理(NLP)和 Transformer 结构中,尤其在处理可变长序列时效果显著。
2. 冻结 LayerNorm 的作用
- 稳定训练过程
- 在一些微调任务中,预训练模型的 LayerNorm 参数(如 gamma 和 beta)已经很好地适应了特定分布。冻结它们可以保持这种归一化效果,防止在新数据上出现不稳定的变化。
- 保持预训练模型的特性
- 对于 Transformer 模型(如 BERT、ViT),LayerNorm 在预训练阶段对特定数据分布进行了优化。冻结这些层可以防止在小数据集上微调时破坏预训练的效果。
- 减少计算开销
- LayerNorm 的计算量较小,但冻结参数可以略微减少梯度更新的开销,特别是在大模型上。
- 防止过拟合
- 冻结 LayerNorm 的参数可以减少模型对当前数据集的过度调整,从而提高泛化能力。
3. 如何冻结 LayerNorm 层
在 PyTorch 中,可以冻结 LayerNorm 层的参数如下:
def freeze_layernorm(model):
for layer in model.modules():
if isinstance(layer, nn.LayerNorm):
layer.eval() # 切换到 eval 模式(不影响 LayerNorm,但统一规范)
for param in layer.parameters():
param.requires_grad = False # 冻结 γ 和 β
与 BatchNorm 的区别:
- BatchNorm: 冻结 running_mean 和 running_var,避免小 batch size 的统计波动。
- LayerNorm: 没有全局统计量(如 running_mean),只冻结 γ 和 β,通常更稳定,特别是在 NLP 中。
4. 总结
- 一般不冻结 LayerNorm,尤其是在微调 Transformer 或 NLP 模型时。
LayerNorm 在适应新数据方面表现稳定,冻结它可能会限制模型调整特征分布的能力。 - BN 冻结较常见,LN 冻结较少见。
只有在小数据集、计算资源受限或特定实验需求下,才可能考虑冻结 LayerNorm。