Transformer模型

1.1.整体架构

1.2.Attention背景

    机器翻译是从RNN开始跨入神经网络的,主要分:

  • Simple RNN

  • Contextualize RNN

  • Contextualized RNN with attention

  • Transformer

1.2.1.Simple RNN

    在这个编码-解码模型中,编码器将整个源序列压缩成一个向量(Encoder Output),源端信息和解码器之间唯一的联系为:压缩后的这个向量(Encoder Output)会作为解码器的初始状态(Initial State)输入,它带来的问题:随着解码器长度的增加,该向量(Encoder Output)的信息会出现衰减

    这种模型的两个问题

  1. 源端序列不论长短都会被压缩成一个固定维度向量,而这个向量中关于源端序列末尾的token信息更多,如果序列很长,最终可能“遗忘”了向量中开始部分的token信息。

  2. 随着Decoder TimeStep信息增加,初始隐藏状态(Initial Hidden State)中包含Encoder Output相关信息会衰减,而解码器会“遗忘”源端序列信息,而更多地关注目标序列在timestep之前的token信息。

1.2.2.Contextualize RNN

    为解决上述两个问题(Encoder Output随Decoder TimeStep增加而衰减),提出了加入context的序列到序列RNN模型(RNN sequence to sequence),解码器在每个TimeStep的输入上都加上一个context上下文,于是在解码器执行的每一步时,都把源端的整个句子信息和目标端当前的token一起输入到RNN中,防止源端context信息随着TimeStep的增长而衰减。

    这种模型的问题

  • context对于每个TimeStep都是静态的(解码器端的最终隐藏状态, Final Hidden States,或是所有TimeStep的输出平均值),但每个解码器端的token在解码时用到的context真是一致的么?

1.2.3.Contextualize RNN with Soft Align(Attention)

    在每个TimeStep输入到解码器的RNN结构中之前,都会用当前的输入token的向量(vector)和Encoder Output中每一个位置的向量vector作一个Attention操作,这个操作的目的是计算当前token和每个位置之间的相关度,从而决定每个位置的向量在最终TimeStep的context中占的比重有多少,最终再加权平均:

att(q,X)=i=1NαiXiatt(q,X) = \sum\limits_{i=1}^N \alpha_i X_i

1.3.注意力机制

1.3.1.点积Attention

    注意力机制可以有不同的计算方式:

  • 加性Attention

  • 点积Attention

  • 带参数的计算公式

    点积Attention计算方式如:

Attention(Q,K,V)=softmax(QKTdk)VAttention(Q,K,V) = softmax(\frac{QK^T}{\sqrt{d_k}})V

    上图中,QM×dQ_{M \times d}KN×dK_{N \times d}分别是querykey,其中,query可看做M个维度为d的向量拼接,key可以看做N个维度为d的向量拼接而成。表达式中的1dk\frac{1}{\sqrt{d_k}}是缩放因子,它的作用是做归一化

1.3.2.参数

    一个完整的Attention层涉及的参数有:

  • q,k,vq, k, v分别映射到Q,K,VQ, K, V的线性变换矩阵WQ(dmodel×dk),WK(dmodel×dk),WV(dmodel×dv)W^Q(d_{model} \times d_k), W^K(d_{model} \times d_k), W^V ( d_{model} \times d_v )

  • 把输出的表达OO映射为最终输出oo的线性变换矩阵WO(dv×dmodel)W^O ( d_v \times d_{model} )

