当前位置: 首页 > article >正文

跟着问题学18——大模型基础transformer详解(2)多头自注意力机制

 2.2 自注意力机制(Self-attention)

前面我们得到了数据序列的词向量输入,接下来我们就要开始挖掘提取数据中的特征。在前面的RNN系列模型中,我们使用了参数矩阵将单词输入提取特征到当前隐状态里,为了“记忆”前面的信息,把前一个隐状态的特征也使用参数矩阵转换到当前隐状态里,这样二者结合,实现了特征的提取变换。

那么transformer模型也是这样做的吗?不是的,transformer模型不是简单的用一个转换矩阵挖掘单个单词的特征,也不是利用前一时刻隐状态记忆前面的序列数据的特征信息,而是在最开始的时候采用自注意力机制直接挖掘单词本身及序列中其它单词的特征(不再借用上一时刻隐状态这一中间量)。

       为什么要自注意力机制?可以直接获取一个单词和句子中其它单词的关系(相关性)。比如,

“The animal didn't cross the street because it was too tired ”

比如句子中的“it”指的是什么?

我们应该可以很快理解“it”指的是“animal”,但是原先的RNN系列模型并不能识别出这种相关性,在训练过程中,或者遗忘了“animal”这个信息,或者把“animal”和其它单词放在同等的地位,而自注意力机制则可以学习到“it”指的是“animal”。下面我们具体学习一下自注意力机制是如何工作的。

2.2.1 注意力机制

在学习自注意力机制前,我们先学习一下注意力机制。

注意力机制的理解

在Attention诞生之前,已经有CNN和RNN及其变体模型了,那为什么还要引入attention机制?主要有两个方面的原因,如下:

(1)计算能力的限制:当要记住很多“信息“,模型就要变得更复杂,然而目前计算能力依然是限制神经网络发展的瓶颈。

(2)优化算法的限制:LSTM只能在一定程度上缓解RNN中的长距离依赖问题,且信息“记忆”能力并不高。

注意力机制其实是源自于人对于外部信息的处理能力。由于人每一时刻接受的信息都是无比的庞大且复杂,远远超过人脑的处理能力,因此人在处理信息的时候,会将注意力放在需要关注的信息上,对于其他无关的外部信息进行过滤,这种处理方式被称为注意力机制。

从特征的角度考虑就是,对于原始的数据,会挖掘得到其“特征值”(value),这个是描述数据本质特征的向量,这个特征值会对应一个“索引”,类似字典中的键,称为键向量(key),而所谓的注意力就是设置一个查询向量(query),用于查询匹配和前面键向量相似度,然后根据这个相似度赋予对应的值向量一个权重参数,然后加权求和将原始数据特征变换为新的特征。

2.2.1.1非自主提示和自主提示

针对于注意力机制的引起方式(查询向量),可以分为两类,

非自主提示:指的是由于物体本身的特征十分突出引起的注意力倾向,源自于物体本身。

自主提示:指的是经过先验知识的介入下,对具有先验权重的物体引起的注意力倾向,源自于一种主观倾向。

举例说明如下:

 

当我们第一眼看到上图时,我们便会首先将注意力集中到兔子身上。这是因为,整张图中兔子的特征十分的突出,让人一眼就关注到兔子身上。这种引起注意力的方式便是非自主提示。在看到兔子之后,我们便想兔子在干嘛,从而我们就会关注兔子的行为。此时兔子在吃草,这时我们便把注意力集中在兔子周边的草上。这种引起注意力机制的方式便是自主提示,其中"兔子在干嘛"则是我们主观意识。

另外,为加深理解,再引用一下动手学深度学习中的例子解释:

此时我们面前有五个物体,分别是报纸,论文,咖啡,笔记本和书。首先,我们会关注在咖啡身上,因为只有咖啡是红色,而其他物体是黑白。那么红色的咖啡由于其显眼的特征,就成了注意力机制的非自主提示。

喝完咖啡后,十分精神,想看本书。此时,通过"想看书"这种意识,我们将注意力放到了书上。这种通过主观意识引起注意力的方式称为自主提示。

注意力机制的设计

根据自主提示和非自主提示来设计注意力机制。

首先考虑简单情况,即只考虑非自主提示的话,只需要对所有物体的特征信息(非自主提示)进行简单的全连接层,甚至是无参数的平均汇聚层或者最大汇聚层(不需要查询向量),就可以提取出需要感兴趣的物体。

下图是平均汇聚方法的示例图,最后结果是所有物体向量的平均加权和。

而如果考虑自主提示的话,我们就需要设计一种通过查询(Query),键(Key)和值(Value) 来实现注意力机制的方法。其中Query指的是自主提示,即主观意识的特征向量,Key指的是非自主提示,即物体的突出特征信息向量,Value则是代表物体本身的特征向量。

