本文主要对论文“Attention is All You Need”的核心架构进行介绍。

下图是Transformer的架构:

Attention is All You Need 论文架构理解

Attention

一个attention函数可以看做是将一个query跟一组key-value对映射到一个输出。query、keys、values和输出都是向量。输出是values的加权和,每一个values对应的权重是由兼容函数(compatibility function)根据query和对应的key计算出来的。

Attention is All You Need 论文架构理解

图1
Scaled Dot-Product Attention

Scaled Dot-Product Attention 的输入为queries、keys和values,queries和keys的维度为 d k d_k dk ,values的维度为 d v d_v dv 。然后我们计算query跟所有的keys的点积,然后除以 d k \sqrt{d_k} dk ,之后再通过softmax函数计算所有values的权重。

为了方便计算,我们将所有的queries打包到矩阵Q中,同理将keys和values也打分别包到矩阵K和V中。于是计算Attention函数的公式就可以写成下面的样子:
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 (1) Attention(Q,K,V)=softmax(\frac{QK^T}{\sqrt{d_k}})V \tag{1} Attention(Q,K,V)=softmax(dk QKT)V(1)
两个最常用的Attention函数是加法注意(additive attention) 和 点积注意(dot-product (multi-plicative) attention) 。上面这个模型就是用的点积注意,不过缩放因子用的是 1 d k \frac{1}{\sqrt{d_k}} dk 1 。加法注意计算兼容函数用的是一个单隐层的前馈神经网络。这两个函数的理论复杂度是一样的,不过在实践中,点积注意速度更快,更节省空间,因为后者可以使用高度优化的矩阵乘法代码实现。

如果 d k d_k dk 比较小,两个机制表现是相似的,如果 d k d_k dk 值较大的话,加法注意要由于点积注意。我们怀疑对于较大的 d k d_k dk 值,点积的大小会增大,从而将softmax函数推入一个梯度极小的区域。为了抵消这个影响,我们将点积乘以 1 d k \frac{1}{\sqrt{d_k}} dk 1

Multi-Head Attention

多头注意力使用的不是单一的注意函数,作者发现分别将queries、keys、values用不同的、学习线性投影分别映射到 d k , d k , d v d_k,d_k,d_v dk,dk,dv 维是有益的,并且投影了h次。对于queries、keys、values的每一个映射版本,都可以并行的执行attention函数,生成 d v d_v dv 维的输出值。最后将他们连接在一起并再次投影得到最终值。这就是上图右侧的多头注意力。

多头注意能够使模型在不同的表示子空间、不同的位置共同关注信息。如果只有单一的注意力头,平均会抑制这种情况。
M u l t i H e a d ( Q , K , V ) = C o n c a t ( h e a d 1 , ⋯   , h e a d h ) W O w h e r e   h e a d i = A t t e n t i o n ( Q W i Q , K W i K , V W i V ) (2) MultiHead(Q,K,V)=Concat(head_1,\cdots,head_h)W^O \\where \, head_i=Attention(QW_i^Q,KW_i^K,VW_i^V) \tag{2} MultiHead(Q,K,V)=Concat(head1,,headh)WOwhereheadi=Attention(QWiQ,KWiK,VWiV)(2)
其中投影参数矩阵 W i Q ∈ R d m o d e l × d k W_i^Q \in \mathbb{R}^{d_{model} \times d_k} WiQRdmodel×dk W i K ∈ R d m o d e l × d k W_i^K \in \mathbb{R}^{d_{model} \times d_k} WiKRdmodel×dk W i V ∈ R d m o d e l × d v W_i^V \in \mathbb{R}^{d_{model} \times d_v} WiVRdmodel×dv W O ∈ R h d v ∈ d m o d e l W^O \in \mathbb{R}^{hd_v \in d_{model}} WORhdvdmodel

作者部署了8个并行的注意力层(注意力头),即 h = 8 h=8 h=8 ,对于每一层,设置 d k = d v = d m o d e l / h d_k=d_v=d_{model}/ h dk=dv=dmodel/h ,由于每个注意力头的维度都降低了,所以其总的计算代价跟全维度单头注意力的计算代价相似。

Position-wise Feed-Forward Networks

除了attention子层,编码器和解码器的每一层都包含了一个全连接的前馈网络,每一个位置都是独立部署并且是一样的。这包括两个线性转换,中间是一个ReLU**函数。
F F N ( x ) = m a x ( 0 , x W 1 + b 1 ) W 2 + b 2 (3) FFN(x)=max(0,xW_1+b_1)W_2+b_2 \tag{3} FFN(x)=max(0,xW1+b1)W2+b2(3)
线性变换在不同位置上是相同的,他们层与层之间使用不同的参数。另一个描述的方式是内核大小为1的两个卷积。输入输出的维度是 d m o d e l = 512 d_{model}=512 dmodel=512 ,内层的维度是 d f f = 2048 d_{ff}=2048 dff=2048

Embeddings and Softmax

跟其他的序列转移模型一样,我们使用学习的嵌入(learned embeddings)将输入和输出的tokens转换为维度为 d m o d e l d_{model} dmodel 的向量。我们通常也使用学习的线性变换和softmax函数将解码器的输出转换为预测下一个token的概率。在这个模型中,在两个嵌入层之间使用相同的权重矩阵,… ,在嵌入层,我们用 d m o d e l \sqrt{d_{model}} dmodel 乘以这些权重。

Position Encoding

因为这个模型中没有循环层也没有卷积层,为了使模型能够利用序列的信息,我们必须注入序列中tokens的相对或者绝对信息。为了达到这个目的,在输入嵌入中添加了“位置编码”,在每个编码器和解码器栈底部。位置编码跟嵌入的维度相同,都是 d m o d e l d_{model} dmodel ,以便于二者相加。对于位置编码也有许多选择,例如学习到的编码或者固定的编码。

在这项工作中,我们使用不同频率的 sine 和 cosine 函数:
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 ) (4) PE_{(pos,2i)} = sin(pos/10000^{2i/d_{model}}) \\PE_{(pos,2i+1)} = cos(pos/10000^{2i/d_{model}}) \tag{4} PE(pos,2i)=sin(pos/100002i/dmodel)PE(pos,2i+1)=cos(pos/100002i/dmodel)(4)
其中 p o s pos pos 是位置, i i i 是维度。也就是说,每一个位置编码的维度都对应一个正弦信号。波长形成一个从 2 π 2\pi 2π 100002 ⋅ π 10000 2 \cdot \pi 100002π 的几何连续。之所以选择这个函数,是因为我们猜测它会比较容易的学习相对位置的参与,因为对于任意固定的偏移 k k k P E p o s + k PE_{pos+k} PEpos+k 能够被表示为 P E p o s PE_{pos} PEpos 的一个线性函数。

我们也试验过使用学习的位置嵌入,结果发现两种方式取得几乎一样的结果。我们选择正弦版本,是因为他可能允许模型推断序列的长度比训练中遇到的更长。

相关文章:

  • 2021-07-06
  • 2021-10-06
  • 2021-08-09
  • 2021-07-02
  • 2021-08-01
  • 2021-04-22
  • 2021-04-15
猜你喜欢
  • 2021-08-11
  • 2022-02-26
  • 2021-08-14
  • 2021-06-18
  • 2021-09-03
  • 2021-10-09
  • 2021-08-11
相关资源
相似解决方案