Transformer回顾与细节

我们在《Seq2seq Attention模型详解》中,详细地回顾了以 RNN 为基础模块的Seq2seq模型。本文所讲述的Transformer也采用Seq2seq式的编码器-解码器结构,不过它摒弃了经典的 RNN,采用 self-Attention。由于并行计算、长时序建模、模型容量大等优势,它受到BERT、GPT、T5等众多预训练模型的青睐。Transformer的模型结构简单,但细节较多,本文会用尽可能深入而明了的方式进行讲述。

0.序

进入正文前,我们先对上述的3个Transformer优势进一步说明。其一,RNN 的串行结构无法支持并行计算,而Transformer的同一层的多个self-Attention完全独立,即多个head,可并行计算。其二,RNN 的串行结构会"遗忘"位于时序输入靠前位置的内容,而Transformer的self-Attention只需一步计算,就能得出时序输入中的任意两个位置的内容的联系,缓解了长距离依赖问题;其三,Transformer的参数量更多,对数据分布的建模能力更强,满足海量数据场景的要求。

在这里插入图片描述

1. 总体结构:Encoder与Decoder

Encoder由多层结构一致的layer串联而成(默认6层),每个layer包含两个sublayer:“多头self-Attention"和"前馈神经网络”。

Decoder同样由多层结构一致的layer串联而成,每个layer包含三个sublayer:“Masked多头self-Attention”、“多头self-Attention"和"前馈神经网络”。

在这里插入图片描述

2. 输入

Encoder和Decoder的输入,皆由Embedding和位置编码组成。

在这里插入图片描述

2.1 Embedding

Encoder的Embedding层是一个look-up表,用于得到输入序列经过tokenizer后的各个token的嵌入表示。Decoder的Embedding层通常与Encoder共享参数,用于得到Decoder前一时刻的预测输出的token的嵌入表示。如果采用Teacher Forcing,这里变为用于得到Decoder前一时刻的真实标签的token的嵌入表示。

2.2 位置编码

在Transformer中,self-Attention把任意两个字之间计算距离缩小为1,因此丢失了序列顺序。

位置不敏感的模型,例如Transformer、CNN,无法捕捉输入顺序,即在序列顺序打乱后,模型的输出保持不变。所以,通过额外加入位置编码,补偿输入的顺序关系。

根据不同位置是否存在相对关系,分为绝对位置编码和相对位置编码。绝对位置编码能够反映位置k的信息,通常直接加在输入x_k上;相对位置编码能够反映不同位置i和j的距离关系,通常加在Attention计算中。

Transformer采用了固定式位置编码,即三角函数cos和sin,公式如下:
P E ( p o s , 2 i ) = s i n ( p o s 1000 0 2 i d m o d e l ) 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)}=sin(\frac{pos}{10000^{\frac{2i}{d_{model}}}}) \\ PE_{(pos,2i+1)}=cos(\frac{pos}{10000^{\frac{2i}{d_{model}}}}) PE(pos,2i)=sin(10000dmodel2ipos)PE(pos,2i+1)=cos(10000dmodel2ipos)

其中, p o s pos pos表示token在输入序列中的位置,2i表示PE向量的第2i个分量, d m o d e l d_model dmodel表示位置编码的维度(与embedding维度相等)。
由此,绝对位置编码可表示为位置的线性函数。

此外,受益于三角函数特性,模型能学习到不同token的相对位置关系,推导如下:

利用和差公式:
sin ⁡ ( α + β ) = sin ⁡ α ⋅ cos ⁡ β + cos ⁡ α ⋅ sin ⁡ β cos ⁡ ( α + β ) = cos ⁡ α ⋅ cos ⁡ β − sin ⁡ α ⋅ sin ⁡ β \begin{aligned} &\sin (\alpha+\beta)=\sin \alpha \cdot \cos \beta+\cos \alpha \cdot \sin \beta \\ &\cos (\alpha+\beta)=\cos \alpha \cdot \cos \beta-\sin \alpha \cdot \sin \beta \end{aligned} sin(α+β)=sinαcosβ+cosαsinβcos(α+β)=cosαcosβsinαsinβ

代入pos+k的位置编码计算中,设 w i = 1 1000 0 2 i d m o d e l w_i=\frac{1}{10000^{\frac{2i}{d_{model}}}} wi=10000dmodel2i1