注意力机制是通过Query与Key的注意力汇聚(指的是对Query和Key的相关性进行建模,实现池化筛选或者分配权重),实现对Value的注意力权重分配,生成最终的输出结果。如下图所示:

另外,还有一种理解方式。我们可以将查询,键和值理解为一种软寻址(Soft Addressing)

Value可以看作存储器存储的内容,Key看作是存储器的地址。当Key==Query时,则取出Key地址对应存储器中的Value值,这被称为硬寻址。

而软寻址则是通过计算Key和Query的相似度来进行寻址,这种方法不只是获取一个Key地址中存储器的Value值,而是获取所有的存储器中的Value值的加权和 。至于每个Value的权重(重要程度),是通过Key和Query相似度计算得到的,最终的输出是所有Value值和其权重的加权和。如下图所示:

 

注意力机制模型

从本质上理解,Attention是从大量信息中筛选出少量重要信息,并聚焦到这些重要信息上,忽略大多不重要的信息。权重越大越聚焦于其对应的Value值上,即权重代表了信息相对查询向量的重要性,而Value是其对应的信息。

至于Attention机制的具体计算过程,如果对目前大多数方法进行抽象的话,可以将其归纳为两个过程:

第一个过程是根据Query和Key计算权重系数第二个过程根据权重系数对Value进行加权求和

而第一个过程又可以细分为两个阶段:第一个阶段根据Query和Key计算两者的相似性或者相关性;第二个阶段对第一阶段的原始分值进行归一化处理;这样,可以将Attention的计算过程抽象为如图展示的三个阶段。

在第一个阶段,可以引入不同的函数和计算机制,根据Query和某个 Keyi ,计算两者的相似性或者相关性,第一阶段产生的分值根据具体产生的方法不同其数值取值范围也不一样。最常见的方法包括:求两者的向量点积、求两者的向量Cosine相似性或者通过再引入额外的神经网络来求值,即如下方式:

点积:

Cosine相似性:

MLP网络:

第二阶段引入类似SoftMax的计算方式对第一阶段的得分进行数值转换,一方面可以进行归一化,将原始计算分值整理成所有元素权重之和为1的概率分布;另一方面也可以通过SoftMax的内在机制更加突出重要元素的权重。即一般采用如下公式计算:

第二阶段的计算结果 即为 对应的权重系数,然后进行加权求和即可得到Attention数值:

通过如上三个阶段的计算,即可求出针对Query的Attention数值,目前绝大多数具体的注意力机制计算方法都符合上述的三阶段抽象计算过程。

2.2.2 Self-attention自注意力机制

学习了注意力机制,我们再来看一下自注意力机制。自注意力机制和注意力机制的区别就在于,注意力机制的查询向量和键向量是不同来源的,例如,在Encoder-Decoder模型中,键向量是Encoder中的元素,而查询向量是Decoder中的元素。在中译英模型中,查询向量是中文单词特征,而键向量则是英文单词特征。而自注意力机制的查询向量和键向量则都是来自于同一组的元素,例如,在Encoder-Decoder模型中,查询向量和键向量都是Encoder中的元素,即查询向量和键向量都是中文特征,相互之间做注意力汇聚。也可以理解为同一句话中的词元或者同一张图像中不同的patch,这都是一组元素内部相互做注意力机制,因此,自注意力机制(self-attention)也被称为内部注意力机制(intra-attention),其计算模型和注意力机制基本是一致的,核心区别在于查询向量和键向量的设置。

自注意力机制是注意力机制的变体,其减少了对外部信息的依赖,更擅长捕捉数据或特征的内部相关性。

自注意力机制在文本中的应用,主要是通过计算单词间的互相影响,来解决长距离依赖问题。

优点:可以建立全局的依赖关系,扩大图像的感受野。相比于CNN,其感受野更大,可以获取更多上下文信息。

缺点:自注意力机制是通过筛选重要信息,过滤不重要信息实现的,这就导致其有效信息的抓取能力会比CNN小一些。之所以这样是因为自注意力机制相比CNN,无法利用图像本身具有的尺度,平移不变性,以及图像的特征局部性(图片上相邻的区域有相似的特征,即同一物体的信息往往都集中在局部)这些先验知识,只能通过大量数据进行学习。这就导致自注意力机制只有在大数据的基础上才能有效地建立准确的全局关系,而在小数据的情况下,其效果不如CNN。

2.2.3 Self-attention计算过程

学习自注意力机制模型之后,我们看一下自注意力机制的计算过程(主要是看查询向量q,键向量k,值向量v是如何运算的),还是这个例子:

The animal didn't cross the street because it was too tired

