1 研究背景
针对主流的序列转录工作如:语言建模和机器翻译,大多数研究都是围绕着RNN的方法进行的,例如长短期记忆(LSTM)和门控循环神经网络(GRU)。对于传统的RNN来说,其计算方式是沿着序列从左到右一步一步进行,假设输入序列是句子,RNN就是一个词一个词逐一的去看。对于当前这个词t来说RNN会计算其隐含层状态
h
t
h_t
ht?,这个
h
t
h_t
ht?是由上一个词的隐含层状态
h
t
?
1
h_{t-1}
ht?1?和当前这个词t决定。这样就做到了考虑了输入和输出序列的中的字符位置进行计算。这是RNN这类模型的优势,但是同时也未其带来了弊端: 1.由于他依赖于时序的输入,这使得其难以实现并行操作。(因为你想计算
h
t
h_t
ht?就必须先计算
h
t
?
1
h_{t-1}
ht?1?),这使得对一些特殊硬件GPU、TPU的多线程利用率有限。 2.由于计算是时序一步步计算的,这是得在计算到后面时有可能会忘记前面所学到的知识。如果不想发生这种情况可能意味着你需要部署一个较大的隐含层去记录信息这增大了内存开销,或者进行一个反向的由后到前的学习,这样会使得运算量倍增。 作者同样指出attention已经被用在了一些RNN模型上了,但是这些模型主要关心的是如何将编码器的内容有效的传递给解码器,归根结底这种注意机制还是与RNN一起使用的。
2 研究动机
为了解决上面提到的问题,一些专家提出了利用卷积神经网络CNN作为基本的构建块。并行计算所有输入和输出位置的隐含表示。但是CNN的主要问题是对于较长的序列块建模难度是相对较大的。例如建模两个相对较远的像素,可能需要连续多层卷积才能最后将这两个间隔较远的像素融合起来。但是如果使用了注意力机制就意味着一次就可以看到整个序列。卷积神经网络CNN的一个好处是他可以生成多个输出通道,每个输出通道可以认为其能识别不一样的模式。作者为了使得Transformer也具备这样的多通道的效果,他提出了multi-head attention。
3 模型结构
Transformer的架构是基于encoder-decoder的架构。如下图1所示,左边是encoder,右边是decoder。
3.1编码器
编码器由
N
=
6
N=6
N=6 个相同的layers组成(这个N是可调的)。每一个layers由两个子层组成分别是上面提到的Multi-Head Attention和各位置独立的全连接层(可以简单的理解为是MLP)组成,这两部分都使用残差链接。最后进行layer normalization(层归一化)。 具体公式是:
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)) , 具体步骤如下:
1
S
u
b
l
a
y
e
r
(
x
)
Sublayer(x)
Sublayer(x) 输入进入子层 2
(
x
+
S
u
b
l
a
y
e
r
(
x
)
(x+Sublayer(x)
(x+Sublayer(x) 残差连接 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)) 进出层归一化
由于残差连接需要输入和输出之间是一样大小。所以作者将每一个层的输入维度变成了
d
m
o
d
e
l
=
512
d_{model}=512
dmodel?=512大小。直接使用固定长度来表示。最后调参只需要注意两个参数分别是N和这里的
d
m
o
d
e
l
d_{model}
dmodel?。这个简单的设计最后影响到了后面的一系列网络,例如Bert和GBT。
3.2 解码器
解码器这边同样由
N
=
6
N=6
N=6 个相同的layers组成,解码器这边除了上面编码器提到的两个sub-layer;还增加了一个Masked Multi-Head Attention的子块。与编码器类似,我们在每个子层周围使用残差连接,然后进行层归一化。为什么加入这个遮蔽多头注意力子块呢?时序预测是依赖当前输入和以前的预测输出进行预测,我们不希望看到当前时刻之后的输入进入注意力层来干扰我们的预测。所以引入遮蔽多头注意力子块以防止引入当前时刻的后续时刻输入。这种屏蔽与输出嵌入偏移一个位置的事实相结合,确保了位置
t
t
t的预测仅依赖于小于t的位置处的已知输出。
3.3 Attention
attention可以被描述为将query和一组key-value对映射到输出,其中query,key,value和输出都是向量。输出为计算值的加权求和,权重是value对应key和我们查询的query的相似度(compatibility function)计算得到的。相似度越大,对应的权重越大。 本文使用的是Scaled Dot-Product Attention,其中query和key的维度为
d
k
d_k
dk?;value的维度为
d
v
d_v
dv?,输出值的维度应该也是
d
v
d_v
dv?的。query和key进行内积,将这个内积作为相似度。两个向量(query和key)如果维度相同,这两个向量的内积值越大,说明其相似度越大,如果两个向量内积为0,则说明其正交了则相似度为0。然后将每个点积结果除以
d
k
\sqrt{d_k}
dk?
?。并应用softmax函数来获得value的权重。 为了增加运算速度,作者将一个个query向量打包成了矩阵Q,key和value打包成了K和V,具体输出矩阵如下:
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(dk?
?QKT?)V Attention有两个最长用的函数,分别是加法attention和点积(乘法)attention。作者这里使用的是改进的点attention,该方法的优点是速度快、占用空间小。作者这里的创新是引入了缩放因子
1
d
k
\frac{1}{\sqrt{d_k}}
dk?
?1?,为什么引入这个缩放因子呢? 当我们输入的
d
k
d_k
dk?较大时,那么query和key之间相对的差距就会更大,就导致值更大(或更小)的值在经过softmax后会更加趋近于1(或0)。这导致值会更加向两边靠拢。此时计算梯度的难度就会增加,因为上面提到作者用的
d
k
=
512
d_k=512
dk?=512相对较大,这使得引入这个缩放因子成为了一个较好的选择。
3.4 Multi-Head Attention
作者这里提到使用
d
m
o
d
e
l
d_{model}
dmodel?维的key、value和query执行单个的attention函数相比,将query、key和value映射低维空间上,投影
h
h
h次,再做
h
h
h次的attention函数,最后每一个函数的输出将其并在一起,再投影回原来的高维空间这样的效果是更加有益的,具体流程图论文中也有展示。 图中的Linear层就是将query、key、value映射到低维空间,然后在Scaled Dot-Product Attention 中进行我们上节提到的n次attention函数,在Concat层上进行合并,最后进入Linear层回到高维空间。
为什么要做这么一个Multi-Head Attention?,因为原来单纯的Scaled Dot-Product Attention可学习的参数是有限的。但是作者所提出的这个算法就增加了可以学习的东西,例如query、key、value映射到低维空间的过程投影的w是可以学的,我给你h次的机会,希望你能学习到不同的投影方法,使得能在投影进去的度量空间里面能够匹配不同的模式需要的相似函数,这一步就类似于CNN中多输出通道。具体公式如下:
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
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
)
where \ head_i=Attention(Q{w_{i}}^Q,K{w_{i}}^K,V{w_{i}}^V)
where?headi?=Attention(Qwi?Q,Kwi?K,Vwi?V)
在Multi-Head上还是以前的
(
Q
,
K
,
V
)
(Q,K,V)
(Q,K,V)但是具体的输出是不同的头的Concat之后再投影到
W
O
W^O
WO的结果。对于每一个不同的头通过不同的可以独立学习的
W
Q
W^Q
WQ、
W
K
W^K
WK、
W
V
W^V
WV 投影到d_v上再进行上面的attention函数就可以了。 本论文中我们采用
h
=
8
h=8
h=8个平行的attention head。前面提到的
d
m
o
d
e
l
=
512
d_{model}=512
dmodel?=512,则投影到低维的空间大小为
d
k
=
d
m
o
d
e
l
/
h
=
64
d_k=d_{model}/h=64
dk?=dmodel?/h=64。
3.5 模型中Attention的应用
- 编码器的注意力层:假设编码器这里输入的序列长度是n,那么该注意力层的输入为n个长度为d的向量。注意力层的三个输入(就是模型图片中的三叉)分别表示模型的key、value以及query。由于采用的是self-attention。所以输入的长度为d的向量即作为key同时也作为value和query。这一给attention层的输出同样也是n个长度为d的向量,输出的本质可以理解为输入的n个向量的加权和。
- 解码器的Masked Mutli-Attention:解码器这边输入为:是编码器中前一层的输出。同时注意Masked的作用是屏蔽掉当前输入序列之后的序列,将其置为0。
- 解码器的Multi-Head Attention:这个注意力层不再使用self-attention。query是来自下面解码器的Masked Multi-Attention输出;编码器的输出作为key和value。
3.6 Position-wise Feed-Forward Networks
编码器和解码器中的每个层都包含一个完全连接的前馈网络,可以简单的理解为是MLP。该前馈网络包括两个线性变换,并在第一个的最后使用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? 具体步骤分解:
1
x
W
1
+
b
1
xW_1+b_1
xW1?+b1? 进行第一次线性变化; 2
m
a
x
?
(
0
,
x
W
1
+
b
1
)
max?(0,xW_1+b_1 )
max?(0,xW1?+b1?)第一次线性变化的结果进入ReLU激活函数; 3
m
a
x
?
(
0
,
x
W
1
+
b
1
)
W
2
+
b
2
max?(0,xW_1+b_1 ) W_2+b_2
max?(0,xW1?+b1?)W2?+b2? 进行第二次线性变化;
输入和输出的维度是
d
m
o
d
e
l
=
512
d_{model}=512
dmodel?=512,内层的维度为
d
f
f
=
2048
d_{ff}=2048
dff?=2048。
3.7 Embeddings and Softmax
因为这里我们输入是一个个词(或者说是叫token),我们需要将一个个词映射成相对应的向量。这里embedings的目的就是学习一个长度为d的向量去表示这个token。在该的模型中,我们在两个嵌入层和pre-softmax线性变换之间共享相同的权重矩阵。这样可以让学习更简单。在嵌入层中,我们将这些权重乘以
d
m
o
d
e
l
\sqrt{d_{model}}
dmodel?
?。
3.8 Positional Encoding
由于本文的模型结构没有使用任何递归结构或卷积结构,为了让模型能利用输入序列的顺序信息,必须引入某种能表达输入序列每个部分的绝对或相对位置的信息才行。文章采取的方法是位置编码(positional encoding),在送入encoder和decoder之前进行位置编码。具体公式如下所示:
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/10000(2i/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/10000(2i/dmodel?))
4 训练和实验
在标准WMT 2014英语-德语数据集上进行了训练,该数据集中有450万个句子对。这些句子使用byte-pair编码进行编码,源语句和目标语句共享大约37000个词符的词汇表(英语和德语共享)。 对于英语-法语翻译,使用WMT 2014英法数据集,它包含3600万个句子,并将词符分成32000个word-piece词汇表。 训练上在一台有8个NVIDIA P100 GPU训练我们的模型。基础模型总共12小时的训练。对于我们的大型模型(见表3的底线),步进时间为1.0秒。大模型 使用了30万步(3.5天)的训练。 训练器上使用的是Adam,其中参数选用的分别是:
β
1
=
0.9
β_1=0.9
β1?=0.9,
β
2
=
0.98
β_2=0.98
β2?=0.98,
τ
=
1
0
?
9
\tau=10^{-9}
τ=10?9,学习率如下:
l
r
a
t
e
=
d
m
o
d
e
l
?
0.5
?
m
i
n
(
s
t
e
p
_
n
u
m
?
0.5
,
s
t
e
p
_
n
u
m
?
w
a
r
m
u
p
_
s
t
e
p
s
?
1.5
)
lrate = {d_{model}}^{-0.5}·min(step\_num^{-0.5},step\_num·warmup\_steps^{-1.5})
lrate=dmodel??0.5?min(step_num?0.5,step_num?warmup_steps?1.5)
学习率是根据模型宽度决定的,具体来说就是模型越宽学习率越低,另外一个参数是warmupsteps=4000,具体解释是,这对应于线性增加第一个预热步骤训练步骤的学习速率,然后按步骤数的平方反比成比例地降低学习速率。这里学习率可调的参数也比较少,主要是因为Adam对于学习率不太敏感。 关于正则化本文首先介绍了Residual Dropout,对于每一个子层(例如:多头注意力层以及之后的MLP),在其进入残差之前和进入layer alone之前使用了一个dropout,该dropout率为0.1。本项工作使用了Label Smoothing,这个技术在inception v3有提及的。因为在进行softmax时,我们一般认为正确是1,错误的是0。但是对于softmax是很难真正逼近于1。(因为softmax内部是指数,它需要你输入无限大才能逼近于1)。一般来说不会要求正确的是1,而是会让其下降的0.9左右。这篇论文中,作者直接将这个值降到了0.1(将softmax输出到0.1就行),论文中也提到这会使得perplexity受到损失,因为模型不那么确信,但提高了准确性和BLEU分数。
表1-具体的参数和任务完成效果的表
N
N
N是具体的Transformer架构要堆几层,
d
m
o
d
e
l
d_{model}
dmodel?是token未来要表示成多大的向量,
d
f
f
d_{ff}
dff?表示MLP中间的那个隐含层的输出大小;
h
h
h是多头注意力里面头的个数;
d
k
d_k
dk?,
d
v
d_v
dv?分别是注意中key和value的那个维度;
P
d
r
o
p
P_{drop}
Pdrop?正则化的丢弃率;
τ
t
s
\tau_{ts}
τts?表示要学习的label的真实值是多少。
5 实验结果
模型在 WMT2014 英语-德语的翻译任务上取得了28.4的BLEU评分。在现有的表现最好模型的基础上,包括整合模型,提高了2个BLUE评分。 在WMT 2014英语-法语翻译任务中,大型模型(Transform(big))的BLEU得分为41.0,超过了之前发布的所有单一模型,同样和最新的复杂模型效果不相上下,但是在训练开销上Transformer的训练成本远低于传统的神经网络模型。 ?? 表2-实验结果
6 讨论
在这项工作中,作者提出了Transformer,Transformer的应用不仅仅在机器翻译上,在几乎NLP的工作上都是适用的,甚至是后来的一些CV上的工作。总的来说Transformer采用分布式训练,在GPU上具有更好的训练效率。同时在分析预测更长的文本时,能够捕捉间隔较长的语义关联效果。最后自注意力可以产生更具可解释性的模型。可以从模型中检查注意力分布。各个注意头 (attention head) 也可以学会执行不同的任务。 但是反过来说文章标题是“Attention Is All You Need”,但是attention的作用主要是将序列的信息聚合起来,但是文本使用的其他工作例如MLP、残差连接都是缺一不可的。将这些东西去掉只使用Attention我们同样也无法得到想要的训练结果。同时对于Attention来说其对数据的抓取能力没用那么强,以至于我们可能需要更加庞大的数据和模型才能得到相对较好的结果,这也就是为什么看到后期的一些Transformer越做越大的原因。
|