{ P E ( p o s + k , 2 i ) P E ( p o s + k , 2 i + 1 ) = { sin ⁡ ( w i ⋅ ( pos + k ) ) cos ⁡ ( w i ⋅ (  pos  + k ) ) = { sin ⁡ ( w i ⋅ p o s ) cos ⁡ ( w i ⋅ k ) + cos ⁡ ( w i ⋅ p o s ) sin ⁡ ( w i ⋅ k ) cos ⁡ ( w i ⋅ p o s ) cos ⁡ ( w i ⋅ k ) − sin ⁡ ( w i ⋅ p o s ) sin ⁡ ( w i ⋅ k ) = { P E ( p o s , 2 i ) cos ⁡ ( w i ⋅ k ) + P E ( p o s , 2 i + 1 ) sin ⁡ ( w i ⋅ k ) P E ( p o s , 2 i + 1 ) cos ⁡ ( w i ⋅ k ) − P E ( p o s , 2 i ) sin ⁡ ( w i ⋅ k ) \begin{aligned} \begin{cases} PE_{(pos+k, 2 i)} \\ PE_{(pos+k, 2i+1)} \end{cases} &= \begin{cases} \sin \left(w_{i} \cdot (\text{pos}+k)\right) \\ \cos \left(w_{i} \cdot(\text { pos }+k)\right) \end{cases} \\ &= \begin{cases}\sin \left(w_{i} \cdot pos\right) \cos \left(w_{i} \cdot k\right)+\cos \left(w_{i} \cdot pos\right) \sin \left(w_{i} \cdot k\right) \\ \cos \left(w_{i} \cdot pos\right) \cos \left(w_{i} \cdot k\right) - \sin \left(w_{i} \cdot pos \right) \sin \left(w_{i} \cdot k\right) \end{cases} \\ &= \begin{cases}PE_{(pos,2i)} \cos \left(w_{i} \cdot k\right) + PE_{(pos,2i+1)} \sin \left(w_{i} \cdot k\right) \\ PE_{(pos,2i+1)} \cos \left(w_{i} \cdot k\right) - PE_{(pos,2i)} \sin \left(w_{i} \cdot k\right) \end{cases} \\ \end{aligned} {PE(pos+k,2i)PE(pos+k,2i+1)={sin(wi(pos+k))cos(wi( pos +k))={sin(wipos)cos(wik)+cos(wipos)sin(wik)cos(wipos)cos(wik)sin(wipos)sin(wik)={PE(pos,2i)cos(wik)+PE(pos,2i+1)sin(wik)PE(pos,2i+1)cos(wik)PE(pos,2i)sin(wik)

由于相对距离 k k k是常数,设 u = cos ⁡ ( w i ⋅ k ) , v = sin ⁡ ( w i ⋅ k ) u=\cos \left(w_{i} \cdot k\right), v=\sin \left(w_{i} \cdot k\right) u=cos(wik),v=sin(wik),可得:
[ P E ( p o s + k , 2 i ) P E ( p o s + k , 2 i + 1 ) ] = [ u v − v u ] × [ P E ( p o s , 2 i ) P E ( p o s , 2 i + 1 ) ] \begin{bmatrix} PE_{(pos+k, 2 i)} \\ PE_{(pos+k, 2i+1)} \end{bmatrix}=\begin{bmatrix} u& v \\ -v& u\end{bmatrix} \times \begin{bmatrix} PE_{(pos, 2 i)} \\ PE_{(pos, 2i+1)} \end{bmatrix} [PE(pos+k,2i)PE(pos+k,2i+1)]=[uvvu]×[PE(pos,2i)PE(pos,2i+1)]

由此, P E ( p o s + k , 2 i ) PE_{(pos+k, 2 i)} PE(pos+k,2i)可表示为 P E ( p o s , 2 i ) PE_{(pos, 2 i)} PE(pos,2i)的线性函数。

固定式位置编码的优点是,推理时支持任意长度的输入(不受训练时输入长度的限制)。

BERT采用了可训练式位置编码,训练前,位置编码随机初始化,并和词嵌入加在一起送入模型,作为参数进行训练。推理时,以查表的方式找到特定位置的编码向量。

可训练式位置编码的优点是,在大语料上准确性比较好,缺点是推理时限制了输入的长度(超过的position无法查表得到编码),超出部分可随机初始化,但效果依赖于数据量。

3. 多头Attention

本小节由3个问题展开,问题一是“Attention的计算细节?”,问题二是“multi-head的计算细节?”,问题三是“不同类型Attention的计算细节?”。

问题1. Attention的计算细节?

Q, K, V矩阵是Attention计算的关键。不同类型的Attention的Query、Key、Value来源不同,具体差别将在下文"问题3. 不同类型Attention的计算细节"中详细说明。

此处假设已经确定Query、Key、Value,分别通过线性变换,即可得到Q、K、V矩阵,再按如下公式计算Attention:
Attention(Q,K,V) = s o f t m a x ( Q K T d k ) ⋅ V \text{Attention(Q,K,V)} = softmax(\frac{QK^T}{\sqrt{d_k}})·V Attention(Q,K,V)=softmax(dk QKT)V

其中,Q、K的维度为[batch_size, seq_len, d_k] ,V的维度为[batch_size, seq_len, d_v]。分母 1 d k \frac{1}{\sqrt{d_k}} dk 1 是一个放缩因子,防止d_k增大时,Q和K的点积值过大,方差变成原来的 d_k 倍,导致softmax梯度变得非常小。
D ( q ⋅ k d k ) = d k ( d k ) 2 = 1 D(\frac{q·k}{\sqrt{d_k}}) = \frac{d_k}{(\sqrt{d_k})^2} = 1 D(dk qk)=(dk )2dk=1

放缩因子 1 d k \frac{1}{\sqrt{d_k}} dk 1 将方差控制为1,有效缓解了梯度消失问题。

在这里插入图片描述

问题2. multi-head的计算细节?

我们将Attention视为一个头。Encoder和Decoder的每一层中,都有多个头。这样做的好处有,多个头之间相互独立,可以并行计算;并且可以关注到不同子空间的信息。

在单头Attention中,我们只计算一组Q, K, V矩阵。在多头Attention中,Query、Key、Value分别通过n次线性变换得到n组Qi、Ki、Vi矩阵,其中n是头的个数。此时,以K矩阵为例,维度由单头的[nbatches, seq_len, d_model],变为了[nbatches, seq_len, num_head, d_k],其中d_k=d_model/num_head。

每一组Qi、Ki、Vi,分别经过Attention计算,得到单头输出Zi。最后,所有的Z0 ~ Zn拼接在一起,此时维度变回了[nbatches, seq_len, d_model],并通过线性变换得到最终输出Z。

在这里插入图片描述

问题3. 不同类型Attention的计算细节?

Encoder和Decoder中,共包含"多头self-Attention"、"masked 多头self-Attention"和"多头cross-Attention"三种Attention机制。
在这里插入图片描述

其一,多头self-Attention位于Encoder中,即上图左侧橘色模块。它的输入Query、Key、Value均来源于同一文本,即Encoder的输入(从Encoder第二层开始,此处变为前一层的输出)。多头self-Attention的作用是建模输入中的各个单词的依存关系(e.g.语法特征)。

其二,masked 多头self-Attention位于Decoder中,即上图右侧下方橘色模块。它的Query、Key、Value都来源于前一时刻的Decoder的输出(若采用Teacher Forcing,此处变为前一时刻的ground truth)。

为了在推理过程中,避免模型看到要预测的信息,防止泄露,采用了Sequence Mask。

Transformer所采用的的mask分为Padding Mask和Sequence Mask。其中,Padding Mask(可用于encoder和decoder)用于将被PAD为0的位置上的值成为一个非常小的负数-1e9(可以是负无穷),经过softmax之后,这些位置的概率就变为了0。由此,相当于把[PAD]的无用信息给mask掉了。Sequence Mask(只用于decoder)则使用和原Tensor大小相同的下三角形掩码Tensor,即上三角部分全为非常小的负数(可以是负无穷),经过softmax之后,这些位置的概率就变为了0。由此,相当于把序列尾端元素给mask掉了。

其三,多头cross-Attention,又称为多头encoder-decoder Attention,位于Decoder中,即上图右侧上方橘色模块。它的query来自前一层decoder的输出,它的key和value来自encoder的输出。多头cross-Attention是Source各单词和Target各单词的对齐机制。

4. 残差模块

每个sublayer中,都包含一个 Add&Norm 模块。其中Add是残差连接;Norm是层归一化;还包含dropout。

以Encoder为例,如下图,残差模块的计算顺序是:step 1.对原始输入进行层归一化;step 2.把层归一化的输出,送入自注意或前馈神经网络;step 3.把自注意或前馈神经网络的输出,送入dropout;step 4.把dropout的输出与未经过层归一化的原始输入直接相加。

层归一化的优点是,避免数据落入激活函数的饱和区,减缓梯度消失问题。
残差连接的优点是,可以加快模型收敛,解决随着层数加深,误差传播的值越来越小的问题。

在这里插入图片描述

5. 输出

位于最后的 linear layer 将 decoder 的输出扩展到与 vocabulary size 一样的维度上。
FFN ( x ) = m a x ( 0 , x W 1 + b 1 ) W 2 + b 2 \text{FFN}(x)=max(0, xW_1+b_1)W_2+b_2 FFN(x)=max(0,xW1+b1)W2+b2

经过 softmax 后,得到词表中各个 word 作为预测结果的概率。采用beam search,得到生成序列。

在这里插入图片描述
附:训练小技巧

技巧1. 标签平滑,公式如下,防止过拟合;
技巧2. 学习率先线性增长,前5000步预热,再指数衰减;
在这里插入图片描述


Reference

[1] The Illustrated Transformer
[2] The Annotated Transformer
[3] 图解Transformer(完整版)
[4] positional encoding位置编码详解
[5] 让研究人员绞尽脑汁的Transformer位置编码

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SunnyGJing

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

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

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

打赏作者

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

抵扣说明:

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

余额充值