Step1:首先,self-attention会根据编码器的输入向量(每个单词)计算出三个新的向量,分别称为查询向量Query、键向量Key、值向量Value,这三个向量是分别用embedding输入向量(1*512)与三个参数矩阵相乘得到的结果,三个矩阵是随机初始化的,其值在BP的过程中会一直进行更新,维度为(512,64)(使用了多头,详见下面)。

如下图:的维度是(1,512),的维度是(512,64),的维度是(1,64)

计算公式为:

 

 

 

得到的这三个向量的维度是64,低于embedding维度512,但是它们的维度不一定非要更小。这里取64的值更多是为了使得后面拼接多头注意力输出的Z值矩阵维度相同(64*8=512)。如果只是单头注意力的话,维度也可以设为512。

Step2:计算自注意力self-attention的分数值,该分数值决定了当我们在某个位置挖掘变换一个词的特征时,对输入句子的其他部分单词的关注程度。这个分数值的计算方法是查询向量Query与键向量Key做点乘。

以下图为例,首先我们需要针对Thinking这个词,计算出其他词对于该词的一个分数值,首先是针对于自己本身即q1·k1,然后是针对于第二个词即q1·k2

Step3:接下来,把点乘的结果除以一个常数然后把得到的结果做一个softmax的计算。这里我们除以8,这个值一般是采用上文提到的矩阵的列维度的开方即64的开方8,当然也可以选择其他的值。最终得到的结果即是每个词对于当前位置的词的相关性大小,当然,当前位置的词相关性肯定会很大,这些值均为正且和为1.

这种通过 query 和 key 的相似性程度来确定 value 的权重分布的方法被称为scaled dot-product attention。其实scaled dot-Product attention就是我们常用的使用点积进行相似度计算的attention,只是多除了一个(为K的维度)起到调节作用,使得内积不至于太大。

Step4:下一步就是把Value和softmax得到的对应值进行加权求和,得到的结果即是当前单词self-attetion的特征值。

再次以有4个单词的句子为例,首先计算第一个单词作为查询向量和句子中4个单词(包括第一个单词本身)的相关性:

然后将句子中4个单词的值向量加权求和作为这一轮自注意力层挖掘第一个单词的特征向量,

        在计算信息值的时候,是并行计算的,也就意味着一个句子4个单词的特征经过自注意力层全都挖掘提取了,如下。

在实际的应用场景,为了提高计算速度,我们采用的是矩阵的方式,直接计算出Query, Key, Value的矩阵,然后把embedding的值与三个矩阵直接相乘,把得到的新矩阵Q与K相乘,乘以一个常数,做softmax操作,最后乘上V矩阵

最后,用矩阵形式将上述几个步骤统一到下面这个公式里面,即:

2.2.4 多头自注意力机制Multi-head attention

单一注意力机制,只会建立一种查询向量和键向量的依赖关系。而我们常希望可以基于相同的注意力汇聚方法学习到不同的依赖关系(类似于多通道),然后将这些依赖关系组合起来,实现捕获序列内各种范围的依赖关系。

例如,机器翻译任务,以 " I like fishing because it can relax my mind " 要翻译为 " 我喜欢钓鱼,因为可以放松心灵 " 为例,我们以"放松"为Query,对英文句子中每个单词的Key进行注意力汇聚,结果获取"放松"和"relax"的依赖关系。这是单头注意力的结果。

如果我们进行多次注意力汇聚,则可能捕获"放松"和"fishing", "I"等单词的依赖关系。这样,我们将多个结果进行融合就可以得到更为全面,复杂的依赖关系,这对于深度学习下游任务,例如目标检测,语义分割等都具有很大帮助。这就是本章节要介绍的多头注意力汇聚方法。

为了让注意力更好的发挥性能,作者提出了多头注意力的思想,其实就是将每个query、key、value分出来多个分支,有多少个分支就叫多少头(是一个矩阵分成多块,还是多个矩阵),就是说不仅仅只初始化一组Q、K、V的矩阵,而是初始化多组,tranformer是使用了8组,所以最后得到的结果是8个矩阵。对Q, K, V求多次不同的注意力计算,得到多个不同的output,再把这些不同的output拼接起来得到最终的output。

论文通过添加一种称为“多头”注意力的机制,进一步细化了自注意力层。这通过两种方式提高了注意力层的性能:

它扩展了模型注意于不同位置的能力。在上面的例子中,z1包含了每个单词的部分编码,但它可能被自身所支配。如果我们翻译一句话,比如“这只动物没有过马路是因为它太累了”,那么知道“它”指的是哪个词会很有用。

它为注意力层提供了多个“表示子空间”。正如我们接下来将看到的,对于多头注意力,我们不仅有一组,而且有多组查询/键/值权重矩阵(Transformer使用八个注意力头,所以我们最终为每个编码器/解码器使用八组)。这些集合中的每一个都是随机初始化的。然后,在训练之后,使用每个集合将输入嵌入(或来自较低编码器/解码器的向量)投影到不同的表示子空间中。

