Transformer模型 | 个人理解

一、Transformer整体架构图

在这里插入图片描述

二、Encoder端的输入

以机器翻译任务为例子,训练数据是法语句子“Je suis etudiant”和翻译成英文后的句子“I am a student”。
Inputs是法语句子“ J e {Je } Je s u i s {suis} suis e t u d i a n t {etudiant} etudiant”,句子中的单词“Je”经过word embedding转换为嵌入向量 x 1 {x_1} x1,再加上positional embedding(位置编码向量)得到第一个Encoder block的输入向量 x 1 {x_1} x1.
句子中的每个单词都是自身嵌入向量+位置编码向量得到最终的Encoder端输入embedding.
在这里插入图片描述

三、self-attention

3.1整体来看:

每个单词的embedding 向量 x i {x_i} xi 进入self-attention,得到向量 z i {z_i} zi z i {z_i} zi再传入前馈神经网络。
在这里插入图片描述

3.2从宏观上看self-attention:

在这里插入图片描述
对于RNN来说,在生成it_单词的向量 z i {z_i} zi时,只能考虑到it_前面的那些单词。但是Transformer在Encoder端使用self-attention,可以实现在生成每个单词对应的向量 z i {z_i} zi的时候,考虑到当前句子中所有单词和它之间的关系。
这样向量 z i {z_i} zi中就包含了上下文信息。
以上面的图为例,it_单词对应的向量 z i {z_i} zi包含了句子中所有其它单词对它的影响程度(联系紧密程度),也就是在it_单词对应的embedding向量中嵌入了上下文信息。
初始的文本输入通过**word embedding转为嵌入向量+positional embedding(位置编码)**输入到第一个Encoder block,此时单词对应的embedding向量x i并没有包含整个句子的上下文信息,通过self-attention生成的向量z i就包含了整个句子的上下文信息,即句子中哪些单词对它更“重要”。

3.3从微观上看self-attention

3.3.1一个单词如何进行self-attention计算:

现在来看self-attention中每一步是怎么计算得到最后的输出向量 z i {z_i} zi
在这里插入图片描述

第一步:生成Q K V,辅助计算注意力机制
有三个权重矩阵 W Q {W^Q} WQ W K {W^K} WK W V {W^V} WV ,它们的初始值通常是通过一种随机初始化的方法来得到的,随着训练的进行,模型通过反向传播算法根据损失函数来调整权重矩阵的值,从而逐步优化模型参数。
如上图所示,对于第一个单词“Thinking”进行self-attention计算,查询向量q1是x1*权重矩阵 W Q {W^Q} WQ 得到的,键向量k1是 x 1 {x_1} x1 * 权重矩阵 W K {W^K} WK 得到的,值向量 v 1 {v_1} v1 x 1 {x_1} x1 * 权重矩阵 W V {W^V} WV 得到的。
对于句子中的每个单词,都要进行self-attention计算,得到向量 z i {z_i} zi
在这里插入图片描述
对于单词“Thinking”,进行self-attention计算(即QKV操作):
第二步:单词“Thinking”对应的embedding是 x 1 {x_1} x1,Query向量是 q 1 {q_1} q1,利用 q 1 {q_1} q1计算当前句子中所有单词的Score, q 1 ∗ k 1 {q_1*k_1} q1k1得到第一个单词的分数, q 1 ∗ k 2 {q_1*k_2} q1k2得到第二个单词的分数……,这个分数就表明在生成向量 z 1 {z_1} z1的时候要对整个句子中每个单词关注多少;
第三步:把得到的分数除以维度的平方根(这步是为了梯度更加稳定,有利于训练);
第四步:把上一步结果通过softmax函数转换为[0,1]区间内的概率分布值,目的是让差异变大,也就说当前单词“Thinking”和句子中哪些单词联系密切对应的softmax值就越大,联系越弱对应的softmax值就越小;
第五步:句子中每个单词的Value向量乘以对应的softmax分数,就是“Thinking”对应的值向量 v 1 ∗ 0.88 {v_1*0.88} v10.88,“Machines”对应的值向量 v 2 ∗ 0.12 {v_2*0.12} v20.12;
第六步:对加权后的值向量求和,即对于单词“Thinking”把整个句子中所有单词加权后的值向量求和得到 z 1 {z_1} z1 z 1 {z_1} z1就是“Thinking”的embedding嵌入 x 1 {x_1} x1在self-attention层该位置的输出。
这样,单词“Thinking”现在对应的嵌入向量 z 1 {z_1} z1就包含了该单词在整个句子中的上下文信息,这个单词和句子中其他单词之间的关系紧密程度。

