🐬 目录:
- 一、Transformer简介
- 二、理解注意力机制
- 自注意力机制
- 多头注意力机制
一、Transformer简介
Transformer是一种用于自然语言处理(NLP)和其他序列到序列(Seq2Seq)任务的深度学习模型框架,它在2017年由Vaswani等人首次提出。以下是Transformer的一些重要组件和特点。
自注意力机制
:这是Transformer的核心概念之一,它使模型能够同时考虑输入序列中的所有位置,而不是像循环神经网络(RNN)或卷积神经网络(CNN)一样逐步处理。自注意力机制允许模型根据输入序列中的不同部分来赋予不同的注意权重,从而更好地捕捉语义关系。
多头注意力
:Transformer中的自注意力机制被扩展为多个注意力头,每个头可以学习不同的注意权重,以更好地捕捉不同类型的关系。多头注意力允许模型并行处理不同的信息子空间。
堆叠层
:Transformer通常由多个相同的编码器和解码器层堆叠而成。这些堆叠的层有助于模型学习复杂的特征表示和语义。
位置编码
:由于Transformer没有内置的序列位置信息,它需要额外的位置编码来表达输入序列中单词的位置顺序。
残差连接和层归一化
:这些技术有助于减轻训练过程中的梯度消失和爆炸问题,使模型更容易训练。
编码器和解码器
:Transformer通常包括一个编码器用于处理输入序列和一个解码器用于生成输出序列,这使其适用于序列到序列的任务,如机器翻译。
如上图所示,N×表示可以堆叠N个编码器和解码器。一旦输入句子,编码器就会学习其特征并将特征发送给解码器,而解码器又会生成输出句(目标句)。
论文地址:《Attention is all you need》
代码地址
二、理理解注意力机制
Transformer中的编码器不止一个,而是一组N个编码器串联而成。一个编码器的输出作为另一个编码器的输入。原句中的特征会由最后一个编码器输出。编码器模块的主要功能是提取原句中的特征,编码器到底是如何工作的呢?它又是如何提取出原句(输入句)的特征呢?要进一步理解,我们可以将编码器再次分解。下图展示了编码器的组成部分(以N=2为例)。
由上图可知,每一个编码器的构造都是相同的,并且包含两个部分:
👉多头注意力层
👉前馈网络层
现在我们来学习这两部分是如何工作的。要了解多头注意力机制的工作原理,我们首先需要理解什么是自注意力机制
2.1 自注意力机制
A dog ate the food because it was hungry(一只狗吃了食物,因为它很饿)
例句中的代词it(它)可以指代dog,或者food。当阅读这段文字,我们自然而然地认为it指代的是dog而不是food。但是当计算机在面对这两种选择时该如何选择?这时,自注意力机制有助于解决这个问题。具体而言,模型分别计算每个单词的特征值。当计算每个词的特征值时,模型都要遍历该词与句中其他词的关系。通过建模词与词之间的关系来更好理解当前词的意思。如下图所示,当计算it的特征值时,模型会将it与句中其他词一一关联,以便更好地理解它的意思。
如上图所示,it的特征值由它本身与句子中其他词的关系计算所得。通过关系连线,模型可以明确知道原句中it所指dog而不是food,这是因为it与dog的关系更紧密。我们已经初步了解了什么是自注意力机制,下面我们将关注它具体如何实现。
简单起见,我们假设输入句为I am good,首先,我们将每个词转化为对应词嵌入向量,形成输入矩阵X,假设输入矩阵X为:
通过输入矩阵X,我们可以看出,矩阵的第一行表示单词I的嵌入向量,第二行为对应单词am的嵌入向量,第三行对应单词good的词嵌入向量,通过矩阵X,我们再创建三个新的权重矩阵,分别是WQ、WK、WV。值得注意的是,三个权重矩阵的初始值完全是随机的,最优值需要通过训练获得。用矩阵X分别乘以矩阵WQ、WK、WV后就可以依次创建出查询矩阵Q、键矩阵K和值矩阵V。如下图所示。
根据上图,我们可以总结出以下三点:
📌三个矩阵的第一行q1、k1和v1分别代表单词I的查询向量、键向量和值向量。
📌三个矩阵的第一行q2、k2和v2分别代表单词am的查询向量、键向量和值向量。
📌三个矩阵的第一行q3、k3和v3分别代表单词good的查询向量、键向量和值向量。
要计算一个词的特征值,自注意力机制会使该词与给定句中的所有词联系起来,以I am good为例。为了计算单词I
的特征值,需要将I与句中的其他所有单词一一关联,如下图所示。
了解一个词与句中所有词的相关程度有助于更精确地计算特征值。自注意力机制利用查询矩阵、键矩阵和值矩阵将一个词与句中所有词来呢西起来共包含4个步骤
🏃 第一步:计算查询矩阵Q与键矩阵KT的点积
自注意力机制首先计算查询矩阵与键矩阵KT的点击,结果如下图所示:
首先,来看Q ⋅ \cdot ⋅KT矩阵的第一行,如下图所示。可以看到,这一行计算的是查询向量q1(I)与所有的键向量k1(l)、k2(am)和k3(good)的点积。通过计算两个向量的点积可以知道它们之间的相似度
.因此,通过计算查询向量(q1)和键向量(k1、k2、k3)的点积,可以了解单词l与句子中所有单词的相似度。我们了解到,I这个词与自己的关系比与am和good这两个词的关系更紧密,因为点击值q1 ⋅ \cdot ⋅k1大于q1 ⋅ \cdot ⋅k3
🏃 第二步:除以键向量维度获得稳定梯度
自注意力机制的第二步是将Q ⋅ \cdot ⋅KT矩阵除以键向量维度的平方根。这样做的目的主要是获得稳定的梯度。我们用dk表示键向量的维度,然后用Q ⋅ \cdot ⋅KT除以 d k \sqrt{d_k} dk,如下图所示。
🏃 第三步:Softmax函数进行归一化
目前所得的相似度分数尚未被归一化,使用softmax函数对其进行归一化处理,如下图所示,应用softmax函数将数值分布在0到1范围内,且每一行的所有数之和等于1.
上述矩阵被称为分数矩阵,通过这些分数,我们可以了解句子中每个词与所有词的相关程度。以上图所得分数矩阵的第一行为例,I这个词与它本身的相关程度为90%,与am这个词的相关程度是7%,与good这个词的相关程度为3%。
🏃 第四步:计算注意力矩阵Z
自注意力矩阵最后一步是计算注意力矩阵Z。注意力矩阵包括句子中每个单词的注意力值。它可以通过将分数矩阵 s o f t m a x ( Q ⋅ K T / d k ) softmax(Q\cdot K^T/\sqrt{d_k}) softmax(Q⋅KT/dk)乘以值矩阵V得出。如下图所示:
由上图可以看出,注意力矩阵Z就是值向量与分数加权之后求和所得到的结果,假设计算结果如下图所示:
第一行z1对应 I 这个词的自注意力值,它通过以下方法计算所得,单词 I 的自注意力值z1是分数加权的值向量之和。所以,z1的值将包含90%的值向量v1(l)、7%的值向量v2(am),以及3%的值向量v3(good)。因此可以得到单词 I 与句中其他词的相关关系。
同样,am和good也是分数加权的值之和。综上所述,注意力矩阵Z由句子中所有单词的自注意力值组成,它的计算 公式如下:
Z = s o f t m a x ( Q ⋅ K T / d k ) V Z=softmax(Q \cdot K^T/ \sqrt d_k)V Z=softmax(Q⋅KT/dk)V
现将自注意力机制的计算步骤总结如下:
🌟计算查询矩阵与键矩阵的点积 Q ⋅ K T Q \cdot K^T Q⋅KT,求得相似值,称为分数;
🌟将 Q ⋅ K T Q \cdot K^T Q⋅KT除以键向量维度的平方根 d k \sqrt{d_k} dk;
🌟用 s o f t m a x softmax softmax函数对分数进行归一化处理,得到分数矩阵 s o f t m a x ( Q ⋅ K T / d k ) V softmax(Q \cdot K^T/ \sqrt d_k)V softmax(Q⋅KT/dk)V
🌟通过将分数矩阵与值矩阵V相乘,计算出注意力矩阵Z
自注意力机制的计算流程如下图所示,其中,mask为可选操作:
2.2 多头注意力机制
多头注意力是指我们可以使用多个注意力头,而不是只用一个。使用多个注意力矩阵,而非单一的注意力矩阵,可以提高注意力矩阵的准确性。多头注意力机制主要通过两种方式提高了注意力层的性能:❤️ 它扩展了模型关注不同位置的能力,单一注意力机制就像是一个人只能集中精力看一个特定的地方。在句子中,如果我们用单一注意力来理解 “it”,那么我们只能依赖于 “it” 所在的具体位置附近的信息来判断它的含义。相比之下,多头注意力机制就像是同时有多个人,每个人都能独立地看整个句子的不同部分。每个人(即每个注意力头)都能从不同角度和位置上捕捉信息,然后将这些信息整合起来。这样做可以更全面地理解 “it” 是指代哪个词(比如 “dog” 还是 “food”),以及在整个句子中它的角色和意义。
❤️ 它为注意力层提供了多个“表示子空间”。使用多头注意力,我们不仅有一个,而且还有多组查询/键/值权重矩阵(Transformer 使用八个注意力头,所以我们最终每个编码器/解码器都有八个集合) . 这些集合中的每一个都是随机初始化的。然后,在训练之后,每个集合用于将输入嵌入(或来自较低编码器/解码器的向量)投影到不同的表示子空间中。
多头注意力结构如下图所示:
为了计算注意力矩阵,需要创建三个新的矩阵,分别是查询矩阵、键矩阵和值矩阵。为了创建查询矩阵Q1、键矩阵K1和值矩阵V1,我们引入三个新的权重矩阵,称为 W 1 Q W_1^Q W1Q、 W 1 K W_1^K W1K、 W 1 V W_1^V W1V。用矩阵分别乘以 W 1 Q W_1^Q W1Q、 W 1 K W_1^K W1K、 W 1 V W_1^V W1V,就可以依次创建出查询矩阵、键矩阵和值矩阵。基于以上内容,注意力矩阵Z1可以按以下公式计算得出:
Z 1 = s o f t m a x ( Q 1 ⋅ K 1 T / d k ) V 1 Z_1=softmax(Q_1 \cdot K_1^T/ \sqrt d_k)V_1 Z1=softmax(Q1⋅K1T/dk)V1
同理,可以计算出 h 个注意力矩阵。假设我们有8个注意力矩阵,即Z1-Z8,那么可以直接将所有注意力头(注意力矩阵)串联起来,并将结果乘以一个新的权重矩阵W0,从而得出最终的注意力矩阵,公式如下所示:
M u l t i − h e a d a t t e n t i o n = C o n c a t e n a t e ( Z 1 , Z 2 , … , Z i , … Z 8 ) W 0 Multi-head attention = Concatenate(Z_1,Z_2,…,Z_i,…Z_8)W_0 Multi−headattention=Concatenate(Z1,Z2,…,Zi,…Z8)W0