Attention

目录

1. Attention

1.1 Attention应运而生:解决信息过长时信息丢失的问题

1.2 通过翻译Tom chase Jerry揭示Attention的算法流程

1.3 Attention的算法流程总结:通过计算相似性得出权重最后加权求和

2 Self-Attention

2.1 什么是自注意力机制:从宏观视角看自注意力机制

2.2 通过向量计算自注意力:先三个向量后计算得分且softmax最后加权求和

2.2.1 计算自注意力第一步:生成查询向量、键向量和值向量向量

2.2.2  计算自注意力第二步:计算得分

2.2.3  计算自注意力第三步:分数除以8然后softmax下

 self-attention为什么要除以根号d_k

2.2.4  计算自注意力第四步:值向量乘以softmax分数后对加权值向量求和

2.3 通过矩阵运算实现自注意力机制

 3  多头注意力机制“multi-headed” attention


1. Attention

1.1 Attention应运而生:解决信息过长时信息丢失的问题

Encoder(编码器)和 Decoder(解码器)之间只有一个「向量C」来传递信息,且C的长度固定。

比如翻译一段语句,翻译的句子短还好,句子一长呢?当输入句子比较长时,所有语义完全转换为一个中间语义向量C来表示,单词原始的信息已经消失,可想而知会丢失很多细节信息。

所以Encoder-Decoder是有缺陷的,其缺陷在于:当输入信息太长时,会丢失掉一些信息。

而为了解决「信息过长,信息丢失」的问题,Attention 机制就应运而生了。
Attention 模型的特点是 Eecoder 不再将整个输入序列编码为固定长度的「中间向量C」,而是编码成一个向量的序列。引入了Attention的Encoder-Decoder 模型如下图:

  •  从输出的角度讲

每个输出的词Y会受到每个输入的整体影响,不是只受某一个词的影响,毕竟整个输入语句是整体而连贯的,但同时每个输入词对每个输出的影响又是不一样的,即每个输出Y受输入的影响权重不一样,而这个权重便是由Attention计算,也就是所谓的注意力分配系数,计算每一项输入对输出权重的影响大小

  • 从编码的角度讲

在根据给到的信息进行编码时(或称特征提取),不同信息的重要程度是不一样的(可用权重表示),即有些信息是无关紧要的,比如一些语气助词之类的,所以这个时候在编码时,就可以有的放矢,根据不同的重要程度针对性汲取相关信息

1.2 通过翻译Tom chase Jerry揭示Attention的算法流程

再举一个机器翻译的例子,即用Google翻译这句话:Tom chase Jerry

1. 在翻译“杰瑞”的时候,带有注意力机制的模型会体现出英文单词对于翻译当前中文单词不同的影响程度,比如给出类似这样一个概率分布值:(Tom,0.3)(Chase,0.2) (Jerry,0.5),每个英文单词的概率代表了翻译当前单词“杰瑞”时,注意力分配模型分配给不同英文单词的注意力大小(类似我司七月在线开董事会,虽然每个人都有发言权,但对不同议题进行决策时,很明显对具体议题更擅长的人拥有更大的发言权,而这个发言权就像权重一样,不同的人对最终决策结果的产生有着不同大小的影响)

2. 目标句子中的每个单词都应该学会其对应的源语句子中单词的注意力分配概率信息。这意味着在生成每个单词的时候,原先都是相同的中间语义表示C会被替换成根据当前生成单词而不断变化的C_{i}(注:这里就是Attention模型的关键,即由固定的中间语义表示C换成了根据当前输出单词来调整成加入注意力模型的变化的C_{i})。

 生成目标句子单词的过程成了下面的形式:

 而每个C_{i}可能对应着不同的源语句子单词的注意力分配概率分布,比如对于上面的英汉翻译来说,其对应的信息可能如下: 

其中,f_{2}函数代表Encoder对输入英文单词的某种变换函数,比如如果Encoder是用的RNN模型的话,这个f_{2}函数的结果往往是某个时刻输入x_{i}后隐层节点的状态值;g代表Encoder根据单词的中间表示合成整个句子中间语义表示的变换函数,一般的做法中,g函数就是对构成元素加权求和,即下列公式: 

 其中,L_{x}代表输入句子Source的长度,a_{ij}代表在Target输出第i个单词时Source输入句子中第j个单词的注意力分配系数,而h_{j}则是Source输入句子中第j个单词的语义编码。