1.3.3.Query,Key,Value

    Query和Key的作用得到的Attention权值作用到Value上,它们之前的关系如:

  • Query(M×dqk)Query(M \times d_{qk})Key(N×dqk)Key(N \times d_{qk})的维度必须一致,Value(N×dv)Value(N \times d_v)和Query/Key的维度可以不一致。

  • Key(N×dqkKey(N \times d_{qk}Value(N×dv)Value(N \times d_v)的长度必须一致,Key和Value本质上对应同一个Sequence在不同空间的表达。

  • Attention得到的Output(M×dv)Output(M \times d_v)的维度和Value的维度一致,长度和Query一致。

  • Output每个位置i是由value的所有位置的向量vector加权平均之后的向量,而其权重是由位置为i的query和key的所有位置经过Attention计算后得到的,权值的个数等于key/value的长度。

    在经典的Transformer结构中,假设线性映射之前的Query, Key, Valueq,k,v,映射之后的Q,K,V,那么:

  1. Self-Attentionq,k,v都是同一个输入,即当前序列上一层输出的高维表达。

  2. Cross-Attentionq代表当前序列,k,v是同一个输入,对应的是编码器最后一层的输出结果(对解码器每一层来说,保持不变)。

    底层捕获的更多信息是Lexical-Level级别的,而高层捕获的更多则是Semantic-Level的关系。

1.3.4.Attention的作用

    query对应的是需要被表达的序列(称为序列A),keyvalue对应的是原来表达A的序列(称为序列B),其中keyquery是在同一高维空间中,value不用在同一高维空间中,最终生成的outputvalue在同一高维空间中。

序列A和序列B在高维空间α\alpha中的高维表达AαA_{\alpha}的每个位置分别和BαB_{\alpha}计算相似度,产生的权重作用于序列B在高维空间β\beta的高维表达BβB_{\beta},获得序列A在高维空间β\beta中的高维表达AβA_{\beta}

    所以编码部分只存在于Self-Attention,而解码部分存在Self-AttentionCross-Attention

  • Self-Attention:编码中的Self-Attentionquery,key,value对应了源端序列(A和B是同一序列),解码器中的Self-Attentionquery,key,value都对应了目标端序列。

  • Cross-Attention:编码器中的Cross-Attentionquery对应了目标端序列,key,value对应了源端序列(每一层中的Cross-Attention用的都是编码器的最终输出)。

1.3.5.解码器Decoder端的Mask

    Transformer模型属于自回归模型,也就是说后面的token推断是基于前边的token的,解码器端的Mask的功能是为了保证训练阶段和推理阶段的一致性。推理阶段,token按照从左到右的顺序推理,即,在推理TimeStep=T的token时,解码器只能“看到”TimeStep < T的 T - 1个token,不能和TimeStep大于自身的token做Attention运算。为保证训练和推理的一致性,训练时要防止token和它之后的token做Attention运算。

1.3.6.多头Attention

    多头Attention(Multi-Head Attention)。Attention是将querykey映射到同一高维空间中计算相似度,而多头Attention会把querykey映射到高维空间α\alpha的不同子空间中(α1,α2,...,αh)(\alpha_1, \alpha_2,...,\alpha_h)中计算相似度。

不改变参数数量的情况下增强每一层的Attention的表现力

    参数总量保持不变的情况下,同样的query,key,value映射到原来的高维空间的不同子空间中执行Attention计算,最后一步合并不同子空间的Attention信息。

1.4.Transformer模型其他

1.4.1.Feed Forward Network

    每一层经过了Attention运算之后,会有一个FFN,这个FFN的目标就是做空间变换,它包含了2层Linear Transformation层,中间激活函数使用ReLU。

    FFN加入引入了非线性变换(ReLU激活函数),交换了Attention Output空间,从而增加模型表现力,如果去掉,模型效果会差很多。

1.4.2.Positional Encoding

    位置编码层(Positional Encoding)存在于编码端(Encoder)和解码端(Decoder)的embedding之后,第一个Block之前,它十分重要,若没有这部分,Transformer模型就无法使用,它补充了Attention机制本身不能捕捉位置信息的缺陷。

PE(pos,2i)=sin(pos/100002i/dmodel)PE(pos,2i) = sin(pos / 10000^{2i/d_{model}})

PE(pos,2i+1)=cos(pos/100002i/dmodel)PE(pos,2i + 1) = cos(pos / 10000^{2i/d_{model}})

    Positional Embedding成分直接叠加到Embedding之上,使得每个token的位置信息和它的语义信息(Embedding)充分融合,并被传递到后续所有经过复杂变换的序列表达中去。

优势1

  • 模型输入编码器(Encoder)的每个token对应的向量有2部分:

    • Positional Encoding

    • Embedding Output

  • Transformer的特性使得编码器(Encoder)的输入向量之间完全平等(不存在类似RNN中recurrent结构),token的实际位置和positional encoding唯一绑定,可通过对positional encoding进行操作来改变token在序列中的实际位置。

  • 对inference阶段而言(参考下图)

    • 图b中输入的Embedding部分没有变化,但Positional Encoding部分被打乱了顺序。

    • 图c中的Positional Encoding部分没有变化,但Embedding部分被打乱了顺序。

    • 其实两个图是完全等价的。

  • 对train阶段而言(Learned Positional Encoding)

    • 由于Positinal Encoding是迅联出来的,那么它在inference阶段代表哪个位置,完全由训练时的实际位置决定

    • 例:在解码器中,Cross-Attention模块有Mask,目的是防止token和它之后的token执行Attention运算,即从左到右的模型,倘若此时突然想要从右到左的模型

      • 在预处理阶段将序列翻转过来

      • 在训练时将Mask策略换一下

优势2

    原始论文中的Positional Encoding(PE)是正余弦函数,位置(pos)越小,波长越长,每一个位置对应的PE都是唯一的,使用正余弦函数作为PE,是因为这个可以使得模型学习到token之间的相对位置关系:对于任一偏移量kPEpos+kPE_{pos + k}可以由PEposPE_{pos}的线性表示。

PE(pos+k,2i)=sin((pos+k)/100002i/dmodel)PE(pos+k,2i) = sin((pos + k)/ 10000^{2i/d_{model}})

PE(pos+k,2i+1)=cos((pos+k)/100002i/dmodel)PE(pos+k,2i + 1) = cos((pos + k) / 10000^{2i/d_{model}})

    上述两个公式由前一项的线性组合得到,即通过某个线性变换矩阵就从k得到了k+1

1.4.3.Layer Normalization

    在每个Block中,最后出现的就是层归一化(Layer Normalization),这个是一个通用技术,其本质是规范化优化空间,加速收敛。

    为了保证特征分布的稳定性(左),可加入Layer Normalization,这样可以加速模型的优化速度。

最后更新于

这有帮助吗?