用到的核心公式是:
在这里插入图片描述
这样,self-attention计算就完成了,得到的 z i {z_i} zi向量可以传递给前馈神经网络,
上面的过程是一个单词如何进行self-attention计算。

3.3.2对整个句子中的单词同时进行self-attention计算过程:

在实际模型中,为了加快计算效率,self-attention机制是通过矩阵的计算实现的:
第一步,对整个句子生成Q K V向量
在这里插入图片描述
假设句子中是2个单词, X {X} X矩阵的维度就是2*(一个embedding的维度),前面的一个14的小方格代表一个单词,这个图中的24小方格就是代表两个单词。
Q K V列上的维度是64,这是Transformer中设定的维度。
Q是当前句子的查询向量,K是当前句子的键向量,V是当前句子的值向量矩阵;
最后得到self-attention层计算得到的结果矩阵 Z {Z} Z

前面讲的一个单词经过self-attention得到向量z,可以包含该单词在整个句子中的上下文信息,包含该单词和其他单词之间联系的紧密程度。
那么这里利用矩阵经过self-attention得到矩阵 Z {Z} Z,矩阵Z中每个向量就对应了每个单词经过self-attention得到的输出 z i {z_i} zi向量。

3.3.3多头注意力机制(multi-head attention)

在Transformer中采用的是多头注意力机制(multi-head attention),
多头注意力机制可以理解为使用多种不同的Q K V,计算得到不同的self-attention结果。
为什么使用多头注意力机制?论文中给出的原因是:将模型分为多个头,形成多个子空间,让模型去关注不同方面的子信息,最后再将各个方面的信息综合起来。
在这里插入图片描述
每个头唯一的不同就是使用的权重矩阵WQ WK WV不相同,第0个头使用的权重矩阵是 W 0 Q {W_0^Q} W0Q W 0 K {W_0^K} W0K W 0 V {W_0^V} W0V ,第1个头使用的权重矩阵是 W 1 Q {W_1^Q} W1Q W 1 K {W_1^K} W1K W 1 V {W_1^V} W1V ……

Transformer中使用的是8个注意力头,会得到8个注意力计算的结果矩阵 Z 0 {Z_0} Z0 Z 7 {Z_7} Z7
注意,这里得到的8个结果矩阵都是为了计算一个句子的自注意力,
换言之,如果是计算一个单词的自注意力,这里的8个结果向量都是为了计算这一个单词的自注意力。

但是对于一个单词来说,前馈神经网络只接收self-attention该位置上的一个输出作为输出;对于一个句子来说,前馈神经网络只接收一个向量矩阵作为输入。也就是说,对于一个单词embedding向量 x i {x_i} xi来说,虽然经过多头注意力机制会得到8个向量 z 0 {z_0} z0 z 7 {z_7} z7 ,但需要把这8个向量弄成一个,作为给前馈神经网络的输入。
在这里插入图片描述
8个 Z {Z} Z矩阵合并成一个矩阵Z的方法如上图所示:
需要把 Z 0 {Z_0} Z0 Z 7 {Z_7} Z7这8个矩阵进行合并:先进行concate连接操作,再乘上权重矩阵得到最后的输出矩阵 Z {Z} Z
Z {Z} Z输入到前馈神经网络中,进行后续的计算。

整体对于一个句子的多头注意力机制过程如下图:
在这里插入图片描述
第一个编码器的输入是嵌入向量组成的矩阵 X {X} X,后边编码器的输入(矩阵 R {R} R)是前一个编码器的输出,输出的矩阵 Z {Z} Z X {X} X R {R} R的维度相同,把矩阵Z作为后面前馈神经网络的输入。

