讨论一下为什么transformer中用layer norm
前序知识:常见的归一化层的工作原理 常见的norm
之前已经讲过各个常见的归一化层了,不了解的可以去看看这篇文章。
首先咱们得了解在NLP中,如果输入的几个句子不是等长的,需要使用Padding技术或者Truncation技术来使句子等长。因此对于短文本来说,为了对齐长句子,剩下的位置会被填充零向量,即 [0, 0, 0, ..., 0]。它对应的vector可能是这样用“0值”padding后的结果
因此对于文本来说,这些embedding是没有意义的。
Transformer 中选择使用 Layer Normalization(LN)而非 Batch Normalization(BN)的原因有以下几点:
1. 根本差异
BN 对一个批次中维度进行归一化,这意味着在 NLP 模型中,同一批次中的句子不同 token 的特征被归一化到相同的分布。然而,批次中的 token 可能是填充位或无意义的片段,因此,对它们进行统一归一化会影响有意义的特征。相比之下,Layer Normalization 只对每个样本的特征维度进行归一化,使每个句子内部的特征分布稳定,而不受其他样本影响。
2. 适用于mini batch和变长序列
在 NLP 任务中,批次大小往往较小,特别是动态的 RNN 或 BERT 等模型中,句子长度不一致会导致批次的缩小。小批次情况下,BN 的效果会变差,因为它依赖批次内的统计信息。LN 独立于批次大小,适合小批次、变长序列等场景,因此更加稳定。
3. 隐藏层维度的归一化
Layer Normalization 更关注单个样本中不同特征之间的分布一致性,而在 NLP 任务中,我们希望同一句话的分布稳定。BN 通过对同一特征在批次内归一化,适合图像等任务,但对 NLP 中变动较大的语言特征来说,LN 的效果更合适。
4. 正则化效果
Layer Normalization 也能提供正则化效果,尤其在小批次和 RNN 中表现更好,使模型收敛更稳定,适用于 Transformer 中的多头注意力和自注意力机制
举例说明
假如我们有2个句子,每个句子分别有3个单词,每个单词的维度是4
对数据使用层归一化计算时,层归一化只会作用在行上也就是每个单词的维度上。
其中句子的大小(2)与序列长度(3)这两个维度都不会对norm有影响
所以这个会执行6次LN
输出结果如下
if __name__ == '__main__':
x = torch.tensor([
[
[0.5, -1.2, 0.3, 2.4],
[1.0,1.0,1.0,1.0],
[2.0,2.0,2.0,2.0],
],
[
[1.3, -0.7, 2.2, -0.1],
[0.4, -0.5, 1.0, -1.4],
[0.2, 1.7, -0.9, 1.8]
]
])
LN = nn.LayerNorm(normalized_shape=4)
print(LN(x))
# 输出如下
# tensor([[[-4.6614e-08, -1.3295e+00, -1.5641e-01, 1.4859e+00],
# [ 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00],
# [ 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00]],
#
# [[ 5.4776e-01, -1.2051e+00, 1.3365e+00, -6.7923e-01],
# [ 5.7735e-01, -4.1239e-01, 1.2372e+00, -1.4021e+00],
# [-4.4632e-01, 8.9264e-01, -1.4282e+00, 9.8190e-01]]],
# grad_fn=<NativeLayerNormBackward0>)
结果表明单词和单词直接不会有任何影响
这就是最根本原因!
标签:Transformer,01,00,批次,layer,归一化,0.0000,句子,norm From: https://blog.csdn.net/wlxsp/article/details/143451177思考题:
看实验中的数据有两行是完全一样的数据,他们归一化后的结果都是0,请问如何来分辨出原始激活值的特征差异呢???
评论区回答