主要思想就是在于:希望不同注意力的output可以从不同层面(representation subspace)考虑关联性而得到最终的输出。

做8次不同的自注意力层计算,会得到8个Z值矩阵,

这给我们留下了一个小的挑战,前馈神经网络没法输入8个矩阵呀,这该怎么办呢?所以我们需要一种方式,把8个矩阵降为1个,首先,我们把8个矩阵连在一起,这样会得到一个大的矩阵,再随机初始化一个大矩阵和这个组合好的矩阵相乘,最后得到一个最终的矩阵。也就意味着最初求的QKV矩阵也分别是8个。

这就是multi-headed attention的全部流程了,把所有的矩阵放到一张图内看一下总体的流程。

既然我们已经谈到了注意力头,让我们重新审视之前的例子,看看当我们在例句中对单词“it”进行编码时,不同的注意力头会集中在哪里(这里不同颜色代表attention不同头的结果,颜色越深attention值越大):

然而,如果我们把所有的注意力都放在画面上,事情可能会更难解读:

对于使用自注意力机制的原因,论文中提到主要从三个方面考虑(每一层的复杂度,是否可以并行,长距离依赖学习),并给出了和RNN,CNN计算复杂度的比较。可以看到,如果输入序列n(句子中单词数量)小于表示维度d的话,每一层的时间复杂度self-attention是比较有优势的。当n比较大时,作者也给出了一种解决方案self-attention(restricted)即每个词不是和所有词计算attention,而是只与限制的r个词去计算attention。在并行方面,多头attention和CNN一样不依赖于前一时刻的计算,可以很好的并行,优于RNN。在长距离依赖上,由于self-attention是每个词和所有词都要计算attention,所以不管他们中间有多长距离,最大的路径长度也都只是1,可以捕获长距离依赖关系。

2.2.5小结

其总的过程可以概括如下:

1.将输入单词转化成嵌入向量;

2.根据嵌入向量利用参数矩阵得到q,k,v三个向量;

3.为每个向量计算一个score:score =q . k ;

4.为了梯度的稳定,Transformer使用了score归一化,即除以矩阵列维度的开方(论文中是64的开方8) ;

5.对score施以softmax归一化;

6.softmax点乘Value值v,得到加权的每个输入向量的评分v;

7.相加之后得到最终的输出结果z :z= v。

参考资料

The Illustrated Transformer – Jay Alammar – Visualizing machine learning one concept at a time.

李宏毅transformer视频课程

https://zhuanlan.zhihu.com/p/338817680

Transformer:注意力机制(attention)和自注意力机制(self-attention)的学习总结_注意力机制和自注意力机制-CSDN博客

10.1. 注意力提示 — 动手学深度学习 2.0.0 documentation

跟着问题学18——万字长文详解Transformer-CSDN博客

【深度学习】batch normalization和layer normalization区别_layer normalization和batch normaliza


http://www.kler.cn/a/457594.html

相关文章:

  • 深入理解 JVM 的垃圾收集器:CMS、G1、ZGC
  • 线性代数自学资源推荐我的个人学习心得
  • Nacos服务注册和发现
  • 服务器端请求伪造之基本介绍
  • HTML——57. type和name属性
  • 【three.js】材质(Material)
  • Linux 使用入门指南
  • 如何在 Spring Boot 中配置数据库?
  • 【bluedroid】A2dp Source播放流程源码分析(3)
  • C#控件开发2—流动管道
  • 小猫咪抽奖系统源码1.11(有卡密功能)
  • 【潜意识Java】探寻Java子类构造器的神秘面纱与独特魅力,深度学习子类构造器特点
  • 4. 指针和动态内存
  • Pytorch | 利用PC-I-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
  • 【13】Selenium+Python UI自动化测试 集成日志(某积载系统实例-07)
  • 【学习笔记】ChatGPT原理与应用开发——基础科普
  • No.29 笔记 | CTF 学习干货
  • C++ 设计模式:策略模式(Strategy Pattern)
  • 「Mac畅玩鸿蒙与硬件48」UI互动应用篇25 - 简易购物车功能实现
  • 【Spring】基于注解的Spring容器配置——@Scope注解
  • 如何通过采购管理系统提升供应链协同效率?
  • Android Bluetooth 问题:BluetoothAdapter enable 方法失效
  • 【2025最新计算机毕业设计】基于SpringBoot的网上服装商城系统(高质量项目,可定制)【提供源码+答辩PPT+文档+项目部署】
  • 一起来看--红黑树
  • TVS二极管选型【EMC】
  • 从0入门自主空中机器人-2-2【无人机硬件选型-PX4篇】