每个注意力头关注到的信息有什么不一样?

在这里插入图片描述
当只有one-head的时候,it_主要关注animal_;当有two-heads的时候,it_主要关注animal_和tire;当有all-heads的时候,比较难从图上进行解释,也反映了神经网络的可解释性比较差。

3.3.4 padding操作

前面展示的是输入一句话,但通常在训练过程中,都是采用batch的方式一次计算多句话,出现问题:不能保证每句话的长度都相同。解决办法:padding操作

在这里插入图片描述
当只输入一句话的时候,X的维度是2维的;当输入一个batch(多句话)的时候,X的维度是3维的,
每一行中灰色的部分就是padding填充的,
embedding_dimension设定的是512,X用图形化表示应该是3维,阴影的部分就代表维度512,想象一下相当于是多个二维的面叠起来构成立体的三维。
在这里插入图片描述

padding操作添加在self-attention部分,需要保证padding的操作不会影响softmax计算,所以灰色的部分填充负无穷,这样softmax计算结果是0,不会有影响。
在这里插入图片描述
在进行padding操作的时候,先得到padding 矩阵,0表示不需要填充,1表示需要填充,1乘上负无穷得到后面的矩阵,把后面这个矩阵输入到softmax中,得到score分数。
注意:padding操作不仅仅存在于编码器,只要使用batch进行计算,都需要用到。

3.4 self-attention和前馈神经网络之间的Add操作

回顾一下Transformer整体结构图,可以看到其中绿色的方块“Add&Norm”,
在这里插入图片描述
通过上面的结构图可以看到,Add操作就是把“self-attention的计算结果向量矩阵 Z {Z} Z + 输入的embedding向量矩阵 X {X} X”;
类似RestNet网络中的残差连接,起到特征增强的作用。

3.5 self-attention和前馈神经网络之间的Normalization操作

在这里插入图片描述
使用的是NLP中常用的layer norm,layer norm就是对每个样本都计算均值和方差,再对每个特征归一。
看上面的图,Self-attention层输出的向量 z {z} z,构成矩阵 Z {Z} Z 对( X {X} X+ Z {Z} Z)进行Layer Norm层归一化操作,得到新矩阵,再把矩阵中的向量输入前馈神经网络。

3.6 Encoder端的整体数据流动过程

在这里插入图片描述
这里的前馈神经网络就是一个简单的MLP(多层感知机),包括两层Linear和一个ReLU激活函数。

四、Decoder端的解码过程

4.1 整体解码过程

解码过程如上图所示,每个time step(时间步)会输出一个解码后的单词。
在这里插入图片描述在这里插入图片描述
传统的seq to seq模型的解码器部分使用的是RNN模型,

在这里插入图片描述
对于RNN模型,在训练过程中,输入t时刻的词,模型看不到未来的词,只有当模型训练结束,模型才能看到t+1时刻的词。
因为RNN是串联的,所有RNN有上面的特性。但是Transformer是并行计算的结构,所以需要添加mask操作

在这里插入图片描述

4.2 Decoder中的Masked self-attention

再来复习下Transformer的整体结构,
在这里插入图片描述
上图是Transformer训练过程的结构图,其中Decoder端的输入Outputs就是翻译的句子结果,比如翻译的句子对是<I love China , 我爱中国>,Outputs就是“我爱中国”,经过word embedding得到嵌入向量,再加上positional embedding,作为第一个Decoder block的输入,单个词对应的embedding向量和权重矩阵 W Q 、 W K 、 W V {W^Q、W^K、W^V} WQWKWV相乘得到查询向量 q {q} q,键向量 k {k} k,值向量 v {v} v。当前单词的q向量和句子中每个单词的k向量相乘得到每个单词的score。(即进行QKV计算)
在这里插入图片描述
对整个句子操作得到矩阵Scaled Scores,为了让当前时刻不看到后面的句子,采用mask操作,就是让Scaled Scores矩阵和Look-Ahead Mask相加得到最终的Masked Scores矩阵,就是把方格中对应的灰色部分数据填成负无穷,负无穷经过softmax变成0,。
在这里插入图片描述
在这里插入图片描述
就是给了解码端“我”,让它预测下一个时间步的输出“爱”,这个时候不能让模型看到“我”后面的句子“爱中国”,因为本来就是让模型去预测“我”后面的下一个字是什么,如果不进行mask操作,相当于模型已经知道“我”后面的信息是“爱中国”,这样再预测就没有意义了。
相当于 已经告诉了模型问题的答案,再让模型去学习怎么回答就没有意义了。

