Transformer是一种用于自然语言处理(NLP)和其他序列到序列(Seq2Seq)任务的深度学习模型框架,在2017年由Vaswani等人首次提出。在此之前,RNN结构能够捕获时序信息,但是不能用于并行计算,CNN结构能够并行,但是不能够捕获时序信息。Transformer利用attention代替RNN结构,能够有效地捕捉序列间的长距离依赖关系,还可以实现并行运算,加速模型的计算。
注意力机制
注意力机制是一种处理序列数据时,让模型能够聚焦于输入序列中最重要的部分的技术,这种机制模仿了人类在处理信息时能够集中注意力与某些关键细节的行为。举例来说,假如你现在正在听一场演讲,在听的过程中,你会自然而然地关注某些关键点,比如演讲者提到的一个重要数据或者一个引人深思的观点或者一个印象深刻的故事。这种选择性地聆听并聚焦于某些信息的能力,可以帮助你更好的理解演讲的内容,这就叫做注意力机制。
注意力机制就像是在机器学习模型中的这种能力——它能够让模型在处理输入数据时,关注到其中最重要的部分。在自然语言处理领域,注意力机制被广泛地应用于机器翻译、文本摘要、问答系统等多种任务中。
自注意力机制
自注意力机制之所以被称为“自注意力“, 是因为它允许每个位置的词或符号关注自身的上下文信息,同时也可以关注序列中其他位置的信息。这里的”自“是指每个位置都可以关注自身以及序列中的其他位置,而不仅仅是关注其他位置。从而每个位置上的词都能够更好的理解上下文。
在传统的方法中(例如RNN和LSTM),模型通常只能串行地处理序列中的词,并且难以有效地捕捉长距离依赖关系。相比之下,自注意机制允许模型并行处理序列中所有词,并且通过计算注意力权重来确定哪些词之间存在关联,从而更好地理解输入序列的上下文。
自我关注:在注意力机制中,每个位置上的词都会计算一个与自身关联的注意力权重。这意味着词不仅关注序列中的其他词,而且还关注自身的信息。这种自我关注的能力是自注意力机制的一个关键特性。
相互关注:除了自我关注之外,每个位置上的词还可以关注序列中的其他词。这种相互关注的能力使得模型能够捕捉到输入序列中词与词之间的关系,即使是远距离的依赖关系也能被很好的处理。
上下文相关性:自注意力机制通过计算注意力权重来确定每个词在其上下文中所扮演的角色。这使得模型能够理解词在不同上下文中可能具有的不同含义。
上图为自注意力结构图
自注意力机制基本原理
自注意力机制的核心在于计算不同位置上的词之间的重要性和相关性。这个过程设计到了解查询(Query)、键(Key)和值(Value)的三个基本概念。
查询(Query):代表当前词想要关注的信息(我应该关注什么信息)。
键(Key):代表其他词可以关注的信息(我这里有什么可以被关注)。
值(Value):代表了关注后当前词和其他词的信息(关注之后能得到的信息)。
数学公式
假设输入序列 x i x_i xi表示第 i i i个位置的词向量, W Q , W K , W V W_Q,W_K,W_V WQ,WK,WV分别是用于查询、键和值向量的权重矩阵,则自注意计算可表示为:
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 = x i W Q Q=x_iW_Q Q=xiWQ是序列中第 i i i个位置的词向量×权重矩阵 W Q W_Q WQ,表示查询向量,用于询问“我应该关注什么?”
-
K = x i W K K=x_iW_K K=xiWK是序列中第 i i i个位置的词向量×权重矩阵 W K W_K WK,表示键向量,用于询问“这里有什么可以被关注”
-
V = x i W V V=x_iW_V V=xiWV是序列中第 i i i个位置的词向量×权重矩阵 W V W_V WV,表示值向量,用于询问“关注后能得到的信息。”
-
d K d_K dK是键向量的维度。
权重初始化
注意力权重并不是固定的初始值,而是通过模型训练自动学习到的。注意力权重反映了每个词对其自身和其他词的关注程度,这些权重是在训练过程中动态调整的。
初始值
- 随机初始化:在模型开始训练之前,注意力权重相关的参数通常是随机初始化的(包括查询向量Q、键向量K和值向量V的权重矩阵)。随机初始化是为了打破对称性,让不同的层和节点可以从不同的起点开始学习。
- 常见的初始化方法:常见的初始化方法包括Glorot初始化(Xavier初始化)、He初始化和正态分布初始化等。这些方法旨在保持梯度流的稳定性,避免梯度消失或梯度爆炸问题。
得出初始值的过程
- 参数初始化:在模型构建阶段,会为权重矩阵随机初始化一些值。这些权重矩阵用于计算查询向量、键向量和值向量。
- 前向传播:在训练的每一步中,模型会对输入数据进行前向传播,计算预测输出。
- 损失计算:根据预测输出和真实标签计算损失。
- 反向传播:使用反向传播算法来计算损失相对于模型参数的梯度。
- 权重更新:使用优化器(如Adam、SGD等)根据计算出的梯度来更新模型参数,包括那些用于计算注意力权重的参数。
自注意力机制的工作流程
假设现在我们有一个英文句子:“The cat is sitting on the mat.” 我们可以使用自注意力机制来捕捉句子中不同单词之间的关系。
编码输入
首先将输入序列转换成一系列的向量表示,这些向量可以通过嵌入层或前一层的输出得到,在示例中,假设每个单词都被表示为一个100维的向量。例如:
the
-> [0.08041, 0.1043, …, -0.1210]cat
-> [0.0123, 0.2041, …, 0.05615]is
-> [0.00704, 0.07322, …, 0.1060]sitting
-> [2.1484, 1.0595, …, -7.95898]on
-> [2.6733, -9.08023, …, -7.0845]the
-> [0.08007,0.10457, …, -0.06454]mat
-> [-6.1545, 4.1954, …, 1.11547]
生成Q、K、V向量
对于每个输入位置,通过线性变换(即与权重矩阵相乘)生成对应的查询向量(Query Vector),键向量(Key Vector)和值向量(Value Vector)。为了生成Q、K和V,我们需要三个权重矩阵 W Q , W K 和 W V W_Q,W_K和W_V WQ,WK和WV。这些权重矩阵的大小取决于输入向量的维度(在以上示例中是100维)和我们希望输出的查询、键和值向量的维度(假设也是100维)。这样查询、键和值向量都是100维向量通过不同的线性变换得到。
假设我们已经有了三个权重矩阵:
- W Q W_Q WQ是一个100×100的矩阵,用于生成查询向量。
- W K W_K WK是一个100×100的矩阵,用于生成键向量。
- W V W_V WV是一个100×100的矩阵,用于生成值向量。
计算注意力权重
计算查询向量和键向量之间的相似度得分,通常使用点积操作(即内积),然后将相似度得分除以一个缩放因子(通常是键向量的维度的平方根),最后应用softmax函数将得分转换为概率分布形式,即注意力权重。
以“cat”为例,我们计算它和其他单词的注意力权重。例如“cat”和”mat“都是名词,它们之间的相似度可能会比较高,在原来的句子中cat(猫)是坐在mat(垫子)上的,所以语义之间也有一定的相关性。
对于每个位置 i i i,我们计算它与其他所有位置 j j j的注意力权重 a i j a_{ij} aij:
α i j = s o f t m a x ( Q i K J T d K ) \alpha_{ij}=softmax(\frac{Q_iK^T_J}{\sqrt{d_K}}) αij=softmax(dKQiKJT)
如果我们要计算cat与mat的注意力权重,那么计算方式就是:
α c a t , m a t = s o f t m a x ( Q c a t K m a t T d 1 00 ) \alpha_{cat,mat}=softmax(\frac{Q_{cat}K^T_{mat}}{\sqrt{d_100}}) αcat,mat=softmax(d100QcatKmatT)
这里 d K d_K dK为100,表示维度。
加权求和
将注意力权重与相应的值向量相乘,然后对所有位置的结果进行求和,这个加权求和的结果表示了给定位置的信息,同时考虑了序列中其他位置的影响。计算方式为对于每个位置 i i i,我们用其对应的注意力权重 a i j a_{ij} aij加权求和所有位置的 j j j的值向量 V j V_j Vj:
c i = Σ j = 1 n α i j V j c_i=\Sigma^n_{j=1}\alpha_{ij}V_j ci=Σj=1nαijVj
其中 n n n是序列的长度,在以上的例子中是7(句子中的单词数)。
将cat的注意力权重 α c a t , j \alpha_{cat,j} αcat,j应用于其他单词的值向量 V j V_j Vj,得到一个加权求和的结果 c c a t c_{cat} ccat,这个结果包含了整个句子中其他单词对cat的影响,计算公式如下:
c
c
a
t
=
Σ
j
=
1
7
α
c
a
t
,
j
V
j
c_{cat}=\Sigma^7_{j=1}\alpha_{cat,j}V_j
ccat=Σj=17αcat,jVj
可以理解为对于“cat”,根据其于其他位置
j
j
j的相似度(由注意力权重
α
c
a
t
,
j
\alpha_{cat,j}
αcat,j表示)来整合其他位置的信息。
输出
向量 c c a t c_{cat} ccat包含了关于“cat”在整个句子中的上下文信息,包括它与其他单词的关系,将它作为下一步的输入。
示例解释
在这里我们以单词“cat”为示例,看看自注意力机制是如何利用Q、K和V来确定应该关注的内容的。
- 查询向量(Q):对于“cat”,计算 Q c a t = x c a t W Q Q_{cat}=x_{cat}W_Q Qcat=xcatWQ。这个向量代表了“cat”想要获取什么信息,即“我应该关注什么?”。比如说“cat”是一个名词,它想要关注与之对应的名词或者动词,即“cat”应该怎么样在什么东西上。
- 键向量(K):对于句子中的每个单词,我们都计算对应的键向量 K j = x j W K K_j=x_jW_K Kj=xjWK。这些向量代表了每个单词的特点,即“这里有什么可以被关注”。例如,“mat”的键向量可能与“cat”的查询向量有较高的相似度,因为它们都属于名词。而且“mat”是可以被坐上面的。
- 值向量(V):对于每个单词 j j j,我们计算对应的值向量 V j = x j W V V_j=x_jW_V Vj=xjWV。这些向量包含了如果被关注的话,能提供的信息。例如”mat“的值向量包含关于”mat“的详细信息,包括它与”cat”的关系。比如说“mat”被“cat”关注,说明“mat”是和“cat”有相关关系的,要么坐,要么盖。
Transformer中的自注意力机制
Transformer主要由编码器(Encoder)-解码器(Decoder)两部分组成,编码器负责将输入序列转换为一系列隐藏状态,解码器负责接收编码器的输出,并产生输出序列。
自注意力机制的作用主要有:
在编码器中:
- 捕获上下文信息:自注意力机制允许每个词不仅关注自身,还能关注到序列中的其他词,从而更好的理解每个词在上下文中的意义。
- 并行处理:与传统的递归神经网络(RNN)不同,自注意力机制可以并行处理整个序列,显著加快了训练速度。
- 长距离依赖:自注意力机制特别擅长捕捉长距离依赖关系,这对于处理具有复杂句法结构的句子尤为重要。
- 多头注意力(Multi-head Attention):通过使用多个并行的注意力机制(每个称为一个“头”),模型可以同时考虑不同的注意力分布,从而更全面地理解输入。
在解码器中:
- 自注意力:解码器也使用自注意力机制来关注其输出序列中的各个词,这有助于确保解码器在生成新词时考虑到之前生成的所有词。
- 编码器-解码器注意力:解码器还使用编码器-解码器注意力(Encoder-Decoder Attention),使得解码器能够关注编码器产生的所有隐藏状态,从而更好地生成输出序列。
总结,以上就是关于transformer中自注意力机制的详细说明,希望这篇博客对你理解transformer以及自注意力机制有所帮助,如果你有什么想法,欢迎大家在评论区留言讨论。