LayerNorm
(Layer Normalization)是一种常用的归一化技术,用于神经网络模型中的层级归一化操作。它在每个样本的每个特征维度上进行归一化,使得每个特征的均值为0,方差为1,从而有助于提高模型的训练效果和泛化能力
LN是针对自然语言处理领域提出的,例如像RNN循环神经网络
与 Batch Normalization (批归一化)既有相似之处又有不同:从公式上看,都是减去均值除以标准差,也存在两个可训练的参数 gamma 和 beta
但是,BN 是对一个 batch 数据的每个 channel 进行 Norm 处理,LN是对单个数据的指定维度进行Norm处理,与batch无关。而且在BN训练时需要累计moving_mean和moving_var两个变量,LN不需要累计
所以说,,LayerNorm
是在每个样本的特征维度上进行归一化,而不是在批次维度上。这意味着在LayerNorm
中,每个样本都有自己的均值和方差
用法:
torch.nn.LayerNorm(normalized_shape,eps=1e-05,elementwise_affine=True)
其中,参数normalized_shape可以指定想要Norm的维度,但是指定的维度必须是要从最后一维开始的,比如:数据的shape是[4,2,3],那么normalized_shape可以是[3](最后一维上进行Norm处理) ,也可以是[2,3](Norm最后两个维度),也可以是 [4,2,3] (对整个维度进行Norm),但是不能是[2] 或[4,2],否则会报错
实现:
import torch
import torch.nn as nn
def layer_norm_process(feature:torch.Tensor,beta=0,gamma=1,eps=1e-5):
var_mean = torch.var_mean(feature,dim=-1,unbiased=False)
# 均值
mean = var_mean[1]
# 方差
std = var_mean[0]
# layer norm process
feature = (feature - mean[...,None]) / torch.sqrt(var[...,None] + eps)
feature = feature * gamma + beta
return feature
调用:
def main():
t = torch.rand(4,2,3)
# 仅在最后一个维度上做norm处理
# 调用官方实现的layerNorm
norm = nn.LayerNorm(normalized_shape = t.shape[-1],eps=1e-5)
t1 = norm(t)
# 上述自定义的LayerNorm处理
t2 = layer_norm_process(t,eps=1e-5)
print("t1:\n",t1)
print("t2:\n",t2)
if __name__ = '__main__':
main()
代码中的 t.shape[-1] 指的是数据的最后一个维度
注意:beta最初初始化为 0,gamma最初初始化为1,这两个参数后面通过训练慢慢学习得到
优点:
- 不依赖于批次大小,因此在训练和推理阶段都可以使用
- 在处理小批次数据时,相比于BN批归一化,
LayerNorm
更稳定 - 由于每个样本都有自己的均值和方差,可以更好地适应不同样本之间的差异