Transformer于2017年提出,最开始应用于NLP领域,随着Transformer的快速发展,在视觉领域中也越来越多的论文或应用用到了Transformer,这里记录一下自己学习的一些知识点。
PDF: 《Attention Is All You Need》
Code: attention-is-all-you-need-pytorch
一、前置知识
1.1 注意力机制
Transformer内部采用自注意力机制,注意力机制介绍可参考:https://www.cnblogs.com/xiaxuexiaoab/p/18302563
1.2 LayerNorm
不同于图像领域采用BatchNorm,NLP中每个样本的时序数据长度可能不一致,所以LayerNorm在文本处理中更常用,每个样本自己算均值和方差。LayerNorm可参考:https://www.cnblogs.com/xiaxuexiaoab/p/18325271
1.3 位置编码
将位置信息附加到原有词向量上,Transformer中采用的是正余弦函数计算绝对位置编码,更多的位置编码方式可以参考:https://0809zheng.github.io/2022/07/01/posencode.html
二、Transformer
首先对Transformer进行一个简单的认识,直接来一张论文原图。Transformer采用Encoder-Decoder架构,包含Input、Encoder、Decoder、Output几部分,其中Encoder由N个相同的模块按顺序组成,模块里面包含多头注意力、残差连接、LayerNorm以及前向推理等小模块;Decoder也由N个相同的模块组成,如果把中间一个红色子模块遮挡住(后续会介绍,先简单理解成一个模)就和Encoder一致了。
至此心里应该有个大体框架,接下来我们在进一步介绍Input、Encoder、Decoder、Output四个部分。
2.1 Input
原始输入的是句子或者一段语音,经过编码后得到词向量Input Embedding(可以编为OneHot编码,或者采用Word2Vec编码)。再通过位置编码得到位置向量Positional Encoding,最后将位置信息和原始词向量进行相加,实现位置信息附加到词向量上,能增加额外的位置信息,进而帮助模型更好地理解输入的顺序。
位置编码
论文中按照上式计算出绝对位置编码,其中pos表示词的索引,d表示词向量的维度,奇数位采用余弦值,偶数位采用正弦值。更多的编码方式可以参考:位置编码
两边输入的区别
左边Encoder的输入和上面说的一致,就是原始信息的词向量 + 位置编码。
右边是Outputs向右偏移作为输入是咋回事呢? 就是右边Decoder的输出依赖于前一个输出值。举个语音识别的例子应该就清楚了。
左边原始信息是一段语音(真实意思是机器学习),右边经过符号位BEGIN后预测得到第一概率最大的词为“机”,那么预测值“机”又会作为下一个预测时的输入,依此类推不断向右偏移,直到预测结束。
2.2 Encoder
论文中N设为6,也就是Encoder采用6个相同的模块,第一个模块词向量+位置编码作为输入,经过Multi—Head Attention后输出维度和输入一致,然后在把输出与输入通过残差连接在一起并对其进行LayerNorm,之后经过前向网络后再进行一次残差连接和LayerNorm,第二个模块以第一个模块的输出作为输入,依此类推,第6个模块的输出作为最终Encoder的输出。
Multi-Head Attention
Self Attention是考虑了所有输入向量的信息,其作用相当于权重的重新分配(输入向量越相关其对应的权重越大),输出向量数量和输入向量数量保持一致。可以参考self Attention
论文中采用的是多头注意力,就是几个注意力进行拼接,做的一点修改是除了一个key的维度。
其输出可以用下式表达:
Add & Norm
这里的Add是指残差连接,最先出现在ResNet,可以有效防止网络退化。
Norm是指LayerNorm
Feed Forward
有两个线性层组成,两个线性层之间加入ReLU激活函数。
2.3 Decoder
论文中N也是设为6,这里和Encoder不同的地方在于第一个子模块中多头注意力出现了Mask,第二个子模块中嵌入了Encoder的输出,第三个子模块和Encoder中一样。
Masked Multi-Head Attention
前面分析了Decoder的输入依赖于前一个节点的输出,因此这里不像Encoder那样可以看到所有输入信息,而是只能看到之前的信息,所以引入Mask来遮挡住后面的数值,即如果对第i个节点进行处理,这把第i个以后的输入全部不考虑(置为0即可)。
Encoder怎么和Decoder模块连接
第二个子模块连接了Encoder的输出,具体而言就是将Encoder的输出经过矩阵后生成相应的K和V,然后Decoder中子模块的输出作为Q,中间在按照注意力进行进行连接输出。这种也称作Cross Attention。还是以之前语音识别的例子来展示。
cross attention可以参考:Listen, attend and spell: A neural network for large vocabulary conversational speech recognition 以及Cross Attention Source of image
2.4 Output
这个就想对简单了,Decoder的输出经过一个线性层得到的特征向量再通过softmax激活函数得到输出的概率值。
三、相关细节
3.1 如何知道预测的长度
前面分析了Decoder的预测依赖于前面的输出,可以像一个序列一样一直延伸下去,那问题点在于在不知道结果的情况下如何确定输出的长度。通常有两种方式。
- 通过网络预测一个输出长度
- 给定一个上限值,再忽略掉END标志位之后的输出
第一种通常需要引入额外的网络对输出长度进行预测,这里还是以之前语音识别的例子讲下第二种,引入END标志位,当预测的标志位概率最大时停止。
3.2 训练和推理
主要区别在于训练时OutPuts是采用的真实结果,而推理时采用的是真实的预测值作为下一个的输入。那这就出现了一个问题:推理时不知道真实输出,训练采用真实输出,如何处理这中间的差异,换句话就是训练看到的是全对的,而预测有可能错,预测错一个对后续会有影响?
一个措施是采用Scheduled Sampling,也就是在训练的时候人为加入一些噪音。更多内容可以参考:
3.3 并行化体现在哪里
采用自注意力机制相比于RNN一个优点是可以并行化处理数据,那这里并行化又如何体现了,Encoder里面一次性输入全部句子,所以不管训练还是推理都可以并行,但是在Decoder部分推理依赖于前面的输出,所以推理时Decoder是没办法并行处理的,而训练时采用正常值作为输入,借助Masked可以实现并行。
- Encoder: 训练和推理都可以并行
- Decoder: 训练时可以并行,推理时不能并行
3.3 位置编码还有哪些
位置编码的作用是将位置信息附加到原有词向量之上,提供模型额外的位置信息。
参考Transformer中的位置编码(Position Encoding)还有更多的位置编码方式。
四、参考资料
Self Attention
LayerNorm
位置编码
李宏毅 Transformer