3 Model Architecture
大多数自然语言转换模型都有一个encoder-decoder结构:
- encoder: 把输入的离散符号序列 x = ( x 1 , . . . , x n ) x=(x_1,...,x_n) x=(x1,...,xn)转换为连续值序列 z = ( z 1 , . . . , z n ) z=(z_1,...,z_n) z=(z1,...,zn)
- decoder: 生成输出符号序列
(
y
1
,
.
.
.
,
y
m
)
(y_1,...,y_m)
(y1,...,ym)
每一步模型都是自回归的,即之前生成的符号序列会作为额外的输入,用来生成下一个输出。
3.1 Encoder and Decoder Stacks
- Encoder:
1.由6个基本层堆叠起来,每个基本层包含两个子层:multi-head self-attention mechanism和fully connected feed-forward network 。
2.每个子层有一个残差连接(residual connection),然后有一个归一化层(layer normalization)。
3.每个子层的输出是: L a y e r N o r m ( x + S u b l a y e r ( x ) ) LayerNorm(x+Sublayer(x)) LayerNorm(x+Sublayer(x))
Sublayer(x)是子层sub-layer的函数。
4.嵌入层和子层输出的维度都是512。 - Decoder:
1.同样由6个基本层堆叠起来。
2.每个基本层除了两个子层以外,还有第三个子层:对于encoder stack的输出进行multi-head attention。
3.同样,每个子层有一个残差连接(residual connection),然后有一个归一化层(layer normalization)。
4.修订decoder的self-attention sub-layer 来保留位置。因为输出的嵌入层由偏移了一个位置。确保对i位置的预测值只取决于已知的在i之前的输出。
3.2 Attention
Attention函数可以描述为:将query和一组key-value pairs映射到output。
query, keys, values和output都是向量。output是values的加权和,权重由query与对应key的一个兼容性函数计算得到。
3.2.1 Scaled Dot-Product Attention
输入由
d
k
d_k
dk维的queries和keys,
d
v
d_v
dv维的values组成。
计算query和所有keys的点积,每个都除以
d
k
\sqrt{d_k}
dk,然后再通过一个softmax function获得values的权重。计算出输出矩阵为:
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
∈
R
n
×
d
k
,
K
∈
R
m
×
d
k
,
V
∈
R
m
×
d
v
Q\in R^{n\times d_k},K\in R^{m\times d_k},V\in R^{m\times d_v}
Q∈Rn×dk,K∈Rm×dk,V∈Rm×dv
如果逐个向量来看:
A
t
t
e
n
t
i
o
n
(
q
t
,
K
,
V
)
=
∑
s
=
1
m
1
Z
e
x
p
(
<
q
t
,
k
s
>
d
k
)
v
s
Attention(q_t,K,V)=\sum\limits_{s=1}^{m}\frac{1}{Z}exp(\frac{<q_t,k_s>}{\sqrt{d_k}})v_s
Attention(qt,K,V)=s=1∑mZ1exp(dk<qt,ks>)vs
其中Z是归一化因子。事实上q,k,v分别是query,key,value的简写,K,V是一 一对应的,它们就像是key-value的关系,那么上式的意思就是通过
q
t
q_t
qt这个query,通过与各个
k
s
k_s
ks内积的并softmax的方式,来得到
q
t
q_t
qt与各个
v
s
v_s
vs的相似度,然后加权求和,得到一个
d
v
d_v
dv维的向量。其中因子
d
k
\sqrt{d_k}
dk起到调节作用,使得内积不至于太大(太大的话softmax后就非0即1了,不够“soft”了)。
最后得到
d
v
d_v
dv维的输出。
3.2.2 Multi-Head Attention
用h次不同的线性变换将
d
m
o
d
e
l
d_{model}
dmodel维的keys,values和queries分别映射成
d
k
d_k
dk维,
d
k
d_k
dk维和
d
v
d_v
dv维。然后把它并行代入注意力机制,产生
h
×
d
v
h\times d_v
h×dv维的输出。然后再拼起来,通过一个线性变换得到最后的输出。
h
e
a
d
i
=
A
t
t
e
n
t
i
o
n
(
Q
W
i
Q
,
K
W
i
Q
,
V
W
i
V
)
head_i=Attention(QW_i^Q,KW_i^Q,VW_i^V)
headi=Attention(QWiQ,KWiQ,VWiV)
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
MultiHead(Q,K,V)=Concat(head_1,...,head_h)W^O
MultiHead(Q,K,V)=Concat(head1,...,headh)WO其中
W
i
Q
∈
R
d
m
o
d
e
l
×
d
k
,
W
i
V
∈
R
d
m
o
d
e
l
×
d
k
,
W
i
V
∈
R
d
m
o
d
e
l
×
d
v
,
W
O
∈
R
h
d
v
×
d
m
o
d
e
l
W_i^Q\in R^{d_{model}\times d_k},W_i^V\in R^{d_{model}\times d_k},W_i^V\in R^{d_{model}\times d_v},W^O\in R^{hd_v\times d_{model}}
WiQ∈Rdmodel×dk,WiV∈Rdmodel×dk,WiV∈Rdmodel×dv,WO∈Rhdv×dmodel
“多头”(Multi-Head),就是只多做几次同样的事情(参数不共享),然后把结果拼接。
在该文章中,采用
h
=
8
h=8
h=8个平行的attention layers。
d
k
=
d
v
=
d
m
o
d
e
l
/
h
=
64
d_k=d_v=d_{model}/h=64
dk=dv=dmodel/h=64。因为每个head维数的降低,所以和原来维数的单头注意力机制的计算成本是同一量级的。
3.2.3 Applications of Attention in our Model
The Transformer在三个地方用到了multi-head attention:
1.在"encoder-decoder attention"层,queries来自前一个decoder层,memory keys和values来自于encoder的output。这使得decoder的每个位置都去关注输入序列的所有位置。
2.encoder包括self-attention层。在self-attention层中,所有的keys,values和queries都来自同一个地方(在这篇paper中),是encoder的前一层的output,使得encoder的每个位置都能够关注到encoder前一层的所有位置。
3.类似的,decoder也有self-attention层,让decoder的每个位置都能关注到该层以及该层之前的(decoder的)所有位置。
3.3 Position-wise Feed-Forward Networks
除了attention子层以外,encoder和decoder的每一层都包含一个全连接的feed-forward网络,分别且相同地应用到每个position,由两个线性变换组成,两个线性变换中间由一个RELU激活函数连接。 F F N ( x ) = m a x ( 0 , x W 1 + b 1 ) W 2 + b 2 FFN(x)=max(0,xW_1+b_1)W_2+b_2 FFN(x)=max(0,xW1+b1)W2+b2不同位置的线性变换是一样的,但是层与层之间的参数不一样。另外一种描述的方式是:kernel size为1的两次卷积。input和output的维度都是 d m o d e l = 512 d_{model}=512 dmodel=512,中间层的维度是 d f f = 2048 d_{ff}=2048 dff=2048,可以这样理解:每个 d m o d e l d_{model} dmodel 维向量 x 在此先由 x W 1 + b 1 xW_1+b_1 xW1+b1 变为 d f f d_{ff} dff维的 x’,再经过 m a x ( 0 , x ′ ) W 2 + b 2 max(0,x')W_2+b_2 max(0,x′)W2+b2 回归 d_model 维。之后再是一个residual connection。输出 size 仍是 [ s e q u e n c e l e n g t h , d m o d e l ] [sequence length, d_{model}] [sequencelength,dmodel]。
3.4 Embeddings and Softmax
3.5 Positional Encoding
由于本文的模型结构没有使用任何递归结构或卷积结构,为了让模型能利用输入序列的顺序信息,必须引入某种能表达输入序列每个部分的绝对或相对位置的信息才行。文章采取的方法是位置编码(positional encoding),在送入encoder和decoder之前,先对输入进行编码,位置编码的维度和embeddings的维度一致,为
d
m
o
d
e
l
d_{model}
dmodel。所以两者可以相加。
结合位置向量和词向量有几个可选方案,可以把它们拼接起来作为一个新向量,也可以把位置向量定义为跟词向量一样大小,然后两者加起来。在这篇文章中采用的是把两者加起来。
具体来说,采用正弦和余弦函数进行编码。
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是维度。
选择这个函数的原因是:也能学习到相对位置的信息。
对于任意固定的offset k,
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β
还有三角函数具有周期性。