Transformer解释
Transformer解释
小游Transformer解释
Transformer定义
Transformer是一种用于自然语言处理(NLP)和其他序列到序列(sequence-to-sequence)任务的深度学习模型架构,它在2017年由Vaswani等人首次提出。Transformer架构引入了自注意力机制(self-attention mechanism),这是一个关键的创新,使其在处理序列数据时表现出色。
以下是Transformer的一些重要组成部分和特点
- 自注意力机制(Self-Attention):这是Transformer的核心概念之一,它使模型能够同时考虑输入序列中的所有位置,而不是像循环神经网络(RNN)或卷积神经网络(CNN)一样逐步处理。自注意力机制允许模型根据输入序列中的不同部分来赋予不同的注意权重,从而更好地捕捉语义关系。
- 多头注意力(Multi-Head Attention):Transformer中的自注意力机制被扩展为多个注意力头,每个头可以学习不同的注意权重,以更好地捕捉不同类型的关系。多头注意力允许模型并行处理不同的信息子空间。
- 堆叠层(Stacked Layers):Transformer通常由多个相同的编码器和解码器层堆叠而成。这些堆叠的层有助于模型学习复杂的特征表示和语义。
- 位置编码(Positional Encoding):由于Transformer没有内置的序列位置信息,它需要额外的位置编码来表达输入序列中单词的位置顺序。
- 残差连接和层归一化(Residual Connections and Layer Normalization):这些技术有助于减轻训练过程中的梯度消失和爆炸问题,使模型更容易训练。
- 编码器和解码器:Transformer通常包括一个编码器用于处理输入序列和一个解码器用于生成输出序列,这使其适用于序列到序列的任务,如机器翻译。
Transformer的结构
Nx = 6,Encoder block由6个encoder堆叠而成,图中的一个框代表的是一个encoder的内部结构,一个Encoder是由Multi-Head Attention和全连接神经网络Feed Forward Network构成。如下图所示:
简略结构(每一个编码器都对应上图的一个encoder结构):
Transformer的编码组件是由6个编码器叠加在一起组成的,解码器同样如此。所有的编码器在结构上是相同的,但是它们之间并没有共享参数。编码器的简略结构如下:
从编码器输入的句子首先会经过一个自注意力层,这一层帮助编码器在对每个单词编码的时候时刻关注句子的其它单词。解码器中的解码注意力层的作用是关注输入句子的相关部分,类似于seq2seq的注意力。原结构中使用到的是多头注意力机制(Multi-Head Attention),我们先从基础——自注意力机制开始讲起
自注意力机制(Self-Attention)
参考文章一文搞定自注意力机制(Self-Attention)-CSDN博客
参考视频通俗易懂理解自注意力机制(Self-Attention)-哔哩哔哩
自注意力机制(Self-Attention)作为注意力机制中的一种,也被称为intra Attention(内部Attention),是大名鼎鼎的Transformer重要组成部分
Self-Attention的概念
Self-Attention,自注意力机制,又称内部注意力机制,顾名思义,是一种将单个序列的不同位置关联起来以计算同一序列的表示的注意机制。
通过对注意力机制的学习我们知道,在一般任务的Encoder-Decoder框架中,输入Source和输出Target内容是不一样的,比如对于英-中机器翻译来说,Source是英文句子,Target是对应的翻译出的中文句子,Attention机制发生在Target的元素Query和Source中的所有元素之间(即Attention机制与自身还有关注对象都有关系)。
而Self-Attention顾名思义,指的不是Target和Source之间的Attention机制,而是Source内部元素之间或者Target内部元素之间发生的Attention机制,也可以理解为Target=Source这种特殊情况下的注意力计算机制。(即Self-Attention只关注输入本身or只关注关注对象本身)
关于自注意力机制对比CNN
计算步骤
Self-Attention的作用
引入Self Attention
会更容易捕获句子中长距离的相互依赖的特征,因为如果是RNN
或者LSTM
,需要依次序序列计算,对于远距离的相互依赖的特征,要经过若干时间步步骤的信息累积才能将两者联系起来,而距离越远,有效捕获的可能性越小。
但是Self Attention在计算过程中会直接将句子中任意两个单词的联系通过一个计算步骤直接联系起来,所以远距离依赖特征之间的距离被极大缩短,有利于有效地利用这些特征。除此外,Self Attention对于增加计算的并行性也有直接帮助作用。这是为何Self Attention逐渐被广泛使用的主要原因。
Self-Attention的问题
关于多头注意力机制
因为一段文字可能蕴含了比如情感维度、时间维度、逻辑维度等很多维度的特征,为了能从不同的维度抓住输入信息的重点,chatGPT
使用了多头注意力机制(multi-head attention)。
而所谓多头注意力,简单说就是把输入序列投影为多组不同的Query,Key,Value,并行分别计算后,再把各组计算的结果合并作为最终的结果。
这是一张论文原文中的多头注意力机制的架构(Multi-Head Attention),可以看到(V,K,Q)三个矩阵通过h个线性变换(Linear),分别得到h组(V,K,Q)矩阵,每一组(V,K,Q)经过Attention计算,得到h个Attention Score并进行拼接(Concat),最后通过一个线性变换得到输出,其维度与输入词向量的维度一致,其中h就是多头注意力机制的“头数”。
多头注意力机制的代码实现没有详细看
下图为更直观的表示论文中的计算过程,以输入词“X=[‘图’, ’书’, ’馆’]”为例,句子长度为3,词向量的维度为4,这里将词向量分为2个头,线性变换后得到2组(V0,K0,Q0)和(V1,K1,Q1),每组(V,K,Q)进行Self-Attention计算得到两个Score即(Z0和Z1),将Z0和Z1进行拼接Concat后进行线性变换得到输出向量Z,其维度与输入矩阵维度相同。
下图是代码实现的过程,不同于论文,代码中对(V,K,Q)进行一次线性变换,然后在特征维度上进行h次分割(在代码中就是通过矩阵转置transpose和维度变换torch.view)后得到h组(V,K,Q),分别计算Self-Attention Score后进行Concat拼接(同样的通过一系列的transpose和torch.view),最后通过线性变换得到最后的输出。
使用位置编码表示序列的顺序
为了理解单词顺序,Transformer为每个输入的词嵌入添加了一个向量,这样能够更好的表达词与词之间的关系。
为了让模型理解单词的顺序,我们添加了位置编码向量,这些向量的值遵循特定的模式。
Add&Normalize
在经过多头注意力机制得到矩阵Z之后,并没有直接传入全连接神经网络,而是经过了一步Add&Normalize。
Add & Norm 层由 Add 和 Norm 两部分组成,其计算公式如下
其中 X表示 Multi-Head Attention 或者 Feed Forward 的输入,MultiHeadAttention(X) 和 FeedForward(X) 表示输出 (输出与输入 X 维度是一样的,所以可以相加)。
- Add
Add,就是在z的基础上加了一个残差块X,加入残差块的目的是为了防止在深度神经网络的训练过程中发生退化的问题,退化的意思就是深度神经网络通过增加网络的层数,Loss逐渐减小,然后趋于稳定达到饱和,然后再继续增加网络层数,Loss反而增大。
- ResNet残差神经网络
为了了解残差块,我们引入ResNet残差神经网络,神经网络退化指的是在达到最优网络层数之后,神经网络还在继续训练导致Loss增大,对于多余的层,我们需要保证多出来的网络进行恒等映射。只有进行了恒等映射之后才能保证这多出来的神经网络不会影响到模型的效果。残差连接主要是为了防止网络退化。上图就是构造的一个残差块,X是输入值,F(X)是经过第一层线性变换后并且激活的输出,在第二层线性变化之后,激活之前,F(X)加入了这一层输入值X,然后再进行激活后输出。
要恒等映射,我们只需要让F(X)=0就可以了。x经过线性变换(随机初始化权重一般偏向于0),输出值明显会偏向于0,而且经过激活函数Relu会将负数变为0,过滤了负数的影响。
这样当网络自己决定哪些网络层为冗余层时,使用ResNet的网络很大程度上解决了学习恒等映射的问题,用学习残差F(x)=0更新该冗余层的参数来代替学习h(x)=x更新冗余层的参数。
Normalize
归一化目的:
1、加快训练速度
2、提高训练的稳定性
使用到的归一化方法是Layer Normalization。LN是在同一个样本中不同神经元之间进行归一化,而BN是在同一个batch中不同样本之间的同一位置的神经元之间进行归一化。
BN是对于相同的维度进行归一化,但是咱们NLP中输入的都是词向量,一个300维的词向量,单独去分析它的每一维是没有意义地,在每一维上进行归一化也是适合地,因此这里选用的是LN。
全连接层Feed Forward
全连接层是一个两层的神经网络,先线性变换,然后ReLU非线性,再线性变换。
这两层网络就是为了将输入的Z映射到更加高维的空间中然后通过非线性函数ReLU进行筛选,筛选完后再变回原来的维度。
经过6个encoder后输入到decoder中。
Decoder整体结构
和Encoder Block一样,Decoder也是由6个decoder堆叠而成的,Nx=6。包含两个 Multi-Head Attention 层。
第一个 Multi-Head Attention 层采用了 Masked 操作。
第二个 Multi-Head Attention 层的K, V矩阵使用 Encoder 的编码信息矩阵C进行计算,而Q使用上一个 Decoder block 的输出计算。
Masked Multi-Head Attention
与Encoder的Multi-Head Attention计算原理一样,只是多加了一个mask码。mask 表示掩码,它对某些值进行掩盖,使其在参数更新时不产生效果。Transformer 模型里面涉及两种 mask,分别是 padding mask 和 sequence mask。为什么需要添加这两种mask码呢?
padding mask
什么是 padding mask 呢?因为每个批次输入序列长度是不一样的也就是说,我们要对输入序列进行对齐。具体来说,就是给在较短的序列后面填充 0。但是如果输入的序列太长,则是截取左边的内容,把多余的直接舍弃。因为这些填充的位置,其实是没什么意义的,所以我们的attention机制不应该把注意力放在这些位置上,所以我们需要进行一些处理。
具体的做法是,把这些位置的值加上一个非常大的负数(负无穷),这样的话,经过 softmax,这些位置的概率就会接近0!
sequence mask
sequence mask 是为了使得 decoder 不能看见未来的信息。对于一个序列,在 time_step 为 t 的时刻,我们的解码输出应该只能依赖于 t 时刻之前的输出,而不能依赖 t 之后的输出。因此我们需要想一个办法,把 t 之后的信息给隐藏起来。这在训练的时候有效,因为训练的时候每次我们是将target数据完整输入进decoder中地,预测时不需要,预测的时候我们只能得到前一时刻预测出的输出。
那么具体怎么做呢?也很简单:产生一个上三角矩阵,上三角的值全为0。把这个矩阵作用在每一个序列上,就可以达到我们的目的。
注意:
- 在Encoder中的Multi-Head Attention也是需要进行mask的,只不过Encoder中只需要padding mask即可,而Decoder中需要padding mask和sequence mask
- Encoder中的Multi-Head Attention是基于Self-Attention地,Decoder中的第二个Multi-Head Attention就只是基于Attention,它的输入Quer来自于Masked Multi-Head Attention的输出,Keys和Values来自于Encoder中最后一层的输出。
输出
Output如图中所示,首先经过一次线性变换,然后Softmax得到输出的概率分布(softmax层会把向量变成概率),然后通过词典,输出概率最大的对应的单词作为我们的预测输出。
线性变换层是一个简单的全连接神经网络,它可以把解码组件产生的向量投射到一个比它大得多的,被称为对数几率的向量里
transformer的优缺点
优点:
1、效果好
2、可以并行训练,速度快
3、很好的解决了长距离依赖的问题
缺点:
完全基于self-attention,对于词语位置之间的信息有一定的丢失,虽然加入了positional encoding来解决这个问题,但也还存在着可以优化的地方。