与nn.BatchNorm类似,但也有所区别,关于nn,BatchNorm的讲解,请看:nn.BatchNorm讲解,nn.BatchNorm1d, nn.BatchNorm2d代码演示_无脑敲代码,bug漫天飞的博客-CSDN博客
BatchNorm是特征粒度,遍历批次内的样本进行归一化;
而LayerNorm是对整个输入做了归一化,是在样本粒度层面的;
不同之处在于归一化的维度不同;
但是经过nn.LayerNorm之后,数据的shape同样不会改变;
首先来看其接口文档:
CLASStorch.nn.LayerNorm(normalized_shape, eps=1e-05, elementwise_affine=True, device=None, dtype=None)
参数解释:
normalized_shape: 是要归一化的维度,比如输入为 B * S * N, B 代表batchsize大小, S 表示sentence length, N 代表每个token 的嵌入维度, 那么normalized_shape就应该是 S * N;
eps: 是在分布加的一个值,防止出现分母为0的情况;
elementwise_affine: 是否添加超参数, 进行仿射变化,是可学习的;
NLP 代码演示:
>>> # NLP example
>>> batch, sentence_length, embedding_dim = 20, 5, 10
>>> embedding = torch.randn(batch, sentence_length, embedding_dim)
>>> layer_norm = nn.LayerNorm([5,10]) # 后两个维度归一化
>>> output = layer_norm(embedding)
>>> output[0,:,:].mean() # 归一化后均值约为0
tensor(9.5367e-09, grad_fn=)
>>> output[0,:,:].std(unbiased= False) # 归一化后方差为1
tensor(1.0000, grad_fn=)
CV 代码演示:
>>> # CV example
>>> N, C, H, W = 20, 5, 10, 10
>>> input = torch.randn(N, C, H, W)
>>> layer_norm = nn.LayerNorm([C, H, W])
>>> output = layer_norm(input)
>>> output[0,:,:,:].mean()
tensor(-4.5300e-09, grad_fn=)
>>> output[0,:,:,:].std(unbiased = False)
tensor(1.0000, grad_fn=)
>>> output[0,0,:,:].std(unbiased = False)
BatchNorm 一般适用于CV领域, LayerNorm一般适用于NLP领域,至于为什么,有一篇博客讲的很清楚,大家可以参考一下:BatchNorm和LayerNorm——通俗易懂的理解_WSLGN的博客-CSDN博客_batchnorm layernorm