4.  假设C_{i}下标i就是上面例子所说的“ 汤姆” ,那么L_{x}就是3,h1=f(“Tom”)、h2=f(“Chase”)、h3=f(“Jerry”)分别是输入句子每个单词的语义编码,对应的注意力模型权值则分别是0.6,0.2,0.2,所以g函数本质上就是个加权求和函数。如果形象表示的话,翻译中文单词“汤姆”的时候,数学公式对应的中间语义表示的形成过程类似下图。

这里有一个问题:生成目标句子某个单词,比如“汤姆”的时候,如何知道Attention模型所需要的输入句子单词注意力分配概率分布值呢?就是说“汤姆”对应的输入句子Source中各个单词的概率分布:(Tom,0.6) (Chase,0.2) (Jerry,0.2) 是如何得到的呢?

 为了便于说明,我们假设对非Attention模型的Encoder-Decoder框架进行细化,Encoder采用RNN模型,Decoder也采用RNN模型,这是比较常见的一种模型配置

 那么用下图便可以较为便捷地说明注意力分配概率分布值的通用计算过程。

对于采用RNN的Decoder来说

1. 在时刻i,如果要生成y_{i}单词,我们是可以知道Target在生成y_{i}之前的时刻i-1时,隐层节点在i-1时刻的输出值H_{i-1}的(这是RNN结构的特性,如果忘了RNN结构特性请回顾参考文献3)
2.  而我们的目的是要计算生成y_{i}时输入句子中的单词“Tom”、“Chase”、“Jerry”对y_{i}来说的注意力分配概率分布,那么可以用Target输出句子i-1时刻的隐层节点状态H_{i-1}去一 一和输入句子Source中每个单词对应的RNN隐层节点状态h_{j}进行对比,即通过函数F(h_{j},H_{i-1})来获得目标单词和每个输入单词对应的对齐可能性,这个F函数在不同论文里可能会采取不同的方法,然后函数F的输出经过Softmax进行归一化就得到了符合概率分布取值区间的注意力分配概率分布数值

 1.3 Attention的算法流程总结:通过计算相似性得出权重最后加权求和

再比如,图书馆(source)里有很多书(value),为了方便查找,我们给书做了编号(key)。当我们想要了解漫威(query)的时候,我们就可以看看那些动漫、电影、甚至二战(美国队长)相关的书籍。

 

 为了提高效率,并不是所有的书都会仔细看,针对漫威来说,动漫,电影相关的会看的仔细一些(权重高),但是二战的就只需要简单扫一下即可(权重低)。

将Source中的构成元素想象成是由一系列的<Key,Value>数据对构成,此时给定Target中的某个元素Query,通过计算Query和各个Key的相似性或者相关性,得到每个Key对应Value的权重系数,然后对Value进行加权求和,即得到了最终的Attention数值。

 对Source中元素的Value值进行加权求和,而Query和Key用来计算对应Value的权重系数。

第一步:代表漫威漫画的query 和 代表某本书的key 进行相似度计算(常见的方法包括:求两者的向量点积、求两者的向量Cosine相似性等),得到权值
第二步:将权值进行归一化(将原始计算分值整理成所有元素权重之和为1的概率分布,或者说通过SoftMax的内在机制更加突出重要元素的权重),得到直接可用的权重

第三步:将权重和 value 进行加权求和

 

2 Self-Attention

2.1 什么是自注意力机制:从宏观视角看自注意力机制

在一般任务的Encoder-Decoder框架中,输入Source和输出Target内容是不一样的,比如对于英-中机器翻译来说,Source是英文句子,Target是对应的翻译出的中文句子,Attention机制发生在Target的元素Query和Source中的所有元素之间。

而Self Attention顾名思义,指的不是Target和Source之间的Attention机制,而是Source内部元素之间或者Target内部元素之间发生的Attention机制,也可以理解为Target=Source这种特殊情况下的注意力计算机制。其具体计算过程是一样的,只是计算对象发生了变化而已。
 

下面,咱们再通过一个例子了解自注意力机制的工作原理,假定现在要翻译下列句子:
“The animal didn't cross the street because it was too tired”

上面这个“it”是指的什么呢?它指的是street 还是这个 animal 呢?对人来说很简单的问题(必然是animal,因为animal才可能cross,才可能tired),但是对算法而言并不简单,算法不一定知道it指的是animal还是street。
 

当模型处理单词“it”时,self-attention允许将“it”和“animal”联系起来。当模型处理每个位置的词时,self-attention允许模型看到句子中其他位置有关联或相似的单词/信息作为辅助线索,以更好地编码当前单词。

