Transformer技术详细介绍! |
文章目录
- 一. 整体结构图
- 二. 输入部分
- 2.1. 词向量
- 2.2. 位置编码
- 三. 注意力机制
- 3.1. 注意力机制的本质
- 3.2. 举例说明
- 3.3. Transformer中的注意力
- 四. 残差和layerNormal
- 4.1. Layer Normalization
- 五. 前馈神经网络
- 六. Decoder
- 6.1. 掩盖多头注意力机制
- 6.2. 交互层
- 七. 参考
一. 整体结构图
- TRM在做一个什么事情?
- 细化
- 再细化
- 原论文图:
- 单个Encoder可以分为如下3个部分:
二. 输入部分
- 首先说输入部分: 1. Embedding;2. 位置嵌入。 两者相加,如下图所示
2.1. 词向量
- 例如:下面的4个英文单词,经过Word2Vec分别得到的词向量长度是4。
- 再比如 :输入是
我爱你......12个字
,我按字切分,每个字定义一个512维度的字向量(原论文就是512),对于字向量这里可以使用Word2Vec或者随机初始化 [如果数据量非常大,这2个差别不大,可以忽略]
。下面的词向量长度就是512。
2.2. 位置编码
- 可以参考大佬的文章:Sinusoidal 位置编码追根溯源:https://wmathor.com/index.php/archives/1541/
- 苏剑林大佬的文章:Transformer升级之路-Sinusoidal位置编码追根溯源:https://www.spaces.ac.cn/archives/8231
- 不同于RNN、CNN等模型,对于Transformer模型来说,位置编码的加入是必不可少的,因为纯粹的Attention模块是无法捕捉输入顺序的,即无法区分不同位置的Token。让研究人员绞尽脑汁的Transformer位置编码
- 从RNN说下为什么需要位置编码,对于RNN的一个共识,但是很多人会忽略。RNN的参数U,输入参数W,隐层参数V,输出参数。这是一套参数,所有RNN的time steps都共享一套参数(例如有100个词,100个字都是一套参数)。为了更好的理解,按照时间线展开,比如输入我爱你。RNN这种展开的结构,天然的时序关系很符合的,先处理某些东西,后处理某些东西。但是对于Transformer来讲,看刚才的图,多头注意力机制那里,处理的时候是可以并行的,一句话所有单词可以同时处理。不是像RNN输入一个我等处理完我再处理爱…。Transformer是一起处理的,这样做增快了速度,但是忽略了单词之间的序列关系,或者说先后关系。
- 所以Transformer相比于RNN就缺少了某种东西,告诉模型某些我是在前面的,你是在后面的,爱是在中间的。
- 原论文位置编码公式:如何理解呢?pos单词或者字的位置
代表偶数位,
。它如果针对512个维度的位置编码(下图)。
![]()
- 其中 pos表示某个词在句子序列中的实际位置,也可以理解为某个token,
表示词向量的第
,
是位置向量的维度
- 由于
以及
,这表明位置
的向量可以表示成位置
和位置
- 得到上面的位置编码之后: 我们将位置编码512维度和词向量512维度或者字向量512维度相加,得到的结果作为最终Transformer的输入。
- 这里还想引申一下为什么位置嵌入会有用, 公式2可以利用三角函数的性质得到公式3。注意看公式3,我们依第1行为例,比如pos位置代表我,pos+k代表你,k代表爱。也就是我爱你中的你可以用pos我和k爱两者线性组合起来,这样的线性组合意味着位置向量中蕴含了相对位置信息。但还有一个注意的点,这种相对位置信息会在注意力机制那里消失。
三. 注意力机制
3.1. 注意力机制的本质
- Transformer原论文中注意力机制的公式:
- 其中
是3个矩阵(向量),首先
先做一个点乘,softmax经过之后得到的是一个相似度的向量,再乘以
3.2. 举例说明
- 举例子说明: 首先query和key做点乘(这里说一下为什么做点乘,其实做相似度计算有3种方式:点乘、MLP多层网络、余弦相似度)。单独说一下点乘,它反应的是一个向量在另一个向量上投影的长度,
,也就是两个向量越相似它的点乘结果就越大。
- 这里例子中婴儿和左上、左下、右上、右下点乘之后,要判断是婴儿和这4个区域哪一个点乘结果越大,说明越相似,就是越关注。
- NLP中的例子: 这里输入的Query是爱,输入的是我不爱你4个key1、key2、key3、key4向量,Value1、Value2、Value3、Value4是对应的向量。
- 具体如下:首先计算query爱和我、不、爱、你4个key向量计算F函数(就是刚才说的3种相似性方法,这里是点乘)、得到结果s1、s2、s3、s4,然后做一个softmax函数归一化,得到a1、a2、a3、a4,它们结果是相似度,比如0.7、0.1、0.1、0.1,结果相加为1。
- 注意看value上面的箭头,先和a相乘,再相加一起得到attention value。
3.3. Transformer中的注意力
- 比如现在Thinking和Machines两个词,对应的向量是
和
,当然是加上位置编码之后的向量(4维)。如何获取到
乘以一个
的矩阵得到
;
乘以一个
的矩阵得到
;
以一个
的矩阵得到
:
其中每个词的Embedding 的维度为
(也就是这里的4),每个注意力头的输出维度为
(也就是这里的3)。
- 同理:使用的是同一套参数,相应的
- 为了并行化处理: 用矩阵
表示向量
按行组成的矩阵,维度是
(下图中
)。
- 在上述变换基础上进行如下计算,得到输入中 每个词和自身及其他词之间的关系权重:
- 计算相似度,得到attention值。 得到
这3个矩阵之后,计算
的相似性,得到score,然后除以
(为什么要除以它呢?
相乘之后得到的值非常大,值很大的情况下,softmax在反向传播的过程中梯度很小,容易发生梯度消失的现象。除以
)
- 因此有
,该矩阵表示输入数据中每个词和自身及其他词的关系权重,每一行的得分之和为1。基于该得分即可得到,每个词在当前上下文下的新的向量表示,公式如下:
- 得到向量
向量之后,它会被送到Encoder的下一个模块,即前馈神经网络,这个全连接有2层,第一层的激活函数是ReLU,第二层是一个线性激活函数,可以表示为:
- 实际操作中使用矩阵的运算,方便并行,计算速度更快! 还有一个细节点,在实际操作叫多头,这里我们只用了一套参数
、
、
。多头其实就是用了多套参数,分别得到各自的
,如下图2,多了一套参数。 可以这样理解,多头注意力机制相当于把原始信息打到不同的空间(不一套参数)。
- 多个头就会有多个输出,最后需要合在一起输出,如下面是2个头。
- 多头注意力机制: 相当于
个不同的自注意力的集成(ensemble)(如上图中2个,下图中8个),在这里我们以
举例说明。多头注意力机制的输出分成3步:
- ① 将数据
分别输入到下图所示的8个自注意力的中,得到8个加权后的特征矩阵
。
- ② 将8个
按列拼成一个大的特征矩阵
,可以看下面第二个图;
- ③ 特征矩阵经过 一层全连接 后得到最终输出
,其中
。
- 具体多头注意力机制全过程如下:
- 注意: 同self-attention一样,multi-head attention也加入了short-cut机制。
四. 残差和layerNormal
- 首先说一下 残差和LayerNormal 大致情况。首先看输入
和
代表词向量,然后碰到位置编码进行对位相加,得到新的
和
,然后经过self-attention层得到输出结果
和
,现在将
和
变为一个矩阵
,将原始输入直接拿过来变为
,然后和
4.1. Layer Normalization
- 经典的面试题:为什么这里使用Layer Normalization而不是Batch Normalization?
- NLP中所有任务不止Transformer,大家很少用BN,基本都用LN操作。
- 说一下BN操作,特征处理的时候Feature scaling就是为了消除量纲的影响,使模型收敛的更快。李宏毅老师课件链接
- BN理解的重点在于:针对整个batch中的样本同一纬度进行处理。 下图中
- 所以做BN的时候很容易理解,但是如果BN用在NLP中有一个很大的问题。
- BN的优点:
- 第一个就是可以解决内部协变量偏移。
- 第二个优点就是缓解了梯度饱和问题(如果使用sigmoid激活函数的话),加快收敛。
- BN的缺点:
- 第一个,batch_size较小的时候,效果差(这个batch中计算出来的均值和方差不能代表全部数据的均值和方差)。
- 第二个,缺点就是 BN 在RNN中效果比较差。这一点和第一点原因很类似,不过我单挑出来说。
- 第二个的例子:一个batch长度为10,前9个样本的句子长度是5个单词,1个样本的句子长度是20个单词,那么我再输入的时候,前5个单词的均值和方差可以用10个样本计算出来,但是第6个单词到第20个单词的均值和方差怎么计算呢?前9个没有,只有最后一个有。回到了第一个问题中batch很小的时候,效果很差,这就是BN在RNN中效果不好的原因。RNN的输入是动态的。
- 为什么使用layer-norm? 比如还是上面例子,最后1个句子是20个单词,LN做的就是针对这20个单词进行缩放,去做它的均值和方差。而BN做的是针对第一1行单词做方差,第2行单词做方差。
- 理解:为什么LayerNorm单独对一个样本的所有单词做缩放可以起到效果。
- 看下面这张图:同一个位置的做均值和方差,比如我和今做方差,ai和天做方差,默认假设我和今代表同样的语义信息,ai和天代表同样的语音信息。大家想想是不是这样,看上面的图BN的时候,身高做方差,体重做方差,都是代表相同的语音信息。而LN做的是针对所有单词我爱中国共产党所有单词做均值和方差,它的假设是我爱中国共产党在同一个语义信息里。也可以这样理解,在获取我爱中国共产党这个句向量的时候,一个常规的做法是做加权词向量,加权词向量基本假设认为我爱中国共产党这句话中的所有词是在一个语义信息里面的,所以才认为是可以理解的。
五. 前馈神经网络
- 前馈神经网络就是这个图中最上面的,这里是两层的全连接,然后再过一个残差和Normalization。以上所有的都是Encoder的过程。
- 如果我们可视化向量、layer-norm以及前馈神经网络操作,将如下所示:
- 在解码器中也是如此,假设两层编码器+两层解码器组成Transformer,其结构如下:
- 注意(下面也有介绍,这里强调一下):在解码器中,Transformer block比编码器中多了个Encoder-Decoder Attention。在Encoder-Decoder Attention中,
来自于解码器的上一个输出,
和
六. Decoder
- 现在我们已经了解了编码器侧的大部分概念,也基本了解了解码器的工作方式,下面看下他们是如何共同工作的。
- 编码器从输入序列的处理开始,最后的编码器的输出被转换为
和
,它俩被每个解码器的"Encoder-Decoder Atttention"层来使用,帮助解码器集中于输入序列的合适位置。看上一节中的图。
- 下面的步骤一直重复直到一个特殊符号出现表示解码器完成了翻译输出。每一步的输出被喂到下一个解码器中。正如编码器的输入所做的处理,对解码器的输入增加位置向量。
- 下面是Decoder部分,重点讲解一下1(掩盖多头注意力机制)和2(交互层,比encoder多了1层)两部分。
6.1. 掩盖多头注意力机制
- 由于在机器翻译中,解码过程是一个顺序操作的过程,也就是当解码第
个特征向量时,我们只能看到第
及其之前的解码结果,论文中把这种情况下的注意力机制叫做 掩盖多头注意力机制(masked multi-head attention)。
- 从代码层面上讲,需要对当前单词和之后的单词做mask,都抹掉,不让看到。
- 为什么需要mask?举例:看下面S代表输入的开始start,真正的句子的I love you now。
输入,输出
,然后做一个teacher for thing,把
作为下一个时刻的输入得到
,依次,…,这是一个机器翻译的过程。 为什么需要mask? 输入
的时候,输出的是
,如果decoder的输入是没有mask,只是经过和Encoder一样的,那么从 Start 的
6.2. 交互层
- 从图中可以看到这是一个典型的多头注意力机制,是怎么操作的呢?看下图:所有encoder输出和每一个Decoder做交互。
- 具体交互操作看下图:比如现在有2个encoder,输出的这个值得到
,一定要注意Encoder生成的是
矩阵,Decoder生成的是
,多头注意力机制一定有
三个矩阵,在交互的时候利用
- 再简单梳理一下整个过程,虚线代表
矩阵的输出,看下面这条在第一个decoder中在做多头注意力机制的时候,和Decoder中的
七. 参考
- 主要参考dasou博主的视频:https://www.bilibili.com/video/BV1Ey4y1874y?p=6&spm_id_from=pageDriver
- 国外大神,精美图分析,英文:https://jalammar.github.io/illustrated-transformer/
- 国外大神,精美图分析
- Transformer论文 + PyTorch源码解读: https://www.pianshen.com/article/3013330708/
- 详解Transformer (Attention Is All You Need):https://zhuanlan.zhihu.com/p/48508221