文章目录
引言
Transformer同样也是seq2seq模型。在注意力机制诞生后,诞生了多种改进的模型,但是这些模型一般都是把注意力机制与循环神经网络结合(包括一些改良的,如LSTM),但是这些模型有个弊端:RNN由于其顺序结构训练速度常常受到限制,就是并行计算能力不强。既然Attention模型本身可以看到全局的信息, 那么一个自然的疑问是我们能不能去掉RNN结构,仅仅依赖于Attention模型呢,这样我们可以使训练并行化(encoder端并行计算),同时拥有全局信息?为解决这一些问题,论文提出了一种仅基于注意力机制的模型,具有强大的并行计算性以及效果很好。
一、Structure of Transformers
Transformer模型的模型结构为encoder-decoder,
如下图,N个Encoder block组成encoder,N个Decoder block组成decoder。基于注意力机制的构造与基于RNN的不同,基于RNN的是在时间步上串联(在每个time step只能输入一个token),而基于注意力机制的是类似于桶状结构(一起将数据输入到模型中去)。
那么,在Transformer中encoder中的信息如何传给decoder?
将encoder的最后一个Block分别传给decoder中的每一个block,然后decoder进行输出生成。
二、Encoder Structure
以输入为:Thinking Machines为例,Thinking与Machines最开始输入是维度为vocab的one-hot向量,经过embedding层,转换成embedding size大小的向量,输入到self-Attention层中,得到
z
z
z
,经过Feed Forward层将得到
r
r
r
。
r
r
r
将作为下一个encoder Block的input。
其中,Self-attention将在后面详细分析,这里介绍FFN。每一层经过attention之后,还会有一个FFN,这个FFN的作用就是空间变换。FFN包含了2层linear transformation层,中间的激活函数是ReLu。FFN的加入引入了非线性(ReLu激活函数),变换了attention output的空间, 从而增加了模型的表现能力。把FFN去掉模型也是可以用的,但是效果差了很多。
三、Self-attention and multi-head self-attention
Word2vec的基本思想:句子中相近的词之间是有联系的,比如今天后面经常出现上午、下午和晚上。所以Word2vec的基本思想是用词来预测词,skip-gram使用中心词预测周围词,cbow使用周围词预测中心词。那么,一个词的embedding有没有可能关系到周围词外的部分?Self-attention就是自己与自己计算一个相关性(权重),利用自己(句子/文本)
内部的表征
得到一个更好的表征。
1.Self-attention
Self-Attention的基本结构如下:
MatMul对应
Q
K
T
QK^T
Q
K
T
,Scale对应
d
k
\sqrt{d_k}
d
k
,
Mask
是因为每一个batch的数据经过padding后变得等长,在计算attention score时,不希望padding部分参与softmax计算,此时,需要Mask使得padding部分权重为0(padding部分的得分为
−
i
n
f
-inf
−
i
n
f
)。第二个MatMul对应权重与vector标的的计算。
下面展示Self-attention内部是如何计算的
Q
Q
Q
:标的
K
K
K
:和别人计算的标的
V
V
V
:加权的vector标的
对于self-attention来讲,
Q
(
Q
u
e
r
y
)
,
K
(
K
e
y
)
,
V
(
V
a
l
u
e
)
Q(Query), K(Key), V(Value)
Q
(
Q
u
e
r
y
)
,
K
(
K
e
y
)
,
V
(
V
a
l
u
e
)
三个矩阵均来自同一输入(Q、K、V来自embedding的线性变化),首先我们要计算
Q
Q
Q
与
K
K
K
之间的点乘,然后为了防止其结果过大,会除以一个尺度标度
d
k
\sqrt{d_k}
d
k
,其中
d
k
\sqrt{d_k}
d
k
为一个query和key向量的维度。再利用Softmax操作将其结果归一化为概率分布,然后再乘以矩阵
V
V
V
就得到权重求和的表示。
举个例子:
假如我们要翻译一个词组Thinking Machines,其中Thinking的输入的embedding vector用
x
1
x_1
x
1
表示,Machines的embedding vector用
x
2
x_2
x
2
表示。
当我们处理Thinking这个词时,我们需要计算句子中所有词与它的Attention Score,这就像将当前词作为搜索的query,去和句子中所有词(包含该词本身)的key去匹配,看看相关度有多高。我们用
q
1
q_1
q
1
代表Thinking对应的query vector,
k
1
k_1
k
1
及
k
2
k_2
k
2
分别代表Thinking以及Machines对应的key vector,则计算Thinking的attention score的时候我们需要计算
q
1
q_1
q
1
与
k
1
,
k
2
k_1,k_2
k
1
,
k
2
的点乘,同理,我们计算Machines的attention score的时候需要计算
q
2
q_2
q
2
与
k
1
,
k
2
k_1,k_2
k
1
,
k
2
的点乘。我们分别得到了
q
1
q_1
q
1
与
k
1
,
k
2
k_1,k_2
k
1
,
k
2
的点乘积,然后我们进行尺度缩放与softmax归一化,如下图所示:
显然,当前单词与其自身的attention score一般最大,其他单词根据与当前单词重要程度有相应的score。然后我们在用这些attention score与value vector相乘,得到加权的向量。
如果将输入的所有向量合并为矩阵形式,则所有query, key, value向量也可以合并为矩阵形式表示
其中,
W
Q
,
W
K
,
W
V
W^Q,W^K,W^V
W
Q
,
W
K
,
W
V
是我们模型训练过程中学习到的合适参数,上述公式可以简化为矩阵计算:
2.multi-head self-attention
multi-head self-attention的基本结构如下:
multi-head self-attention 与self-attention 的区别在于可以有多组
W
Q
,
W
K
,
W
V
W^Q,W^K,W^V
W
Q
,
W
K
,
W
V
,得到不同的
Q
、
K
、
V
Q、K、V
Q
、
K
、
V
,最后得到不同的
Z
Z
Z
。我们认为一组线性变化提取的是一个维度的特征,采用多组可以从更高维来提取更多的特征。
其中,多个self-attention得到的结果
Z
i
Z_i
Z
i
后续操作如下所示:
拼接后与矩阵
W
o
W^o
W
o
进行线性变化,
四、Residuals与Layer-Normalization
- Residuals:是为了解决多层神经网络训练困难的问题,通过将前一层的信息无差的传递到下一层,可以有效的仅关注差异部分,这一方法之前在图像处理结构如ResNet等中常常用到。 Transformer的层数较多,反向传播时容易出现梯度消失与梯度爆炸,所以添加Residuals,防止信息的丢失与梯度回传的消失
- Layer Normalization:在每个block中,最后出现的是Layer Normalization。Layer Normalization是一个通用的技术,其本质是规范优化空间,加速收敛。当我们使用梯度下降法做优化时,随着网络深度的增加,数据的分布会不断发生变化,为了保证数据特征分布的稳定性,我们加入Layer Normalization,这样可以加速模型的优化速度。
五、Decoder structure of Transformer
这里我们着重介绍Mask self-attention与Encoder-decoder attention
1.Mask self-attention
训练时,decoder端是一次性输入,但是在测试/生成,是不知道后面的token的,需要一个个预测出来,在每一个时间步,将已经生成的输入到桶里面去。在推理阶段,token是按照从左往右的顺序推理的。也就是说,在推理
t
i
m
e
s
t
e
p
=
T
timestep=T
t
i
m
e
s
t
e
p
=
T
的token时,decoder只能“看到”
t
i
m
e
s
t
e
p
<
T
timestep < T
t
i
m
e
s
t
e
p
<
T
的
T
−
1
T-1
T
−
1
个Token, 不能和timestep大于它自身的token做attention(因为根本还不知道后面的token是什么)。为了保证训练时和推理时的一致性,所以,训练时要同样防止token与它之后的token去做attention。Decoder端的Mask的功能是为了
保证训练阶段和推理阶段的一致性
。这里的Mask与encoder端的Mask类似,一个是控制padding部分权重为0;一个是控制后续token部分权重为0。训练的时候需要Mask,预测的时候不需要Mask。
2.Encoder-decoder attention
Encoder-decoder attention的输入:它的Q来自于之前一级的decoder层的输出,但K和V来自于encoder的输出,这使得decoder的每一个位置都可以attend到输入序列的每一个位置。
下面展示Encoder-decoder attention的预测过程:
3. 总结
decoder的训练过程:decoder端是一次性输入,经过Mask self-attention得到处理后的输入。decoder的预测过程:会将上一时间步decoder的输出输入到下一时间步中,如上面的预测过程。
六、Word Embedding and position encoding
通过前面encoder部分,我们可以发现:encoder端并行输入,没有了序列信息,此时,就需要position encoding。position encoding只在encoder端和decoder端的embedding之后,第一个block之前出现,它非常重要,没有这部分,Transformer模型就无法用。position encoding是Transformer框架中特有的组成部分,
补充了Attention机制本身不能捕捉位置信息的缺陷
。为了更好的让模型学习位置信息,所以添加了position encoding并将其叠加在word embedding上。
该论文中选取了三角函数的encoding方式:
p
o
s
pos
p
o
s
表示的是在这句话的第几个位置,
i
i
i
表示的是在embedding的第几个维度。所以,通过三角函数,可以计算出这句话的每一个位置的每一个维度的值。这样计算的优势是:使模型轻松学到相对位置,因为对于任意的偏移量
k
k
k
,
P
E
p
o
s
+
k
PE_{pos+k}
P
E
p
o
s
+
k
可以由
P
E
p
o
s
PE_{pos}
P
E
p
o
s
的线性表示,同时,这个模型与可学习到的位置编码相比,可以解决sequence长度更长的位置信息。
三角函数可视化结果为:
注意:position encoding在训练过程中是固定的
。
七、扩展
为什么Transformer会work?
- Transformer做到内部之间的相互attention
- Transformer能够解决RNN/LSTM模型的长期依赖问题
- Transformer是大模型,有更多的参数,可以提取更高维的信息,学到更好的表征
- 利用self attention思想,结合预训练模型,能够产生语言学预训练知识,为后面的预训练模型提供了框架的基础,能方便下游任务做一个快速的finetune。
参考
- 贪心课程中老师讲解的Transformer
-
Attention机制详解(二)——Self-Attention与Transformer
-
【经典精读】Transformer模型深度解读
-
The Illustrated Transformer
-
pytorch tutorial
如果对您有帮助,麻烦点赞关注,这真的对我很重要!!!如果需要互关,请评论或者私信!