回想一下RNN对隐藏状态的处理:将之前的隐藏状态与当前位置的输入结合起来。在Transformer中,自注意力机制则将对其他单词的“理解”融入到当前处理的单词中。

要更好的理解句中某个特定单词的含义,你要把它放到整个语境之中去理解,比如通过对上下文的把握

权重表示(权重来自于该词/向量本身跟其他各个词/向量之间的相似度),权重越大的单词代表与『该词』越相关(某种意义上可以认为是越相似),从而对理解『该词』越重要,然后把该词编码为包括该词在内所有词的加权和

2.2 通过向量计算自注意力:先三个向量后计算得分且softmax最后加权求和

 2.2.1 计算自注意力第一步:生成查询向量、键向量和值向量向量

 通过向量方式计算自注意力的第一步,就是从每个编码器的输入向量(即每个单词的词向量)生成三个向量:查询向量query-vec、键向量key-vec、值向量value-vec

 查询向量、键向量、值向量这三个向量的维度在论文中设置的是64,在维度上比词嵌入向量更低,因为词嵌入和编码器的输入/输出向量的维度是512,但也不是必须比编码器输入输出的维数小,这样做主要是为了让后续多头注意力的计算更稳定
(在下文你会看到,transformer通过多头注意力机制multi headed attention,对每个512维的输入向量都设置了8个头,不同的头关注每个输入向量不同的部分,而每个头的维度则是:512/8 = 64,且再多说一句,也可以设置为2个头,不一定非得设置为8个头)

 这三个向量的生成方法是把输入的向量分别乘以三个不同的权重矩阵W^{Q}W^{K}W^{V},得到Q、K、V,而这些权重矩阵是在模型训练阶段中训练出来的「对于权重矩阵W^{Q}/W^{K}/W^{V}如何训练出来的,还是标准老套路:先随机初始化,然后在损失函数中表示出来,最后通过反向传播不断优化学习得出,最终目标是最小化模型的预测误差

举例:  有了权重矩阵后,对于单词X_{1}X_{2}分别而言(假定X1是Thinking,X2是Machines):

  • X_{1}W^{Q}权重矩阵相乘得到与这个单词相关的查询向量q_{1}X_{1}W^{K}权重矩阵相乘得到与这个单词相关的键向量k_{1}X_{1}W^{V}权重矩阵相乘得到与这个单词相关的值向量v_{1}
  • 对于单词X_{2}而言,依上类推:X_{2}分别与W^{Q}W^{K}W^{V}相乘得到该单词的查询向量q_{2}、键向量k_{2}、值向量v_{2}

 

 最终使得输入序列的每个单词各自创建一个查询向量、一个键向量和一个值向量

