目录
0.Transformer介绍
1.self-attention 和Multi-heads self-attention
1.1 self-attention(自注意力机制)
1.2 Multi-heads self-attention(多头自注意力机制)
2.网络结构
2.1 encoder(编码器)
2.2 decoder(解码器)
2.3 Position-wise Feed-Forward Networks(FFN)
2.4 Positional Encoding(位置编码)
2.5 Add&Norm
3. 参考博文
0.Transformer介绍
2017年Vaswani等人在发表的《Attention Is All You Need》中提出Transformer模型,是第一个完全依靠自注意力计算其输入和输出的模型,从此在自然语言处理领域中被广泛使用。
论文名称:《Attention Is All You Need》
论文地址:https://arxiv.org/abs/1706.03762
Transformer是一个典型的Seq2Seq模型,Seq2Seq模型的核心思想是将一个序列(如文本)编码成一个固定大小的向量表示,然后解码成另一个序列。这种模型通常包括一个编码器和一个解码器,分别负责将输入序列编码成隐藏表示和将隐藏表示解码成输出序列。因此,Transformer遵循这种整体架构,encoder和decoder都使用堆叠的self-attention和Feed Forward NN(前向传播层),如下图所示:
1.self-attention 和Multi-heads self-attention
1.1 self-attention(自注意力机制)
注意力机制可以描述为将一个query-key-value映射到一个输出的过程,其中query、key、value和输出都是向量。输出计算为value的加权和,其中分配给每个值的权重由query和相应的key进行函数计算得出。Attention计算公式如下图所示:
1)初始化生成qkv:
以下图为例,输入为三个节点a1、a2、a3,通过embedding层,将输入的三个数据转换为向量x1,x2,x3,紧接着对三个节点的向量与权重矩阵Wq、Wk、Wv(这三个参数是可训练的,是共享的)进行计算得到qi,ki,vi,如下图所示。(其中q代表query,后续会去和每一个k进行匹配;
k代表key,后续会被每个q匹配;v代表从输入向量x中提取到的信息)
2)计算相关性分数score:
self-attention的第二步便是计算相关性分数score,为Attention计算公式中部分。分数是通过查询向量(Queries)与我们正在评分的相应单词的键向量(keys)的点积计算得出的,表征两个向量的相关程度大小,值越大,相关程度越大。
点积运算公式:
在计算score中,qi逐个与ki进行点积运算,得出score值。例如q1与k1,k2,k3分别进行得出三个score值。
3)对score进行缩放并进行归一化处理:
在原文中指出,在进行点乘后的值很大,导致通过softmax后的梯度会变得很小,因此文中采用缩放操作,使模型训练时的梯度更加稳定。缩放操作便是Attention计算公式中除以,其中为输入的q的维度,原文中为64,因此进行开平方后为8。
在对score值进行缩放后,使用Softmax 对分数进行归一化处理,使它们都为正且加起来为 1,相当于计算得到针对每个v的权重,softmax 分数决定了每个词在句子中某个位置的重要性。
4)进行每个单词重要程度重分配:
将每个值向量(values)乘以对应的 softmax 分数,目的是做每个单词重要程度的重分配,即Attention公式中softmax乘V的部分,计算后的值即为Attention的值。例如,词“a1”经过self-attention处理后的输出为 0.70 x v1 + 0.18 x v2+ 0.12 x v3,即当前这句话经过self-attention处理后,词“a1”的含义包含了70%的自身含义和18%的下一词"a2"的含义和12%的下一词"a3"的含义,这样处理就体现了文本上下文的关系。
5)总结:
在实际计算时,我们会将输入的词向量x1、x2、x3及经过权重矩阵的得到的Q、K、V都拼接成矩阵进行运算,以便更快地处理。如上图所示,Q、K和V是输入矩阵,分别代表查询矩阵、键矩阵和值矩阵,dk是向量维度。这个公式的作用是通过对Q和K的相似度进行加权,来得到对应于输入的V的加权和,得到注意力机制的输出矩阵。
1.2 Multi-heads self-attention(多头自注意力机制)
作者在文中指出多头注意力允许模型在不同位置共同关注来自不同表征子空间的信息。在单个注意头的情况下,平均化抑制了这一点。
因此,在实际使用中,基本使用的时多头注意力机制(Multi-heads Attention)。如下所示为多头自注意力的表达式:
对于多头注意力,我们有多组查询向量(Queries)、键向量(keys)和值向量(values),这里把一组q, k, v 向量称之为一个头,将得到的每个head得到的结果进行concat拼接操作,并将拼接后的结果乘以一个额外的权重矩阵 (可学习的参数)进行融合,融合后得到最终的结果矩阵。
在论文中使用八个注意力头,每组注意力头中的参数都是可训练的,经过训练可以扩展模型关注输入数据不同位置的能力。八个注意力头会分别生成八个输出结果,但实际上我们只需要一个输出结果。 所以我们需要一种方法将这八个输出压缩成一个矩阵。方法也很简单,将它们乘以一个额外的权重矩阵 即可,这个操作可以简单的经过一个神经网络层的映射即可,如下图所示:
2.网络结构
2.1 encoder(编码器)
编码器是负责把输入信息编码成特征向量的算法组件,这个输入信息根据不同的任务而不同,可是是文本也可以是图像,但文本和图像本身不能直接输入编码器,必须把它们向量化(Embedding)成向量才能送入编码器。
编码器主要是将输入序列转换为一个固定长度的向量,Transformer 中 Encoder 由 6 个相同的层组成,每个层包含 2 个部分:
1)Multi-Head Self-Attention(多头自注意力层)
2)Feed-Forward Neural Network (前向传播层)
在encoder模块中,编码器的自注意力层周围有一个残差连接,然后是Layer Norm层归一化操作,归一化的输出再通过前馈网络FNN中(forward neural network)进行映射以进行进一步处理。前馈网络本质上就是几层神经网络层,中间有 ReLU 激活,两层之间也有残差链接,如下2.3章节所述的MLP block。
网络中,残差连接可以帮助梯度的反向传播,让模型更快更好的收敛。层归一化用于稳定网络,减轻深度学习模型数值传递不稳定的问题。
2.2 decoder(解码器)
解码器是服务于生成任务的,如果是判别任务,可以没有解码器结构。解码器需要对编码器的输出结果进行翻译解释,生成我们想要的目标序列。
解码器用于将编码器生成的向量生成输出序列,Decoder 也是由 6 个相同的层组成,每个层包含 3 个部分:
1)Masked Multi-Head Atttention(掩码多头子注意力层)
与Encoder的Multi-Head Attention计算原理一样,只是多加了一个mask码。Transformer 中的掩码(masking)机制用于防止模型在处理序列时访问不应该访问的信息,模型里面涉及两种 mask,分别是 padding mask 和 sequence mask。
a.padding mask
在自然语言处理任务中,为了将不同长度的句子输入到模型中,我们通常需要对较短的句子进行填充,使其与最长句子的长度相同。填充通常使用特殊的符号(如 <pad>)表示。
填充掩码的目的是在自注意力计算过程中忽略这些填充位置。这样做是因为这些填充符号实际上并不携带任何有意义的信息,我们不希望它们影响其他单词之间的注意力权重计算。填充掩码通过将填充位置对应的注意力 logits 设置为一个非常大的负数来实现。这样,在应用 softmax 函数时,填充位置对应的注意力权重会接近于零。
b.sequence mask
sequence mask 是为了使得 decoder 不能看见未来的信息。对于一个序列,在 time_step 为 t 的时刻,我们的解码输出应该只能依赖于 t 时刻之前的输出,而不能依赖 t 之后的输出。因此我们需要想一个办法,把 t 之后的信息给隐藏起来。这在训练的时候有效,因为训练的时候每次我们是将target数据完整输入进decoder中地,预测时不需要,预测的时候我们只能得到前一时刻预测出的输出。
sequence mask 通过在注意力 logits 矩阵中添加一个下三角矩阵(其上三角部分为负无穷)来实现。这样,在应用 softmax 函数时,当前位置之后的单词对应的注意力权重将接近于零。这使得解码器在每个时间步只能关注当前及之前的单词。
c.总结
填充掩码用于忽略填充符号的影响,而序列掩码确保解码器在生成过程中遵循自回归原则。通过掩码,我们可以使模型在处理序列时更加稳定、可靠。在Encoder中的Multi-Head Attention也是需要进行mask地,只不过Encoder中只需要padding mask即可,而Decoder中需要padding mask和sequence mask。
2)Encoder-Decoder Multi-Head Attention(多头编码-解码子注意力层)
Encoder中的Multi-Head Attention是基于Self-Attention地,Decoder中的第二个Multi-Head Attention就只是基于Attention,它的输入Quer来自于Masked Multi-Head Attention的输出,Keys和Values来自于Encoder中最后一层的输出。
3)Feed Forward NN(前向传播层)
同encoder中的相同,采用MLP模块进行实现,如2.3章节所示。
decoder在最终的输出时,首先经过一次线性变换,然后Softmax得到输出的概率分布,通过词典匹配,输出概率最大的对应的单词作为我们的预测输出。
2.3 Position-wise Feed-Forward Networks(FFN)
在Transformer中,Feed Forward(FNN)层是一个MLP,它在自注意力机制之后对序列中的每个向量单独应用,FFN层的表达式如下所示:
MLP Block由两个全连接层和一个非线性激活函数(如 ReLU 或 GELU)组成,第一个全连接层会将输入的结点个数扩大4倍,因为在最后的输出中有残差连接,所以第二个全连接层会还原回输入的节点个数,如下图所示:
2.4 Positional Encoding(位置编码)
在self-attention的计算机制中,并没有考虑到位置信息,我们希望将输入序列的每个元素信息进行标识,所以在encoder和decoder的输入阶段,进行Positional Encoding。位置编码是一种表示序列中每个位置信息的向量。位置编码的维度与输入向量的维度相同,这样我们可以将它们逐元素相加,从而保留位置信息。
位置编码可以是固定的(如基于正弦和余弦函数的编码),也可以是可学习的(通过训练得到的向量)。在Transformer原论文中,作者使用了基于正弦和余弦函数的固定位置编码,对于一个给定位置 pos 和编码维度 i,位置编码的计算公式如下:
其中,PE(i,2k)和PE(i,2k+1)是位置编码矩阵中第i行第2k和2k+1列的值,d是输入向量的维度。通过这个公式,我们可以为输入序列中的每个位置生成一个位置编码向量,该向量具有一定的模式,能够表示该位置在序列中的位置信息。
为了将位置编码添加到输入序列中,我们可以将输入序列中的每个词语向量与对应位置编码向量相加,得到包含位置信息的输入向量,如下图所示:
2.5 Add&Norm
1.Add
Add,就是在经过计算后的结果的基础上加了一个残差块,加入残差块的目的是为了防止在深度神经网络训练中发生退化问题,退化的意思就是深度神经网络通过增加网络的层数,Loss逐渐减小,然后趋于稳定达到饱和,然后再继续增加网络层数,Loss反而增大。
2.Norm
在神经网络进行训练之前,都需要对于输入数据进行Normalize归一化,目的有:
1.能够加快训练的速度。
2.提高训练的稳定性。
Transformer中使用Layer Normalization进行归一化操作,因为在原始的论文中,transformer应用于NLP领域,layer_norm针对的是文本的长度,整条序列的文本,效果要比batch_norm好。
Batch Normalization 的处理对象是对一批样本, Layer Normalization 的处理对象是单个样本。Batch Normalization 是对这批样本的同一维度特征做归一化, Layer Normalization 是对这单个样本的所有维度特征做归一化。
3. 参考博文
1.Encoder-Decoder_qq_47537678的博客-CSDN博客
2.编码器-解码器模型 - 魔法学院小学弟
3. 变形金刚(Transformer) - 魔法学院小学弟
4. 详解Transformer中Self-Attention以及Multi-Head Attention_太阳花的小绿豆 transformer_太阳花的小绿豆的博客-CSDN博客
5.batchNormalization与layerNormalization的区别 - 知乎
6. 史上最小白之Transformer详解_Stink1995的博客-CSDN博客