《Attention Is All You Need》transform算法解读
《Attention is All You Need》是一篇由Vaswani等人于2017年发表的论文,它介绍了一种名为Transformer的新型神经网络架构,这个架构在自然语言处理(NLP)任务中取得了巨大的成功。以下是对这篇论文的学习解读:
自注意力概述
背景
在《Attention is All You Need》之前,大多数NLP任务都是依靠循环神经网络(RNN)和卷积神经网络(CNN)来处理的。这些传统方法虽然在某些方面有效,但它们存在一些局限性,比如难以并行处理、训练时间长,以及在长序列处理上的性能欠佳。
主要思想
论文的核心思想是:我们不需要复杂的循环或卷积操作,只用注意力机制(self-attention)就能解决大多数问题。
注意力机制
注意力机制可以被看作是一种高效的“记忆”系统,它在处理当前数据的同时,能够“注意”到输入序列的不同部分。简单来说,就是在阅读一段文字时,不是一句一句地逐一处理,而是能够快速回顾和关注整段文字的不同部分。
Transformer的结构
Transformer模型由以下主要部分组成:
- 编码器(Encoder):负责接收输入数据并生成表示(向量),这些表示会在后续步骤中被用到。
- 解码器(Decoder):负责将编码器生成的表示转换为目标输出(如翻译任务中的目标语言句子)。
具体来看,编码器和解码器都堆叠了多个相似的层,每一层主要包括以下组件:
- 自注意力(Self-Attention):这是Transformer的核心模块,它使得每个位置的输入都能够参考整个输入序列的其它位置,从而捕捉到全局信息。
- 前馈神经网络(Feed-Forward Neural Network):自注意力模块之后是一个普通的前馈神经网络,它进一步处理和转换数据。
- 残差连接(Residual Connections)和层标准化(Layer Normalization):这些技术帮助优化训练过程并提高模型稳定性。
优点
使用Transformer模型有许多优势,包括:
- 并行处理:与RNN不同,Transformer可以并行处理整个输入序列,显著提升训练速度。
- 长距离依赖捕捉:自注意力机制使得模型能够有效地捕捉到序列中任意位置间的关系,而不用担心序列长度。
- 性能强大:Transformer在许多NLP任务中(如机器翻译)表现出色,并且已经成为许多后续模型(如BERT、GPT-3)的基础。
Transformer模型通过彻底依赖注意力机制,简化了深度学习模型的架构,同时提升了在NLP任务中的性能。这一巨大突破在学术界和工业界引起了广泛关注,并迅速成为了新一代NLP模型的基础。
以下是自注意力的计算步骤
自注意力的计算步骤1 :初始化计算-计算嵌入向量
巧妇难为无米之炊,我们先谈谈米的制作过程,这里面的米就是将字词转换成计算机程序能识别的嵌入向量
什么是嵌入?
嵌入(Embeddings)是一种将高维离散数据(比如单词)映射到一个低维连续向量空间的方法。这种方法使得机器学习模型能够更加高效地处理和理解这些数据。在NLP中,嵌入特别常用于将单词转换为向量,以便神经网络能处理。
通俗解释嵌入过程
为了更容易理解,我们用一个简单的小故事来比喻嵌入过程。
比喻:图书馆中的书架
假设你运营一个图书馆,图书馆中每本书都有一个唯一的编号。但是这些编号并没有告诉你任何关于这些书的内容,只是一个简单的标识符。为了管理这些书,你决定将每本书编码为一个向量,这个向量能表达出书的特征,比如类型、主题、作者等等。
-
创建一个嵌入矩阵
想象你有一个非常大的一张表格(嵌入矩阵),行数是图书馆中的书的数量,列数是每本书的特征数。 -
将编号映射到嵌入向量
现在,每个编号都可以映射到表格中的一行。这一行就是该编号代表的书的特征向量。例如,编号1的书可能被映射到[2.3, 5.1, -0.7, …]这个向量。
真实的嵌入过程
把书换成单词,我们就有了文本中的单词嵌入。以下是具体步骤:
-
准备一个词嵌入矩阵
这是一个大的二维矩阵,它的行数是词汇表中所有单词的数量,列数是你希望嵌入向量的维度(比如300维)。 -
初始化嵌入矩阵
开始时,矩阵中的数值通常是随机初始化的,或者是通过预训练模型初始化的。这个矩阵就是一个词汇表,每个单词都有其对应的向量。 -
生成单词嵌入
假设你有一句话“我爱自然语言处理”,每个单词都映射到嵌入矩阵中的一行得到其嵌入向量。例如,- “我” -> E1 = [0.1, -0.2, 0.5, …]
- “爱” -> E2 = [0.3, 0.4, -0.1, …]
- “自然” -> E3 = [0.2, 0.1, -0.4, …]
- “语言” -> E4 = [0.0, 0.5, 0.3, …]
- “处理” -> E5 = [0.1, -0.1, 0.6, …]
这些向量E1, E2, E3, E4和E5就是输入嵌入。这些嵌入向量可以被输入到神经网络的下一层,用于进一步处理。
直观理解
- 单词编号就像图书馆的书架编号。
- 嵌入向量就像这本书的特征,比如它是什么类型的书、作者是谁等等。
- 嵌入矩阵就像书架,它将每本书的特征排列好。
经过这样的嵌入过程,原本单词的编号就变成了具有丰富语义信息的向量,这让机器学习模型能够更好地理解和处理语言数据。
用数学公式表示嵌入过程
在《Attention Is All You Need》中,嵌入向量的计算方式主要通过以下几步:
- 使用词嵌入矩阵将输入序列中的每个词映射为一个高维向量。
- 通过位置编码引入词的位置信息。
- 将词嵌入向量与位置编码向量相加,以构成最终的输入嵌入。
具体步骤如下:
Token 嵌入
假设输入序列为 { x 1 , x 2 , … , x n } \{x_1, x_2, \ldots, x_n\} {x1,x2,…,xn},其中每个 x i x_i xi 是一个标记。每个标记被映射到一个 d d d维度的嵌入向量空间,记作 E ( x i ) E(x_i) E(xi)。嵌入向量的计算方式可以用一个嵌入矩阵 E ∈ R V × d E \in \mathbb{R}^{V \times d} E∈RV×d 表示,其中 V V V 是词汇表的大小, d d d 是嵌入向量的维度。
E ( x i ) = E [ x i ] E(x_i) = E[x_i] E(xi)=E[xi]
这里 E [ x i ] E[x_i] E[xi] 表示嵌入矩阵中对应 x i x_i xi 的那一行。
位置编码
位置编码是为了注入序列中标记的位置信息。位置编码的公式如下:
对于位置 p o s pos pos 和维度 i i i,位置编码 P E ( p o s , 2 i ) PE(pos, 2i) PE(pos,2i) 和 P E ( p o s , 2 i + 1 ) PE(pos, 2i+1) PE(pos,2i+1) 的计算方式分别为:
P E ( p o s , 2 i ) = sin ( p o s 1000 0 2 i d ) PE(pos, 2i) = \sin \left( \frac{pos}{10000^{\frac{2i}{d}}} \right) PE(pos,2i)=sin(10000d2ipos)
P E ( p o s , 2 i + 1 ) = cos ( p o s 1000 0 2 i d ) PE(pos, 2i+1) = \cos \left( \frac{pos}{10000^{\frac{2i}{d}}} \right) PE(pos,2i+1)=cos(10000d2ipos)
其中 p o s pos pos 是具体的位置(从 0 0 0 到 n − 1 n-1 n−1), i i i 是维度的索引(从 0 0 0 到 d − 1 d-1 d−1), d d d 是嵌入向量的维度。
求和 最终嵌入向量
最终的嵌入向量是嵌入向量 E ( x i ) E(x_i) E(xi) 和对应的 P E ( p o s ) PE(pos) PE(pos) 的和:
Z i = E ( x i ) + P E ( p o s = i ) Z_i = E(x_i) + PE(pos=i) Zi=E(xi)+PE(pos=i)
综上所述,输入序列中的每个标记 x i x_i xi都有一个对应的嵌入向量 Z i Z_i Zi,其包含了标记本身的嵌入和其在序列中的位置编码。这些最终的嵌入向量将被后续的 Transformer 模型使用。
示例演示
下面来一个实际的例子来说明:假设我们的输入序列是 ["I", "am", "GPT"]
,并且每个嵌入向量的维度为4。
1. Token 嵌入
假设我们的嵌入矩阵 E E E 是如下的一个随机矩阵(为了简单理解,实际情况中嵌入矩阵是训练得到的):
E = ( [ 0.1 , 0.2 , 0.3 , 0.4 ] "I" [ 0.2 , 0.1 , 0.4 , 0.3 ] "am" [ 0.3 , 0.4 , 0.1 , 0.2 ] "GPT" ) E = \begin{pmatrix} [0.1, 0.2, 0.3, 0.4] & \text{"I"} \\ [0.2, 0.1, 0.4, 0.3] & \text{"am"} \\ [0.3, 0.4, 0.1, 0.2] & \text{"GPT"} \end{pmatrix} E= [0.1,0.2,0.3,0.4][0.2,0.1,0.4,0.3][0.3,0.4,0.1,0.2]"I""am""GPT"
将序列中的标记映射到嵌入矩阵中,我们得到嵌入向量如下:
- E ( "I" ) = [ 0.1 , 0.2 , 0.3 , 0.4 ] E(\text{"I"}) = [0.1, 0.2, 0.3, 0.4] E("I")=[0.1,0.2,0.3,0.4]
- E ( "am" ) = [ 0.2 , 0.1 , 0.4 , 0.3 ] E(\text{"am"}) = [0.2, 0.1, 0.4, 0.3] E("am")=[0.2,0.1,0.4,0.3]
- E ( "GPT" ) = [ 0.3 , 0.4 , 0.1 , 0.2 ] E(\text{"GPT"}) = [0.3, 0.4, 0.1, 0.2] E("GPT")=[0.3,0.4,0.1,0.2]
2. 位置编码
假设我们的位置编码也有4个维度。对于位置 p o s = 0 , 1 , 2 pos = 0, 1, 2 pos=0,1,2,维度 d = 4 d = 4 d=4,我们计算位置编码如下:
对于位置 p o s = 0 pos = 0 pos=0:
P E ( 0 , 2 i ) = sin ( 0 1000 0 2 i 4 ) = 0 PE(0, 2i) = \sin\left( \frac{0}{10000^{\frac{2i}{4}}} \right) = 0 PE(0,2i)=sin(1000042i0)=0
P E ( 0 , 2 i + 1 ) = cos ( 0 1000 0 2 i 4 ) = 1 PE(0, 2i+1) = \cos\left( \frac{0}{10000^{\frac{2i}{4}}} \right) = 1 PE(0,2i+1)=cos(1000042i0)=1
因此 P E ( 0 ) = [ 0 , 1 , 0 , 1 ] PE(0) = [0, 1, 0, 1] PE(0)=[0,1,0,1]
对于位置 p o s = 1 pos = 1 pos=1:
P E ( 1 , 0 ) = sin ( 1 1000 0 0 4 ) = sin ( 1 ) PE(1, 0) = \sin\left( \frac{1}{10000^{\frac{0}{4}}} \right) = \sin(1) PE(1,0)=sin(10000401)=sin(1)
P E ( 1 , 1 ) = cos ( 1 1000 0 0 4 ) = cos ( 1 ) PE(1, 1) = \cos\left( \frac{1}{10000^{\frac{0}{4}}} \right) = \cos(1) PE(1,1)=cos(10000401)=cos(1)
P E ( 1 , 2 ) = sin ( 1 1000 0 2 4 ) = sin ( 1 0 − 2.5 ) PE(1, 2) = \sin\left( \frac{1}{10000^{\frac{2}{4}}} \right) = \sin(10^{-2.5}) PE(1,2)=sin(10000421)=sin(10−2.5)
P E ( 1 , 3 ) = cos ( 1 1000 0 2 4 ) = cos ( 1 0 − 2.5 ) PE(1, 3) = \cos\left( \frac{1}{10000^{\frac{2}{4}}} \right) = \cos(10^{-2.5}) PE(1,3)=cos(10000421)=cos(10−2.5)
假设 sin ( 1 ) ≈ 0.8415 \sin(1) \approx 0.8415 sin(1)≈0.8415, cos ( 1 ) ≈ 0.5403 \cos(1) \approx 0.5403 cos(1)≈0.5403, sin ( 1 0 − 2.5 ) ≈ 0.00999983 \sin(10^{-2.5}) \approx 0.00999983 sin(10−2.5)≈0.00999983, cos ( 1 0 − 2.5 ) ≈ 0.99995 \cos(10^{-2.5}) \approx 0.99995 cos(10−2.5)≈0.99995,则位置 p o s = 1 pos = 1 pos=1 的位置编码:
P E ( 1 ) = [ 0.8415 , 0.5403 , 0.00999983 , 0.99995 ] PE(1) = [0.8415, 0.5403, 0.00999983, 0.99995] PE(1)=[0.8415,0.5403,0.00999983,0.99995]
类似地,对于位置 p o s = 2 pos = 2 pos=2:
P E ( 2 ) ≈ [ 1.6829 , 0.2919 , 0.0199992 , 0.9998 ] PE(2) \approx [1.6829, 0.2919, 0.0199992, 0.9998] PE(2)≈[1.6829,0.2919,0.0199992,0.9998]
3. 最终嵌入向量
将标记的嵌入向量与位置编码相加:
对于 p o s = 0 pos = 0 pos=0:
Z 0 = E ( "I" ) + P E ( 0 ) = [ 0.1 , 0.2 , 0.3 , 0.4 ] + [ 0 , 1 , 0 , 1 ] = [ 0.1 , 1.2 , 0.3 , 1.4 ] Z_0 = E(\text{"I"}) + PE(0) = [0.1, 0.2, 0.3, 0.4] + [0, 1, 0, 1] = [0.1, 1.2, 0.3, 1.4] Z0=E("I")+PE(0)=[0.1,0.2,0.3,0.4]+[0,1,0,1]=[0.1,1.2,0.3,1.4]
对于 p o s = 1 pos = 1 pos=1:
Z 1 = E ( "am" ) + P E ( 1 ) ≈ [ 0.2 , 0.1 , 0.4 , 0.3 ] + [ 0.8415 , 0.5403 , 0.00999983 , 0.99995 ] ≈ [ 1.0415 , 0.6403 , 0.40999983 , 1.29995 ] Z_1 = E(\text{"am"}) + PE(1) \approx [0.2, 0.1, 0.4, 0.3] + [0.8415, 0.5403, 0.00999983, 0.99995] \approx [1.0415, 0.6403, 0.40999983, 1.29995] Z1=E("am")+PE(1)≈[0.2,0.1,0.4,0.3]+[0.8415,0.5403,0.00999983,0.99995]≈[1.0415,0.6403,0.40999983,1.29995]
对于 p o s = 2 pos = 2 pos=2:
Z 2 = E ( "GPT" ) + P E ( 2 ) ≈ [ 0.3 , 0.4 , 0.1 , 0.2 ] + [ 1.6829 , 0.2919 , 0.0199992 , 0.9998 ] ≈ [ 1.9829 , 0.6919 , 0.1199992 , 1.1998 ] Z_2 = E(\text{"GPT"}) + PE(2) \approx [0.3, 0.4, 0.1, 0.2] + [1.6829, 0.2919, 0.0199992, 0.9998] \approx [1.9829, 0.6919, 0.1199992, 1.1998] Z2=E("GPT")+PE(2)≈[0.3,0.4,0.1,0.2]+[1.6829,0.2919,0.0199992,0.9998]≈[1.9829,0.6919,0.1199992,1.1998]
最终,我们得到了输入序列的嵌入向量:
Z = ( [ 0.1 , 1.2 , 0.3 , 1.4 ] [ 1.0415 , 0.6403 , 0.40999983 , 1.29995 ] [ 1.9829 , 0.6919 , 0.1199992 , 1.1998 ] ) Z = \begin{pmatrix} [0.1, 1.2, 0.3, 1.4] \\ [1.0415, 0.6403, 0.40999983, 1.29995] \\ [1.9829, 0.6919, 0.1199992, 1.1998] \end{pmatrix} Z= [0.1,1.2,0.3,1.4][1.0415,0.6403,0.40999983,1.29995][1.9829,0.6919,0.1199992,1.1998]
自注意力的计算步骤2: 计算其他向量 (Query Key Value)
在自注意力 (Self-Attention) 机制中,对于每个输入嵌入向量,我们需要创建三个向量:查询 (Query) 向量、键 (Key) 向量和值 (Value) 向量。这三个向量用于计算注意力权重和加权平均值。下面详细讲解QKV的计算原理和算法。
2.1 QKV 前置条件:
- 已经计算好的嵌入向量
- QKV权重矩阵,这三个矩阵是经过训练出来的,维度一般比嵌入向量的维度要小。
2.2 查询Q、键K和值V向量计算公式
首先,我们有输入嵌入向量 { Z 1 , Z 2 , … , Z n } \{Z_1, Z_2, \ldots, Z_n\} {Z1,Z2,…,Zn},每个嵌入向量的维度为 d d d。
对于每个输入嵌入向量 Z i Z_i Zi,我们使用三个不同的权重矩阵将其映射到查询、键和值向量。具体来说:
- 查询向量 Q i \mathbf{Q}_i Qi 通过权重矩阵 W Q ∈ R d × d k \mathbf{W}^Q \in \mathbb{R}^{d \times d_k} WQ∈Rd×dk 变换得到。
- 键向量 K i \mathbf{K}_i Ki 通过权重矩阵 W K ∈ R d × d k \mathbf{W}^K \in \mathbb{R}^{d \times d_k} WK∈Rd×dk 变换得到。
- 值向量 V i \mathbf{V}_i Vi 通过权重矩阵 W V ∈ R d × d v \mathbf{W}^V \in \mathbb{R}^{d \times d_v} WV∈Rd×dv 变换得到。
公式如下:
Q i = Z i W Q \mathbf{Q}_i = \mathbf{Z}_i \mathbf{W}^Q Qi=ZiWQ
K i = Z i W K \mathbf{K}_i = \mathbf{Z}_i \mathbf{W}^K Ki=ZiWK
V i = Z i W V \mathbf{V}_i = \mathbf{Z}_i \mathbf{W}^V Vi=ZiWV
其中:
- W Q ∈ R d × d k \mathbf{W}^Q \in \mathbb{R}^{d \times d_k} WQ∈Rd×dk
- W K ∈ R d × d k \mathbf{W}^K \in \mathbb{R}^{d \times d_k} WK∈Rd×dk
- W V ∈ R d × d v \mathbf{W}^V \in \mathbb{R}^{d \times d_v} WV∈Rd×dv
通常,我们选取 d k = d v = d h = d h d_k = d_v = d_h = \frac{d}{h} dk=dv=dh=hd,其中 h h h 是头的数量, d h d_h dh 是每个头的维度。
3.QKV计算示例
还要是刚才[“I”, “am”, “GPT”]的嵌入向量为基准
Z 0 = [ 0.1 , 1.2 , 0.3 , 1.4 ] \mathbf{Z}_0 = [0.1, 1.2, 0.3, 1.4] Z0=[0.1,1.2,0.3,1.4]
Z 1 = [ 1.0415 , 0.6403 , 0.40999983 , 1.29995 ] \mathbf{Z}_1 = [1.0415, 0.6403, 0.40999983, 1.29995] Z1=[1.0415,0.6403,0.40999983,1.29995]
Z 2 = [ 1.9829 , 0.6919 , 0.1199992 , 1.1998 ] \mathbf{Z}_2 = [1.9829, 0.6919, 0.1199992, 1.1998] Z2=[1.9829,0.6919,0.1199992,1.1998]
假设我们的权重矩阵 W Q \mathbf{W}^Q WQ, W K \mathbf{W}^K WK 和 W V \mathbf{W}^V WV 随机初始化如下(实际过程中权重矩阵是不断训练迭代优化的):
W Q = ( 0.1 0.3 0.2 0.4 0.3 0.2 0.4 0.1 ) \mathbf{W}^Q = \begin{pmatrix} 0.1 & 0.3 \\ 0.2 & 0.4 \\ 0.3 & 0.2 \\ 0.4 & 0.1 \end{pmatrix} WQ= 0.10.20.30.40.30.40.20.1
W K = ( 0.2 0.3 0.2 0.1 0.1 0.2 0.3 0.4 ) \mathbf{W}^K = \begin{pmatrix} 0.2 & 0.3 \\ 0.2 & 0.1 \\ 0.1 & 0.2 \\ 0.3 & 0.4 \end{pmatrix} WK= 0.20.20.10.30.30.10.20.4
W V = ( 0.1 0.4 0.2 0.3 0.3 0.2 0.4 0.1 ) \mathbf{W}^V = \begin{pmatrix} 0.1 & 0.4 \\ 0.2 & 0.3 \\ 0.3 & 0.2 \\ 0.4 & 0.1 \end{pmatrix} WV= 0.10.20.30.40.40.30.20.1
1. 计算查询向量(Query Vectors)
对于 Z 0 \mathbf{Z}_0 Z0:
Q 0 = Z 0 W Q = [ 0.1 , 1.2 , 0.3 , 1.4 ] ( 0.1 0.3 0.2 0.4 0.3 0.2 0.4 0.1 ) = [ 0.73 , 0.86 ] \mathbf{Q}_0 = \mathbf{Z}_0 \mathbf{W}^Q = [0.1, 1.2, 0.3, 1.4] \begin{pmatrix} 0.1 & 0.3 \\ 0.2 & 0.4 \\ 0.3 & 0.2 \\ 0.4 & 0.1 \end{pmatrix} = [0.73, 0.86] Q0=Z0WQ=[0.1,1.2,0.3,1.4] 0.10.20.30.40.30.40.20.1 =[0.73,0.86]
对于 Z 1 \mathbf{Z}_1 Z1:
Q 1 = Z 1 W Q = [ 1.0415 , 0.6403 , 0.40999983 , 1.29995 ] ( 0.1 0.3 0.2 0.4 0.3 0.2 0.4 0.1 ) = [ 0.81255 , 0.930397 ] \mathbf{Q}_1 = \mathbf{Z}_1 \mathbf{W}^Q = [1.0415, 0.6403, 0.40999983, 1.29995] \begin{pmatrix} 0.1 & 0.3 \\ 0.2 & 0.4 \\ 0.3 & 0.2 \\ 0.4 & 0.1 \end{pmatrix} = [0.81255, 0.930397] Q1=Z1WQ=[1.0415,0.6403,0.40999983,1.29995] 0.10.20.30.40.30.40.20.1 =[0.81255,0.930397]
对于 Z 2 \mathbf{Z}_2 Z2:
Q 2 = Z 2 W Q = [ 1.9829 , 0.6919 , 0.1199992 , 1.1998 ] ( 0.1 0.3 0.2 0.4 0.3 0.2 0.4 0.1 ) = [ 0.95914 , 1.070234 ] \mathbf{Q}_2 = \mathbf{Z}_2 \mathbf{W}^Q = [1.9829, 0.6919, 0.1199992, 1.1998] \begin{pmatrix} 0.1 & 0.3 \\ 0.2 & 0.4 \\ 0.3 & 0.2 \\ 0.4 & 0.1 \end{pmatrix} = [0.95914, 1.070234] Q2=Z2WQ=[1.9829,0.6919,0.1199992,1.1998] 0.10.20.30.40.30.40.20.1 =[0.95914,1.070234]
2. 计算键向量(Key Vectors)
对于 Z 0 \mathbf{Z}_0 Z0:
K 0 = Z 0 W K = [ 0.1 , 1.2 , 0.3 , 1.4 ] ( 0.2 0.3 0.2 0.1 0.1 0.2 0.3 0.4 ) = [ 0.88 , 0.95 ] \mathbf{K}_0 = \mathbf{Z}_0 \mathbf{W}^K = [0.1, 1.2, 0.3, 1.4] \begin{pmatrix} 0.2 & 0.3 \\ 0.2 & 0.1 \\ 0.1 & 0.2 \\ 0.3 & 0.4 \end{pmatrix} = [0.88, 0.95] K0=Z0WK=[0.1,1.2,0.3,1.4] 0.20.20.10.30.30.10.20.4 =[0.88,0.95]
对于 Z 1 \mathbf{Z}_1 Z1:
K 1 = Z 1 W K = [ 1.0415 , 0.6403 , 0.40999983 , 1.29995 ] ( 0.2 0.3 0.2 0.1 0.1 0.2 0.3 0.4 ) = [ 0.841125 , 0.94969 ] \mathbf{K}_1 = \mathbf{Z}_1 \mathbf{W}^K = [1.0415, 0.6403, 0.40999983, 1.29995] \begin{pmatrix} 0.2 & 0.3 \\ 0.2 & 0.1 \\ 0.1 & 0.2 \\ 0.3 & 0.4 \end{pmatrix} = [0.841125, 0.94969] K1=Z1WK=[1.0415,0.6403,0.40999983,1.29995] 0.20.20.10.30.30.10.20.4 =[0.841125,0.94969]
对于 Z 2 \mathbf{Z}_2 Z2:
K 2 = Z 2 W K = [ 1.9829 , 0.6919 , 0.1199992 , 1.1998 ] ( 0.2 0.3 0.2 0.1 0.1 0.2 0.3 0.4 ) = [ 1.01512 , 1.055972 ] \mathbf{K}_2 = \mathbf{Z}_2 \mathbf{W}^K = [1.9829, 0.6919, 0.1199992, 1.1998] \begin{pmatrix} 0.2 & 0.3 \\ 0.2 & 0.1 \\ 0.1 & 0.2 \\ 0.3 & 0.4 \end{pmatrix} = [1.01512, 1.055972] K2=Z2WK=[1.9829,0.6919,0.1199992,1.1998] 0.20.20.10.30.30.10.20.4 =[1.01512,1.055972]
3. 计算值向量(Value Vectors)
对于 Z 0 \mathbf{Z}_0 Z0:
V 0 = Z 0 W V = [ 0.1 , 1.2 , 0.3 , 1.4 ] ( 0.1 0.4 0.2 0.3 0.3 0.2 0.4 0.1 ) = [ 0.83 , 0.72 ] \mathbf{V}_0 = \mathbf{Z}_0 \mathbf{W}^V = [0.1, 1.2, 0.3, 1.4] \begin{pmatrix} 0.1 & 0.4 \\ 0.2 & 0.3 \\ 0.3 & 0.2 \\ 0.4 & 0.1 \end{pmatrix} = [0.83, 0.72] V0=Z0WV=[0.1,1.2,0.3,1.4] 0.10.20.30.40.40.30.20.1 =[0.83,0.72]
对于 Z 1 \mathbf{Z}_1 Z1:
V 1 = Z 1 W V = [ 1.0415 , 0.6403 , 0.40999983 , 1.29995 ] ( 0.1 0.4 0.2 0.3 0.3 0.2 0.4 0.1 ) = [ 0.91719 , 0.926682997 ] \mathbf{V}_1 = \mathbf{Z}_1 \mathbf{W}^V = [1.0415, 0.6403, 0.40999983, 1.29995] \begin{pmatrix} 0.1 & 0.4 \\ 0.2 & 0.3 \\ 0.3 & 0.2 \\ 0.4 & 0.1 \end{pmatrix} = [0.91719, 0.926682997] V1=Z1WV=[1.0415,0.6403,0.40999983,1.29995] 0.10.20.30.40.40.30.20.1 =[0.91719,0.926682997]
对于 Z 2 \mathbf{Z}_2 Z2:
V 2 = Z 2 W V = [ 1.9829 , 0.6919 , 0.1199992 , 1.1998 ] ( 0.1 0.4 0.2 0.3 0.3 0.2 0.4 0.1 ) = [ 1.03824 , 1.168122 ] \mathbf{V}_2 = \mathbf{Z}_2 \mathbf{W}^V = [1.9829, 0.6919, 0.1199992, 1.1998] \begin{pmatrix} 0.1 & 0.4 \\ 0.2 & 0.3 \\ 0.3 & 0.2 \\ 0.4 & 0.1 \end{pmatrix} = [1.03824, 1.168122] V2=Z2WV=[1.9829,0.6919,0.1199992,1.1998] 0.10.20.30.40.40.30.20.1 =[1.03824,1.168122]
计算结果
因此,对于给定的输入嵌入向量 Z 0 , Z 1 , Z 2 \mathbf{Z}_0, \mathbf{Z}_1, \mathbf{Z}_2 Z0,Z1,Z2,我们得到了以下查询向量、键向量和值向量:
查询向量(Query Vectors):
Q 0 = [ 0.73 , 0.86 ] \mathbf{Q}_0 = [0.73, 0.86] Q0=[0.73,0.86]
Q 1 = [ 0.81255 , 0.930397 ] \mathbf{Q}_1 = [0.81255, 0.930397] Q1=[0.81255,0.930397]
Q 2 = [ 0.95914 , 1.070234 ] \mathbf{Q}_2 = [0.95914, 1.070234] Q2=[0.95914,1.070234]
键向量(Key Vectors):
K 0 = [ 0.88 , 0.95 ] \mathbf{K}_0 = [0.88, 0.95] K0=[0.88,0.95]
K 1 = [ 0.841125 , 0.94969 ] \mathbf{K}_1 = [0.841125, 0.94969] K1=[0.841125,0.94969]
K 2 = [ 1.01512 , 1.055972 ] \mathbf{K}_2 = [1.01512, 1.055972] K2=[1.01512,1.055972]
值向量(Value Vectors):
V 0 = [ 0.83 , 0.72 ] \mathbf{V}_0 = [0.83, 0.72] V0=[0.83,0.72]
V 1 = [ 0.91719 , 0.926682997 ] \mathbf{V}_1 = [0.91719, 0.926682997] V1=[0.91719,0.926682997]
V 2 = [ 1.03824 , 1.168122 ] \mathbf{V}_2 = [1.03824, 1.168122] V2=[1.03824,1.168122]
自注意力计算步骤3:计算分数
3.1分数计算公式
对于序列中的每个位置 i i i 和 j j j,计算它们的点积注意力得分:
score i j = Q i K j ⊤ d k \text{score}_{ij} = \frac{\mathbf{Q}_i \mathbf{K}_j^\top}{\sqrt{d_k}} scoreij=dkQiKj⊤
1. 计算注意力权重
接下来,使用查询向量Q和键向量K计算注意力权重。这通过对每个查询向量 Q i \mathbf{Q}_i Qi 与所有键向量 K j \mathbf{K}_j Kj 的点积来实现:
Attention ( Q i , K j , V j ) = softmax ( Q i K j ⊤ d k ) V j \text{Attention}(\mathbf{Q}_i, \mathbf{K}_j, \mathbf{V}_j) = \text{softmax}\left(\frac{\mathbf{Q}_i \mathbf{K}_j^\top}{\sqrt{d_k}}\right) \mathbf{V}_j Attention(Qi,Kj,Vj)=softmax(dkQiKj⊤)Vj
计算步骤如下:
3.1 点积计算注意力得分
3.2 Softmax计算注意力权重
将得分通过 softmax 函数归一化以获得注意力权重:
α i j = softmax ( score i j ) = exp ( score i j ) ∑ k = 1 n exp ( score i k ) \alpha_{ij} = \text{softmax}(\text{score}_{ij}) = \frac{\exp(\text{score}_{ij})}{\sum_{k=1}^{n} \exp(\text{score}_{ik})} αij=softmax(scoreij)=∑k=1nexp(scoreik)exp(scoreij)
3.3 加权求和值向量
注意力权重用于加权求和值向量:
Z i ′ = ∑ j = 1 n α i j V j \mathbf{Z}'_i = \sum_{j=1}^{n} \alpha_{ij} \mathbf{V}_j Zi′=j=1∑nαijVj
4. 综合步骤
将所有步骤整合起来,一个输入向量 Z i \mathbf{Z}_i Zi 的自注意力计算步骤如下:
- 计算查询、键和值向量:
Q i = Z i W Q \mathbf{Q}_i = \mathbf{Z}_i \mathbf{W}^Q Qi=ZiWQ
K i = Z i W K \mathbf{K}_i = \mathbf{Z}_i \mathbf{W}^K Ki=ZiWK
V i = Z i W V \mathbf{V}_i = \mathbf{Z}_i \mathbf{W}^V Vi=ZiWV
- 计算每对 Q i \mathbf{Q}_i Qi 和 K j \mathbf{K}_j Kj 的注意力得分:
score i j = Q i K j ⊤ d k \text{score}_{ij} = \frac{\mathbf{Q}_i \mathbf{K}_j^\top}{\sqrt{d_k}} scoreij=dkQiKj⊤
- 使用 softmax 计算注意力权重:
α i j = softmax ( score i j ) \alpha_{ij} = \text{softmax}(\text{score}_{ij}) αij=softmax(scoreij)
- 计算加权求和值向量:
Z i ′ = ∑ j = 1 n α i j V j \mathbf{Z}'_i = \sum_{j=1}^{n} \alpha_{ij} \mathbf{V}_j Zi′=j=1∑nαijVj
计算注意力得分
注意力得分计算公式为:
Attention ( Q , K , V ) = softmax ( Q K T d k ) V \text{Attention}(\mathbf{Q}, \mathbf{K}, \mathbf{V}) = \text{softmax}\left(\frac{\mathbf{Q} \mathbf{K}^T}{\sqrt{d_k}}\right) \mathbf{V} Attention(Q,K,V)=softmax(dkQKT)V
设 d k = 3 d_k=3 dk=3。
计算第一个注意力得分:
A 11 = Q 1 ⋅ K 1 T 3 = 0.1 ⋅ 0.11 + 0.2 ⋅ 0.19 + 0.3 ⋅ 0.3 3 ≈ 0.11 + 0.038 + 0.09 3 = 0.218 3 ≈ 0.126 \mathbf{A}_{11} = \frac{\mathbf{Q}_1 \cdot \mathbf{K}_1^T}{\sqrt{3}} = \frac{0.1 \cdot 0.11 + 0.2 \cdot 0.19 + 0.3 \cdot 0.3}{\sqrt{3}} \approx \frac{0.11 + 0.038 + 0.09}{\sqrt{3}} = \frac{0.218}{\sqrt{3}} \approx 0.126 A11=3Q1⋅K1T=30.1⋅0.11+0.2⋅0.19+0.3⋅0.3≈30.11+0.038+0.09=30.218≈0.126
计算其余的注意力得分 A 12 , A 13 , ⋯ \mathbf{A}_{12}, \mathbf{A}_{13}, \cdots A12,A13,⋯ 同理。
得分矩阵:
A = [ A 11 A 12 A 13 A 21 A 22 A 23 A 31 A 32 A 33 ] \mathbf{A} = \begin{bmatrix} \mathbf{A}_{11} & \mathbf{A}_{12} & \mathbf{A}_{13} \\ \mathbf{A}_{21} & \mathbf{A}_{22} & \mathbf{A}_{23} \\ \mathbf{A}_{31} & \mathbf{A}_{32} & \mathbf{A}_{33} \end{bmatrix} A= A11A21A31A12A22A32A13A23A33
假设计算得到 A \mathbf{A} A 为:
A = [ 0.126 0.231 0.352 0.231 0.431 0.550 0.352 0.550 0.640 ] \mathbf{A} = \begin{bmatrix} 0.126 & 0.231 & 0.352 \\ 0.231 & 0.431 & 0.550 \\ 0.352 & 0.550 & 0.640 \end{bmatrix} A= 0.1260.2310.3520.2310.4310.5500.3520.5500.640
然后对 A \mathbf{A} A 的每一行进行 softmax 计算,并分别乘以对应的 V \mathbf{V} V 向量,最后得到注意力得分。
软注意力得分示例:
softmax ( A [ 0 ] ) = [ 0.2 0.3 0.5 ] \text{softmax}(\mathbf{A}[0]) = \begin{bmatrix} 0.2 & 0.3 & 0.5 \end{bmatrix} softmax(A[0])=[0.20.30.5]
最终的加权和:
Attention = [ 0.2 0.3 0.5 ] ⋅ [ V 1 V 2 V 3 ] = 0.2 V 1 + 0.3 V 2 + 0.5 V 3 \text{Attention} = \begin{bmatrix} 0.2 & 0.3 & 0.5 \end{bmatrix} \cdot \begin{bmatrix} \mathbf{V}_1 & \mathbf{V}_2 & \mathbf{V}_3 \end{bmatrix} = 0.2 \mathbf{V}_1 + 0.3 \mathbf{V}_2 + 0.5 \mathbf{V}_3 Attention=[0.20.30.5]⋅[V1V2V3]=0.2V1+0.3V2+0.5V3
如:
Attention 1 = 0.2 [ 0.14 0.22 0.3 ] + 0.3 [ 0.46 0.54 0.6 ] + 0.5 [ 0.78 0.82 0.9 ] \text{Attention}_1 = 0.2 \begin{bmatrix} 0.14 \\ 0.22 \\ 0.3 \end{bmatrix} + 0.3 \begin{bmatrix} 0.46 \\ 0.54 \\ 0.6 \end{bmatrix} + 0.5 \begin{bmatrix} 0.78 \\ 0.82 \\ 0.9 \end{bmatrix} Attention1=0.2 0.140.220.3 +0.3 0.460.540.6 +0.5 0.780.820.9
计算结果:
Attention 1 = [ 0.448 0.576 0.66 ] \text{Attention}_1 = \begin{bmatrix} 0.448 \\ 0.576 \\ 0.66 \end{bmatrix} Attention1= 0.4480.5760.66
依此类推,计算出其余的注意力得分。
假设 d = 4 d = 4 d=4, d k = d v = 2 d_k = d_v = 2 dk=dv=2,输入向量 Z i Z_i Zi 为:
Z 1 = [ 0.1 , 0.2 , 0.3 , 0.4 ] \mathbf{Z}_1 = [0.1, 0.2, 0.3, 0.4] Z1=[0.1,0.2,0.3,0.4]
权重矩阵 W Q , W K , W V \mathbf{W}^Q, \mathbf{W}^K, \mathbf{W}^V WQ,WK,WV 随机初始化为:
W Q = ( 0.1 0.3 0.2 0.4 0.1 0.1 0.2 0.3 ) \mathbf{W}^Q = \begin{pmatrix} 0.1 & 0.3 \\ 0.2 & 0.4 \\ 0.1 & 0.1 \\ 0.2 & 0.3 \end{pmatrix} WQ= 0.10.20.10.20.30.40.10.3
W K = ( 0.4 0.2 0.3 0.1 0.2 0.2 0.1 0.3 ) \mathbf{W}^K = \begin{pmatrix} 0.4 & 0.2 \\ 0.3 & 0.1 \\ 0.2 & 0.2 \\ 0.1 & 0.3 \end{pmatrix} WK= 0.40.30.20.10.20.10.20.3
W V = ( 0.4 0.1 0.3 0.2 0.2 0.3 0.1 0.4 ) \mathbf{W}^V = \begin{pmatrix} 0.4 & 0.1 \\ 0.3 & 0.2 \\ 0.2 & 0.3 \\ 0.1 & 0.4 \end{pmatrix} WV= 0.40.30.20.10.10.20.30.4
计算查询向量:
Q 1 = Z 1 W Q = [ 0.1 , 0.2 , 0.3 , 0.4 ] ( 0.1 0.3 0.2 0.4 0.1 0.1 0.2 0.3 ) = [ 0.17 , 0.29 ] \mathbf{Q}_1 = \mathbf{Z}_1 \mathbf{W}^Q = [0.1, 0.2, 0.3, 0.4] \begin{pmatrix} 0.1 & 0.3 \\ 0.2 & 0.4 \\ 0.1 & 0.1 \\ 0.2 & 0.3 \end{pmatrix} = [0.17, 0.29] Q1=Z1WQ=[0.1,0.2,0.3,0.4] 0.10.20.10.20.30.40.10.3 =[0.17,0.29]
计算键向量:
K 1 = Z 1 W K = [ 0.1 , 0.2 , 0.3 , 0.4 ] ( 0.4 0.2 0.3 0.1 0.2 0.2 0.1 0.3 ) = [ 0.23 , 0.19 ] \mathbf{K}_1 = \mathbf{Z}_1 \mathbf{W}^K = [0.1, 0.2, 0.3, 0.4] \begin{pmatrix} 0.4 & 0.2 \\ 0.3 & 0.1 \\ 0.2 & 0.2 \\ 0.1 & 0.3 \end{pmatrix} = [0.23, 0.19] K1=Z1WK=[0.1,0.2,0.3,0.4] 0.40.30.20.10.20.10.20.3 =[0.23,0.19]
计算值向量:
V 1 = Z 1 W V = [ 0.1 , 0.2 , 0.3 , 0.4 ] ( 0.4 0.1 0.3 0.2 0.2 0.3 0.1 0.4 ) = [ 0.27 , 0.30 ] \mathbf{V}_1 = \mathbf{Z}_1 \mathbf{W}^V = [0.1, 0.2, 0.3, 0.4] \begin{pmatrix} 0.4 & 0.1 \\ 0.3 & 0.2 \\ 0.2 & 0.3 \\ 0.1 & 0.4 \end{pmatrix} = [0.27, 0.30] V1=Z1WV=[0.1,0.2,0.3,0.4] 0.40.30.20.10.10.20.30.4 =[0.27,0.30]
这个过程对于每个输入向量重复,然后计算注意力权重并加权求和即可。希望这个示例能帮助你更好地理解自注意力的计算过程。如果你有更多问题,请随时提问。
计算自注意力(Self-Attention)在Transformer模型中是一个关键步骤,下面通过一个通俗易懂的解释来讲解它的前置条件和主要计算步骤:
前置条件
-
输入嵌入(Embeddings):
首先,你必须有输入序列的嵌入向量,例如一句话中的每个单词都被转换成一个向量。假设我们有一个输入句子“我爱自然语言处理”,经过嵌入层后,每个词会变成一个向量,如 [E1, E2, E3, E4]。 -
查询(Query)、键(Key)和值(Value)向量:
为了计算自注意力,输入嵌入向量需要被进一步转换成三种不同的向量:Query(查询)、Key(键)和Value(值)。这些向量通过嵌入向量与相应的权重矩阵相乘得到:- 查询向量: Q = E ∗ W Q Q = E * W_Q Q=E∗WQ
- 键向量: K = E ∗ W K K = E * W_K K=E∗WK
- 值向量: V = E ∗ W V V = E * W_V V=E∗WV
其中, W Q W_Q WQ、 W K W_K WK、 W V W_V WV 是可训练的权重矩阵。
计算步骤
-
计算相似度分数(Scores):
计算每个词语之间的相似度分数,通常使用查询向量和键向量的点积来实现。如果我们有一个序列中的第i个词和第j个词,那么他们之间的相似度分数计算如下:
s c o r e i j = Q i ⋅ K j T score_{ij} = Q_i \cdot K_j^T scoreij=Qi⋅KjT你可以把这理解为每个词语对其他词语“提出问题”,然后用“键”来衡量问句与词语匹配的程度。
-
缩放分数(Scaling):
为了稳定梯度,点积结果通常会除以一个缩放因子,通常是 d k \sqrt{d_k} dk( d k d_k dk 是键向量的维度)。s c o r e i j = Q i ⋅ K j T d k score_{ij} = \frac{Q_i \cdot K_j^T}{\sqrt{d_k}} scoreij=dkQi⋅KjT
-
归一化得分(Softmax):
对缩放后的分数应用softmax函数,转化为概率分布,确保所有分数的和为1。这些概率分数表示每个词对其他词的注意力权重。
α i j = softmax ( s c o r e i j ) \alpha_{ij} = \text{softmax}(score_{ij}) αij=softmax(scoreij) -
加权求和(Weighted Sum):
使用归一化后的注意力权重 α i j \alpha_{ij} αij对值向量进行加权求和,得到每个词的新的表示。这一步相当于为每个词生成一个新的向量,综合了它与其他所有词的加权信息。
Z i = ∑ j α i j V j Z_i = \sum_{j} \alpha_{ij} V_j Zi=j∑αijVj
示例
假设有一句简单的英文句子 “I love NLP”.
-
输入嵌入: [“I” -> E1, “love” -> E2, “NLP” -> E3]
-
生成查询、键、值向量:
- Q1, Q2, Q3
- K1, K2, K3
- V1, V2, V3
-
计算相似度分数(举例):
- s c o r e 12 = Q 1 ⋅ K 2 T score_{12} = Q1·K2^T score12=Q1⋅K2T
- s c o r e 13 = Q 1 ⋅ K 3 T score_{13} = Q1·K3^T score13=Q1⋅K3T
-
缩放分数: s c o r e 12 d k \frac{score_{12}}{\sqrt{d_k}} dkscore12
-
应用softmax得到权重 α i j \alpha_{ij} αij
-
加权求和值向量得到新的表示 Z 1 Z1 Z1
通过这些步骤,每个词语都变得更加了解整个句子的语义结构,从而在后续处理(如编码和解码)中表现得更好。
解码器中全链接网络中的作用
在Transformer编码器中,全连接网络(Feed-Forward Neural Network, FFNN)就像是一位能把信息“加工”和“提升”的专家。这个网络的主要作用是对已经被初步理解和处理的句子进行进一步的加工,使得模型可以从中提取到更有层次、更深层次的特征。
具体来说,Transformer编码器的流程分为几个步骤,其中全连接网络起到了以下关键作用:
-
进一步处理:
在自注意力(Self-Attention)机制之后,句子中的每个词已经与其他词进行了信息交互。那么在这个基础上,全连接网络会对这些交互后的结果进行更深一步的处理,类似于在基础理解之上进行精细加工。 -
非线性转换:
这个网络由两个线性变换和一个非线性激活函数(比如ReLU)组成。第一个线性变换将输入扩展到一个更高的维度,就像将问题放大来仔细分析,第二个线性变换再将其缩回原来的维度,这是进一步提取有效特征的过程,相当于在放大分析后精炼出核心要点。 -
增强模型的表达能力:
通过这样一级额外的复杂处理,全连接网络帮助模型捕捉到更复杂和抽象的关系,增强了模型理解和表示复杂输入的能力。
举个例子,如果把自注意力机制比作一群人开会,每个人都听取并综合了别人的意见,那么这个全连接网络就像是会后每个人再进行的深度思考和总结,使得每个人的观点更加成熟和精炼。
希望这个解释帮助你更好地理解Transformer编码器中全连接网络的作用!