以下内容主要是本人对transformer模型的学习总结和知识梳理,以便更清晰的理解该模型。
transformer是google于2017年提出的模型架构,论文地址:https://arxiv.org/abs/1706.03762
本文先给出模型的整体架构,然后按数据流的输入顺序解读每一个模块。
Transformer相比于RNN,最大的优点是输入序列可并行训练,大大缩短训练周期。
Transformer的Embedding由两部分组成,分别为word embedding和position encoding。
同其它模型一样,transformer的word emebdding层将输入token转换为 d m o d e l d_{model} dmodel维词向量。在解码时,同样对输出先进行线性变换,再进行softmax归一化,得到下一个词的概率分布。
不同的是,transformer模型的word embedding层和pre-softmax层之间的权重参数是共享的,这样做可以有效减少模型参数量。我们知道embedding层和pre-softmax层的参数大小是vocab_size *embedding_dim,而且通常vocab_size比embedding_dim高两个数量级,因此,共享参数能显著减少模型参数量。
Transformer采用Positional Encoding获得序列中每个词的位置信息。每个位置的编码公式如下:
P E ( p o s , 2 i ) = s i n ( p o s / 1000 0 2 i / d m o d e l ) PE_{(pos,2i)}=sin(pos/10000^{2i/d_{model}}) PE(pos,2i)=sin(pos/100002i/dmodel)
P E ( p o s , 2 i + 1 ) = c o s ( p o s / 1000 0 2 i / d m o d e l ) PE_{(pos,2i+1)}=cos(pos/10000^{2i/d_{model}}) PE(pos,2i+1)=cos(pos/100002i/dmodel)
其中, p o s pos pos是词向量在序列中的位置, i i i是维度。
由三角函数两角和公式可知, P E p o s + k PE_{pos+k} PEpos+k是 P E p o s PE_{pos} PEpos的线性函数。
s i n ( α + β ) = s i n ( α ) c o s ( β ) + c o s ( α ) s i n ( β ) sin(\alpha+\beta)=sin(\alpha)cos(\beta)+cos(\alpha)sin(\beta) sin(α+β)=sin(α)cos(β)+cos(α)sin(β)
c o s ( α + β ) = c o s ( α ) c o s ( β ) − s i n ( α ) s i n ( β ) cos(\alpha+\beta)=cos(\alpha)cos(\beta)-sin(\alpha)sin(\beta) cos(α+β)=cos(α)cos(β)−sin(α)sin(β)
因此,经过上述编码,模型可以获得每个词的绝对位置及相对位置的信息。
word embedding和position encoding相加后,进行LayerNorm,然后输入到Encoder模块
tranformer 采用layer normalization归一化策略对隐藏层词向量进行调整,公式如下:
x − E [ x ] V a r [ x ] + ϵ ∗ γ + β \frac{x - \mathrm{E}[x]}{ \sqrt{\mathrm{Var}[x] + \epsilon}} * \gamma + \beta Var[x]+ϵx−E[x]∗γ+β
其中, γ \gamma γ和 β \beta β为待学习的参数。
1,先将词向量调整到均值为0,方差为 1 的分布。目的是为了使词向量在不同的隐藏层之间保持相同的分布。
2,对归一化后的 x x x进行平移和缩放,调整到均值为 β \beta β,方差为 γ 2 {\gamma}^2 γ2的分布。目的是为了增强模型的非线性表达能力。
transformer提出了一种新的attention机制,即self-attention
如图所示,编码器有6个相同的层(参数不共享)组成,而每一层又都有两个子层。
第一个子层由多头注意力机制组成,第二个子层是全连接的前馈层。
每个子层先进性残差连接,然后归一化。具体地,每个子层的输出和输入相加,即 x x x+Sublayer( x x x),然后进行层归一化,为了进行残差连接,所有的子层和embedding层的输出都保持 d d d=512的维度。
多头注意力机制是transformer模型的核心结构,也是学习的重点。
transformer模型的Embedding与其它模型的Embedding层结构相同,将输入序列转换为 d m o d e l d_{model} dmodel维的词向量矩阵。
我们知道,RNN为了获得序列的时序信息,将序列按时间轴展开,然后依次输入到RNN单元中。
但是transformer并没有采用这种结构,而是根据输入序列的embedding矩阵,对每个位置进行编码,公式如下:
P E ( p o s , 2 i ) = s i n ( p o s / 1000 0 2 i / d m o d e l ) PE_{(pos,2i)}=sin(pos/10000^{2i/d_{model}}) PE(pos,2i)=sin(pos/100002i/dmodel)
P E ( p o s , 2 i + 1 ) = c o s ( p o s / 1000 0 2 i / d m o d e l ) PE_{(pos,2i+1)}=cos(pos/10000^{2i/d_{model}}) PE(pos,2i+1)=cos(pos/100002i/dmodel)
其中, p o s pos pos是词向量在序列中的位置, i i i是维度。
编码的目的是为了获得词向量在序列中所处的位置信息,经过上述编码,模型可以获得每个词的绝对位置及相对位置的信息。
上述公式中,给定偏移量 k k k, P E p o s + k PE_{pos+k} PEpos+k可以表示为 P E p o s PE_{pos} PEpos的线性函数,这样模型就能很容易的学到相对位置信息。
Input Embedding和Positional Encoding矩阵相加后,输入到下一层。为了能够相加,两者维度必须相同
注意力函数可以将一组输入向量(query,key,value)映射为输出向量。具体地,输出向量是values的加权平均,而每个value的权值由query和与其对应的key经过函数计算得到。
下图为注意力机制图解。
左边图点乘注意力机制(与子对应的还有加法注意力机制),可用公式表示为:
A t t e n t i o n ( Q , K , V ) = s o f t m a x ( Q K T d k ) V Attention(Q,K,V)=softmax(\frac{QK^{T}}{\sqrt{d_k}})V Attention(Q,K,V)=softmax(dkQKT)V
另外,左边图的Q,K,V分别由右图Q,K,V经过线性变换得到。
随着Q和V矩阵的维度 d k d_k dk的增加,矩阵乘积结果将会变大,从而导致softmax函数的梯度变小。为了消除这种影响,将矩阵相乘结果除以 d k \sqrt{d_k} dk
解码器也是由6个相同的层组成。…