4.3 Decoder中的Multi-Head Attention

在这里插入图片描述
Decoder端中第一个注意力机制是Masked Multi-Head Attention,
Decoder端中第二个注意力机制Multi-Head Attention, K {K} K V {V} V来自Encoder的输出, Q {Q} Q来自上一层Masked Multi-Head Attention的输出。因为Decoder端中第二个注意力机制的 K {K} K V {V} V来自Encoder,所以这个注意力机制也被叫做Masked Encoder-Decoder Attention。

4.4 Decoder中的Linear和softmax

再来看下Transformer的整体结构
在这里插入图片描述
在这里插入图片描述
解码组件最后输出一个向量(蓝色方块表示),需要把这个输出向量变成一个单词,这就是线性变换层要做的操作,线性变换层Linear是一个简单的全连接神经网络。把解码组件产生的向量投射到一个比它自身大的多的向量中。
假设模型从训练集中学习到一万个不同的英语单词,那么线性变换层之后,向量的长度就是词表的长度_vocab_size,也就是一万。
再进行softmax操作,就得到了这一万个词每个词对应的概率,在其中选择一个概率最大的作为输出,假设下标为5的单词概率最大,就输出下标5在词表中映射的单词am。

五、Transformer的训练过程

首先建立output vocabulary(输出词表),定义词表完成后,就可以使用一个和词表长度相同的向量来表示词表中的单词。
下图词表中有6个单词,就可以使用一个维度为6的向量来表示词表中的每个单词,即为one-hot编码。
训练刚开始的时候,模型的参数都是随机生成的,模型产生的概率分布在每个单元格里赋予了随机的数值,我们可以用真实的输出来比较它。
输入是法语句子,期望的输出是“I am a student”,理想的概率分布如下图左边所示,但实际情况不可能,所以就期望通过softmax使得正确的输出对应的概率值最大。
在这里插入图片描述
优化的时候就是要优化这两个概率分布,使得它们尽可能相同,这就涉及到模型的损失函数问题,一般设置交叉熵损失,辅助模型进行反向传播。

训练结束之后,进入生成阶段,就是输入一个句子,对这个句子进行解码,一个时间步生成一个单词,得到翻译后的句子。这个时候,就设计到解码策略的问题,即怎么选择当前要输出的单词。
前面用的选择当前概率最大的词作为输出是贪婪采样策略,还有其它几种采样方式如下图:
在这里插入图片描述
贪婪采样:每个时间步选择当前概率最大的,作为输出;直到出现结束符或达到最大句子长度。
在这里插入图片描述
Beam Search:超参数集束宽度来设定每个时间步会保留几个取值路径,最后再比较这两个输出的概率大小,选择一个概率最高的,作为最终的输出。
在这里插入图片描述
基于温度系数的采样:在归一化(softmax)的过程中添加超参数t,通过改变t来控制概率分布的形状,使得分布更加均匀或集中。
在这里插入图片描述
Top-k和Top-p采样,先把词表中每个单词的概率进行降序排列,然后缩小采样范围,Top-k就是选前k个,Top-p就是词表中前多个单词的概率相加超过p,就选前多少个单词。然后再随机(真的随机)选择一个单词。
在这里插入图片描述
在这里插入图片描述

内容来自看b站视频做的笔记,加深了对Transformer架构的理解
:https://www.bilibili.com/video/BV1ng4y1K7GZ/?spm_id_from=333.1007.top_right_bar_window_history.content.click

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

失眠的树亚

你的鼓励是我最大的创作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值