2.2.2  计算自注意力第二步:计算得分

 例子中的第一个单词“Thinking”(pos#1)计算attention分值,即计算每个词对“Thinking”的打分,这个分决定着编码“Thinking”时(某个固定位置时),应该对其他位置上的单词各自给予多少关注度

这个得分通过“Thinking”所对应的查询向量query和所有词的键向量key,依次乘积得出来。所以如果我们是处理位置最靠前的词的attention分值的话

  • 第一个分数是q1和k1的点积(根据点积结果可以判断q1和k1这个向量的相似性)
  • 第二个分数是q1和k2的点积(根据点积结果可以判断q1和k2这个向量的相似性)
     

 

 2.2.3  计算自注意力第三步:分数除以8然后softmax下

  • 将分数除以8(8是论文中使用的键向量的维数64的平方根,这会让梯度更稳定,也可以使用其它值)(除以)
  • 然后通过softmax传递结果,softmax的作用是使所有单词的分数归一化,得到的分数都是正值且它们的和为1
 self-attention为什么要除以根号d_k

 除以dk 的原因有两点:
dk​是词向量/隐藏层的维度
1、首先要除以一个数,防止输入softmax的值过大,导致偏导数趋近于0;

2、选择根号d_k是因为可以使得q*k的结果满足期望为0,方差为1的分布,类似于归一化

 这个softmax分数决定了在编码当下位置(“Thinking”)时,包括当下位置单词(“Thinking”)在内每个单词的所获得的关注度。显然,正在当下位置上的Thinking获得最高的softmax分数(毕竟自己跟自己最相似嘛,所以编码thinking时对Thinking、Machines的注意力分数分配是:0.88 0.12)。


2.2.4  计算自注意力第四步:值向量乘以softmax分数后对加权值向量求和

 将softmax分值乘以每个值向量,这样操作的意义在于留下我们想要关注的单词的value,并把其他不相关的单词丢掉(例如,让它们乘以0.001这样的小数)

对加权值向量求和,产生“Thinking”的self-attention的输出结果

接下来,针对每个单词都进行上述六个步骤的自注意力得分计算,相当于

1.  先是“Thinking”对应的query(q1)与各个不同的key(k1、k2)计算相似度,然后除以8继而softmax,最后softmax值乘以值向量v1、v2并加权求和
相当于:z_1 = softmax [(q_1k_1)/\sqrt{d_k}] \times v_1 + softmax [(q_1k_2)/\sqrt{d_k}] \times v_2

2.   再是“Machines”对应的query(q2)与各个不同的key(k1、k2)计算相似度,然后也除以8继而softmax,最后softmax值乘以值向量v1、v2并加权求和
相当于:z_2 = softmax [(q_2k_1)/\sqrt{d_k}] \times v_1 + softmax [(q_2k_2)/\sqrt{d_k}] \times v_2

 最终每个词的输出向量z_i都包含了其他词的信息,每个词都不再是孤立的了,而且词与词的相关程度可以通过softmax输出的权重进行分析

 

 所有单词的自注意力计算就完成了,得到的向量就可以传给前馈神经网络。然而实际中,这些计算是以矩阵形式完成的,以便算得更快。下面咱们再看看如何用矩阵实现的。

2.3 通过矩阵运算实现自注意力机制

 第一步是计算查询矩阵、键矩阵和值矩阵。为此,我们将输入词向量合并成输入矩阵X(矩阵的每一行代表输入句子中的一个单词,所以整个矩阵就代表整个句子),将其乘以我们训练的权重矩阵:W^{Q}W^{K}W^{V}「再次提醒:词嵌入向量 (512,或图中的4个格子),和q/k/v向量(64,或图中的3个格子)的大小差异」

 

 最后,由于我们处理的是矩阵,我们可以将步骤2到步骤6合并为一个公式来计算自注意力层的输出,下图是自注意力的矩阵运算形式:

 3  多头注意力机制“multi-headed” attention

为进一步完善自注意力层,下面增加一种叫做“多头”注意力(“multi-headed” attention)的机制,并在两方面提高了注意力层的性能:

1.  它扩展了模型专注于不同位置的能力。编码“Thinking”的时候,虽然最后Z1或多或少包含了其他位置单词的信息,但是它实际编码中把过多的注意力放在“Thinking”单词本身(当然了,这也无可厚非,毕竟自己与自己最相似嘛)
且如果我们翻译一个句子,比如“The animal didn’t cross the street because it was too tired”,我们会想知道“it”和哪几个词都最有关联,这时模型的“多头”注意机制会起到作用
2.  它给出了注意力层的多个“表示子空间”(representation subspaces)
每个注意力头,只关注最终输出序列中一个子空间,互相独立,其核心思想在于,抽取到更加丰富的特征信息

 对于“多头”注意机制,我们有多个查询/键/值权重矩阵集(Transformer使用8个注意力头,因此我们对于每个编码器/解码器有8个“Q K V”的矩阵集合)

每一组都是随机初始化,经过训练之后,输入向量可以被映射到不同的子表达空间中

 在“多头”注意机制下,我们为每个头保持独立的查询/键/值权重矩阵,从而产生不同的查询/键/值矩阵。和之前一样,我们拿X乘以W^{Q}/W^{K}/W^{V}矩阵来产生查询/键/值矩阵。

如果我们做与上述相同的自注意力计算,只需8次不同的权重矩阵运算,我们就会得到8个不同的Z矩阵。

 

 前馈层没法一下子接收8个矩阵,它需要一个单一的矩阵(最终这个单一矩阵类似输入矩阵X那样,矩阵中每个的行向量对应一个单词,比如矩阵的第一行对应单词Thinking、矩阵的第二行对应单词Machines)

 需要一种方法把这8个矩阵合并成一个矩阵。那该怎么做?其实可以直接把这些矩阵拼接在一起,然后乘以一个附加的权重矩阵W^{O}

 

 这几乎就是多头自注意力的全部,接下来把所有矩阵集中展示下,如下图所示

 

 回顾一下之前的一个例子:“The animal didn’t cross the street because it was too tired”,再看一下编码“it”的时候每个头的关注点都在哪里:

 编码it,用两个head的时候:其中一个更关注the animal(注意看图中黄线的指向),另一个更关注tired(注意看图中绿线的指向)

总有一个头会关注到咱们想关注的点,避免在编码it时只重点关注到了the animal,而没重点关注tired。

 把所有的头的注意力都可视化一下,就是下图这样

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值