一、Transformer
以下是Transformer的一些重要组成部分和特点:
自注意力机制(Self-Attention):这是Transformer的核心概念之一,它使模型能够同时考虑输入序列中的所有位置,而不是像循环神经网络(RNN)或卷积神经网络(CNN)一样逐步处理。自注意力机制允许模型根据输入序列中的不同部分来赋予不同的注意权重,从而更好地捕捉语义关系。
多头注意力(Multi-Head Attention):Transformer中的自注意力机制被扩展为多个注意力头,每个头可以学习不同的注意权重,以更好地捕捉不同类型的关系。多头注意力允许模型并行处理不同的信息子空间。
堆叠层(Stacked Layers):Transformer通常由多个相同的编码器和解码器层堆叠而成。这些堆叠的层有助于模型学习复杂的特征表示和语义。
位置编码(Positional Encoding):由于Transformer没有内置的序列位置信息,它需要额外的位置编码来表达输入序列中单词的位置顺序。
残差连接和层归一化(Residual Connections and Layer Normalization):这些技术有助于减轻训练过程中的梯度消失和爆炸问题,使模型更容易训练。
**编码器和解码器:**Transformer通常包括一个编码器用于处理输入序列和一个解码器用于生成输出序列,这使其适用于序列到序列的任务,如机器翻译。
1、多头的意义
**多头注意力机制(Multi-Head Attention)**是 Transformer 模型中的一个关键部分,它通过并行计算多个注意力机制,使模型能够从不同的子空间中提取不同的特征,从而提高模型的表达能力和效果。相比单一的注意力机制,多头注意力有以下几个显著的好处:
self-attention只是使用了一组WQ、WK、WV来进行变换得到查询、键、值矩阵,而Multi-Head Attention使用多组WQ,WK,WV得到多组查询、键、值矩阵,然后每组分别计算得到一个Z矩阵。前馈层只需要一个矩阵,则把得到的8个矩阵拼接在一起,然后用一个附加的权重矩阵 W O W^O WO相乘
具体流程如下:
- 多头计算:
- 使用多组不同的投影矩阵 WiQWQ_iWiQ、WiKWK_iWiK、WiVW^V_iWiV(其中 iii 表示第 iii 个头),将输入序列映射为不同的 Query、Key、Value 向量。假设有 hhh 个头,就会有 hhh 组不同的 WQ、WK、WV。
- 独立计算注意力:
- 每组投影后的查询、键和值,分别执行一次注意力机制(类似于 Self-Attention 的过程),得到每个头的输出 ZiZ_iZi。
- 拼接结果:
- 将所有注意力头的输出 Z1,Z2,…,ZhZ_1, Z_2, \dots, Z_hZ1,Z2,…,Zh 拼接在一起,得到一个更大的矩阵。
- 线性变换:
- 最后将拼接后的矩阵通过一个线性层(线性变换矩阵)再次进行变换,生成最终的输出。
关键点:
- 多头(Multi-Head)指的是多个注意力头。每个头都有自己独立的一组权重 WiQWQ_iWiQ、WiKWK_iWiK、WiVW^V_iWiV,这些权重用于计算不同的查询、键、值向量。
- 每个头会独立执行一次注意力计算,然后通过拼接这些头的输出,再进行一次线性变换得到最终的结果。
1. 捕捉多样化的特征表示
==每个头可以通过不同的线性投影函数,从不同的子空间提取特征。这意味着每个头可以关注输入的不同方面,学习到不同的注意力模式。==例如:
- 一个头可能关注的是局部词之间的关系,比如一个句子中的短距离依赖(例如:
I love apples
中的I
和love
的关系)。 - 另一个头可能会关注句子中的全局依赖关系,捕捉更长距离的依赖(例如:
I went to the store, which was far away.
中的I
和far away
的关系)。
通过多个注意力头,模型可以并行地从不同的角度关注输入序列,从而能够更丰富地表征输入。
2. 稳定学习和减少信息丢失
==单头注意力可能会过于关注某些特定的特征而忽略其他重要的上下文信息,导致模型可能无法捕捉到全局特征。==而多头注意力将查询、键和值向量投影到多个不同的子空间,并对每个子空间的结果进行独立的注意力计算。这可以提高信息的表达丰富性,并通过多个头的加权结果降低信息丢失的风险。
3. 多尺度的信息提取
每个头的投影矩阵可以有不同的参数,这使得每个注意力头可以从不同的尺度和角度捕捉信息:
- 一个注意力头可能关注局部的词语关系;
- 另一个注意力头可以捕捉句子中的长距离依赖关系;
- 第三个头可能专注于句子的语义层级结构。
多头注意力可以让模型在不同的尺度和角度上进行多样化的信息提取。
举例说明:多头注意力的实际意义❤️
场景1:机器翻译
在机器翻译中(如英语翻译为中文),输入是一整句话,输出是另一种语言的句子。模型需要从输入句子中捕捉到多种不同的语义关系,并将其转化为目标语言句子的正确表示。
-
多头注意力在这个过程中能起什么作用?
假设有一句话:The cat sat on the mat.
这句话翻译成中文可能是:
猫坐在垫子上。
- 一个注意力头可能专注于翻译过程中短距离的词语关系,比如**“The cat”** 和 “猫”,捕捉主语和修饰词的关系。
- 另一个头可能关注全句结构关系,确保模型在翻译过程中保持语序和句法一致性。
- 第三个头可能会关注目标语言中的语法规则,例如处理英文的冠词“the”如何在中文中被省略。
通过多个头并行地捕捉句子的不同部分和不同的语义关系,模型可以更好地翻译整个句子,使得翻译结果更加流畅和准确。
场景2:文本分类任务
在文本分类任务中,模型需要对输入的一段文字进行分类,比如情感分析(判断一段文字是积极的还是消极的)。在这个任务中,句子中的某些词语可能是关键,比如:
- “这家餐馆的食物很美味,但服务很差劲。”
在这个句子中,“美味”和“差劲”都对情感分类有重要影响,但它们分别是积极和消极的情感词。
- 多头注意力在这里能起到什么作用?
- 一个注意力头可以专注于积极情感的词语,捕捉“美味”这个词和其周围的上下文关系。
- 另一个头可以专注于消极情感,捕捉“差劲”这个词和其上下文。
- 第三个头可能关注句子的整体结构,分析句子的主语和谓语关系,判断句子的主要情感倾向。
通过多个注意力头并行处理,模型可以从句子中提取出不同层面的情感信息,最终将这些信息整合用于分类决策。
场景3:阅读理解任务
在阅读理解任务中,模型需要根据问题从长文本中找到相关的答案。对于这种任务,多头注意力可以帮助模型捕捉文本中问题和答案的不同关系。
- 例如,问题是:“猫为什么坐在垫子上?”
- 一些注意力头可能专注于理解问题中的关键词 “为什么”和文本中的因果关系。
- 其他注意力头可能关注文本中与“猫”和“垫子”相关的上下文信息。
这样,模型可以更有效地从不同的角度理解文本,并找到正确的答案。
总结:多头注意力的实际意义
好处 | 具体作用 |
---|---|
捕捉多样化的特征表示 | 多个注意力头可以从不同角度学习输入序列的不同特征。 |
稳定学习和减少信息丢失 | 多头并行计算注意力,减少模型仅关注局部信息而忽略全局信息的风险。 |
多尺度的信息提取 | 不同的注意力头可以专注于短距离和长距离依赖,或局部和全局关系。 |
应用于多种任务:机器翻译、文本分类、阅读理解等 | 在不同的任务中多头注意力可以有效提取相关信息,提升模型的表现。 |
通过多头注意力机制,模型能够并行处理和综合不同的信息,从而在各种任务中表现出色。
2、多头的计算结果处理
在多头注意力机制(Multi-Head Attention)中,最终并不是直接将多个头的输出相加,而是进行拼接(Concat),然后通过一个线性变换得到最终的输出。
具体过程如下:
-
每个头的独立注意力计算:
-
给定输入的 Query(Q)、Key(K)和 Value(V),每个注意力头会独立计算它们的注意力输出。
-
对于每个头来说,计算公式是:
Attention ( Q , K , V ) = softmax ( Q K T d k ) V \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V Attention(Q,K,V)=softmax(dkQKT)V
其中 ($ d_k KaTeX parse error: Can't use function '\)' in math mode at position 1: \̲)̲ 是键向量的维度,通常使用缩放… \sqrt{d_k}$ ) 来防止点积值过大。
-
-
拼接(Concat)多头输出:
-
假设有 ( h ) 个头,每个头的输出是一个维度为 ( $d_v $) 的向量。
-
多个头的输出会被拼接(而不是相加)成一个更大的向量,拼接后的向量维度是 ( h × d v h \times d_v h×dv ),即所有头的输出连接在一起。
Concat ( h e a d 1 , h e a d 2 , … , h e a d h ) \text{Concat}(head_1, head_2, \dots, head_h) Concat(head1,head2,…,headh)
例如,如果有 3 个注意力头,每个头的输出维度是 ( d v = 64 d_v = 64 dv=64 ),那么拼接后的向量维度就是 ($ 3 \times 64 = 192 $)。
-
-
线性变换:
-
拼接后的向量会通过一个线性变换投影到模型所需的输出维度,这个线性变换是通过一个矩阵 ( W O W_O WO ) 实现的,公式如下:
Output = Concat ( h e a d 1 , h e a d 2 , … , h e a d h ) W O \text{Output} = \text{Concat}(head_1, head_2, \dots, head_h)W_O Output=Concat(head1,head2,…,headh)WO
其中 ( W_O ) 是一个可学习的投影矩阵,将拼接后的向量转换为所需的输出维度。
-
图示:
多个注意力头输出:
head_1 = [x1_1, x1_2, ..., x1_n]
head_2 = [x2_1, x2_2, ..., x2_n]
head_h = [xh_1, xh_2, ..., xh_n]
拼接:
Concat(head_1, head_2, ..., head_h) = [x1_1, x2_1, ..., xh_1, ..., x1_n, x2_n, ..., xh_n]
线性变换:
Output = Concat(head_1, head_2, ..., head_h) * W_O
通过这种方式,多头注意力可以从不同的角度提取特征,并通过拼接和线性变换将这些特征整合到一起。
总结:
- 多头注意力的每个头会独立进行注意力计算。
- 多个头的输出会被拼接在一起,而不是简单相加。
- 拼接后的向量会通过一个线性变换,得到最终的输出。
这种设计使得 Transformer 模型能够从多个子空间提取不同的特征,并将它们整合起来,增强模型的表示能力。
3、自注意力机制
自注意力的作用:随着模型处理输入序列的每个单词,自注意力会关注整个输入序列的所有单词,帮助模型对本单词更好地进行编码。在处理过程中,自注意力机制会将对所有相关单词的理解融入到我们正在处理的单词中。更具体的功能如下:
**序列建模:**自注意力可以用于序列数据(例如文本、时间序列、音频等)的建模。它可以捕捉序列中不同位置的依赖关系,从而更好地理解上下文。这对于机器翻译、文本生成、情感分析等任务非常有用。
并行计算:自注意力可以并行计算,这意味着可以有效地在现代硬件上进行加速。相比于RNN和CNN等序列模型,它更容易在GPU和TPU等硬件上进行高效的训练和推理。(因为在自注意力中可以并行的计算得分)
**长距离依赖捕捉:**传统的循环神经网络(RNN)在处理长序列时可能面临梯度消失或梯度爆炸的问题。自注意力可以更好地处理长距离依赖关系,因为它不需要按顺序处理输入序列。
自注意力的计算:从每个编码器的输入向量(每个单词的词向量,即Embedding,可以是任意形式的词向量,比如说word2vec,GloVe,one-hot编码)中生成三个向量,即查询向量、键向量和一个值向量。(这三个向量是通过词嵌入与三个权重矩阵即 $ WQ,WK,W^V$ ,相乘后创建出来的)新向量在维度上往往比词嵌入向量更低。
二、RNN缺点
循环神经网络(RNN)在处理序列数据(如时间序列、文本、语音等)方面非常有用,但也存在一些明显的缺点和局限性,尤其是在面对长序列或复杂依赖关系时。以下是 RNN 的主要缺点:
1. 梯度消失和梯度爆炸问题
这是 RNN 最大的缺点之一,尤其是在处理长序列数据时。
-
梯度消失(Vanishing Gradient):当网络进行反向传播时,RNN 中较早时间步的梯度会逐渐衰减,最终接近于零。这意味着网络几乎无法学习到长序列中前面部分的信息,只能聚焦于序列后面的一些近似信息。这使得 RNN 无法有效捕捉长距离依赖。
-
梯度爆炸(Exploding Gradient):与梯度消失相反,梯度爆炸指的是在反向传播过程中,梯度值变得非常大,导致模型参数更新过快,使得网络不稳定并且学习失败。
尽管一些变体(如 LSTM 和 GRU)引入了门控机制,部分缓解了梯度消失和爆炸问题,但对于非常长的序列,仍然可能会遇到这些问题。
2. 难以捕捉长依赖关系
RNN 本质上是顺序处理数据的,即每一步的计算依赖于前一步的输出。因此,它在处理长序列时会逐步累积信息,但在长距离依赖(远距离的输入元素与当前输出相关)问题上表现不佳。这是因为信息逐步传递时会有衰减,导致前面输入的内容无法有效影响后面的输出。
即使是引入了 LSTM 和 GRU 这类改进后的 RNN 变体,尽管能在一定程度上捕捉到长依赖关系,但面对非常长的序列时依然有局限。
3. 顺序计算,缺乏并行化能力
RNN 的一个核心特点是需要按顺序处理序列数据,即每个时间步的输出依赖于前一个时间步的状态。因此,RNN 无法像卷积神经网络(CNN)或 Transformer 一样进行高效的并行计算。
==由于这个顺序性,RNN 的训练和推理过程速度较慢,尤其是在处理长序列时,计算效率显著下降。==这对于需要处理大规模数据的应用(如自然语言处理任务)会成为一个瓶颈。
4. 难以处理非常长的序列
尽管 RNN 理论上可以处理任意长度的序列,但实际应用中,RNN 难以有效处理非常长的序列。这是因为随着序列长度的增加,前面时刻的信息会在传播过程中逐渐丢失,即便是 LSTM 和 GRU 这样的改进模型,也只能捕捉到一定长度的依赖,面对非常长的序列时仍然表现不佳。
5. 缺乏灵活的上下文建模能力
RNN 在处理每个时间步时,只能依赖于从前面时间步传递下来的隐状态(hidden state),因此它对上下文信息的建模能力比较弱,特别是在处理长距离依赖时,容易丢失早期时间步的信息。
相比之下,基于注意力机制的模型(如 Transformer)能够通过自注意力机制直接建立全局依赖关系,灵活地捕捉输入序列中不同位置的相关性。
6. 训练复杂,难以调参
RNN 的训练过程通常比较复杂,尤其是在面对长序列数据时。由于序列数据的顺序性和长依赖关系问题,RNN 需要较长的训练时间,且容易陷入局部最优解。调节超参数(如学习率、梯度裁剪等)也更加困难。
在实践中,RNN 的收敛速度通常较慢,需要大量的调试和调参才能达到较好的效果。
7. RNN 的变种复杂
为了克服 RNN 的缺陷,出现了很多变种,比如 LSTM、GRU 等。这些变体引入了门控机制来缓解梯度消失问题,增强对长依赖关系的捕捉能力。然而,这些模型结构比标准的 RNN 复杂得多,训练开销更大,且难以调试。
8. 推理效率低
由于 RNN 需要逐步处理每个时间步的输入,因此它的推理效率相对较低。特别是在实时应用场景(如语音识别、机器翻译等)中,RNN 的计算延迟可能会影响系统的响应速度。
9. 记忆和上下文限制
RNN 在处理序列时,==每一步的状态都是基于之前的隐状态逐步更新的,这种机制导致它的“记忆”能力有限。如果序列很长,RNN 无法有效保留早期的上下文信息。==即便使用 LSTM 和 GRU 的“记忆”单元,它们在面临极长序列时仍然会有局限。
总结
RNN 的主要缺点包括:
缺点 | 说明 |
---|---|
梯度消失和梯度爆炸问题 | 处理长序列时,梯度更新可能会变得过小或过大,导致训练难以进行。 |
难以捕捉长依赖关系 | 序列过长时,RNN 无法有效记住前面输入的信息,长距离依赖难以建模。 |
顺序计算,缺乏并行化能力 | RNN 需要逐步处理每个时间步,导致无法并行计算,训练和推理速度较慢。 |
难以处理长序列 | RNN 处理非常长的序列时性能不佳,早期输入信息容易丢失。 |
训练复杂,难以调参 | RNN 的训练过程需要大量的调参,且容易陷入局部最优解,训练效率较低。 |
推理效率低 | 由于需要顺序处理序列,推理过程速度慢,无法满足高效推理的需求。 |
记忆和上下文限制 | RNN 在面对长序列时无法有效记住前面时间步的信息,容易丢失上下文。 |
这些问题促使研究人员开发了更有效的模型架构,比如 LSTM、GRU,以及后来出现的 Transformer,它们解决了 RNN 的许多缺陷,尤其在处理长序列和并行计算方面有了显著的改进。
三、为什么每一个输入向量不独享一个w权值
1、输入向量不独享w权值原因
如果每一个输入向量都独享一个独立的权重矩阵 $W_Q、W_K 和 W_V $,即为每个输入单词的词向量都配备单独的 W 权重矩阵,这在理论上是可以的,但在实际应用中会带来很多问题和挑战,主要包括以下几个方面:
1. 参数量急剧增加
假设输入序列长度为 (n),词向量维度为 ( d m o d e l d_{model} dmodel),在没有独立权重矩阵的情况下,$W_Q、W_K 和 W_V $ 矩阵是全局共享的,它们的大小是固定的 ( L × d m o d e l L \times d_{model} L×dmodel)。[ L是自定义的qkv的长度 ]但是,如果每个输入向量都要独享一个权重矩阵,模型需要为每个输入向量都单独分配一组 $W_Q、W_K 和 W_V $矩阵。这样一来,参数量会成倍增加:
- 没有独立权重:参数量为 ( 3 × L × d m o d e l 3 \times L \times d_{model} 3×L×dmodel)。
- 每个输入独享权重:参数量为 ( n × 3 × L × d m o d e l n \times 3 \times L \times d_{model} n×3×L×dmodel)。
对于较长的输入序列(例如自然语言中的句子,序列长度 (n) 可以达到上百),这种独立权重分配的方式会导致参数量急剧增长,模型变得难以训练,并且需要大量的计算资源和存储空间。
2. 难以泛化
共享权重矩阵的一个关键优点是:模型能够通过相同的权重矩阵 WQ、WK、WV 在整个输入序列上进行一致的学习和推断。这种共享机制能够帮助模型更好地泛化到不同的输入场景,因为它们可以学到全局的注意力模式。
如果为每个输入向量都使用独立的权重矩阵,模型只能为每个输入学习到特定的特征,而无法从全局的输入结构中抽象出更通用的模式。这样模型会过拟合到训练数据,无法很好地泛化到未见过的输入。
3. 丧失对输入间关系的理解
在自然语言处理任务中,不同单词之间的关系至关重要。Self-Attention 的核心思想是利用共享的注意力机制来捕捉输入序列中不同单词之间的相互关系。
如果每个输入单词都独享一个权重矩阵,注意力机制将难以有效比较和捕捉不同单词之间的联系。注意力分数的计算依赖于查询(Query)和键(Key)的点积,而这些点积的效果来自于共享的 WQ、WK 矩阵。如果每个单词都拥有独立的权重矩阵,这种机制将失效,模型可能会忽略输入序列中单词间的重要关系。
4. 效率低下
共享权重矩阵的另一个重要优势是计算效率高。在深度学习模型中,使用共享矩阵可以通过矩阵运算进行并行化计算,从而加快训练和推理的速度。而如果每个输入向量都使用独立的权重矩阵,计算将变得非常复杂和冗余,尤其是处理长序列时。
为什么选择共享权重矩阵
通过共享 WQ、WK、WV 权重矩阵,模型可以:
- 节省参数量,使模型在计算上更可行。
- 更好地泛化,因为它学习的是通用的上下文模式,而不是每个单词的特定模式。
- 更高效地捕捉不同单词之间的相互关系,尤其在长序列处理时,能保证模型关注到全局的上下文信息。
- 提高计算效率,能够更快速地训练模型并进行推理。
总结
为每个输入独享一个权重矩阵虽然在理论上可以,但在实践中并不可行,因为这会带来极大的计算开销、参数冗余和模型训练上的挑战。共享的 WQ、WK 和 WV 矩阵使得 Self-Attention 能够以更高效、更泛化的方式来捕捉输入序列中的全局关系,从而使 Transformer 模型在各种自然语言处理任务中表现得非常强大。
2、共享不会导致区分不明显吗
共享权重矩阵确实是一种简化模型的方式,但==并不会导致区分不明显,原因在于自注意力机制(Self-Attention)的核心思想能够有效地捕捉输入之间的细微差异==。以下几点解释了共享权重矩阵为什么不会导致区分不明显:
1. 自注意力机制中的加权求和
在自注意力机制中,虽然所有输入都使用相同的权重矩阵 WQ、WK、WV,但每个输入向量的注意力得分是通过每个向量的**查询(Query)和键(Key)**的点积计算得到的。不同输入的 Query 和 Key 会产生不同的点积值,代表了这些输入之间的相关性。这个相关性经过 Softmax 处理后,会得到不同的注意力权重,然后这些权重用于加权求和对应的 值(Value) 向量。
因此,即使使用相同的权重矩阵,每个输入的位置仍然会根据它与其他位置的相关性得到不同的注意力得分,从而产生不同的输出。换句话说,注意力机制可以动态地根据输入之间的关系调整每个输入向量的输出表示,从而确保了细粒度的区分度。
2. 多头注意力机制的辅助作用
共享权重的同时,多头注意力机制(Multi-Head Attention) 引入了多组独立的 WQ、WK 和 WV 矩阵。每个注意力头可以在不同的子空间中捕捉输入序列的不同特征。
- 通过多头机制,模型能够同时在不同的维度上关注输入序列的不同部分。即使共享了一组权重矩阵,多个注意力头的存在使得模型能够从多角度理解输入,从而提高区分能力。
- 这些头的输出会被拼接在一起,再经过线性变换,增强了模型的整体表达能力。这也意味着,即使在同一个输入序列上,模型也能为不同单词或位置学习到不同的表示方式。
因此,多头注意力的机制能够帮助模型捕捉更复杂的模式和关系,避免单一的注意力头无法有效区分不同输入的问题。
3. 位置编码(Positional Encoding)
Transformer 模型中的词向量(Embedding)本身并不包含位置信息。为了让模型能够理解输入序列的顺序关系,Transformer 引入了位置编码(Positional Encoding)。位置编码为每个位置的向量提供了额外的位置信息,使得每个输入向量不仅依赖于词本身的表示,还依赖于它在序列中的位置。
- 虽然每个输入使用的是相同的投影矩阵进行转换,但由于每个位置的向量加入了独特的位置信息(位置编码),不同位置的向量在注意力机制中的表现会有所不同,从而进一步增加了区分度。
4. 非线性变换与层叠网络
Transformer 中的**前馈神经网络(Feed-Forward Network)和残差连接(Residual Connection)**也在一定程度上增加了模型的区分能力。每个输入在通过自注意力层后,还会经过非线性变换,这有助于为每个输入生成更加独特的表示。此外,Transformer 模型通常会堆叠多个注意力层和前馈层,模型通过多层堆叠逐步增强对不同输入的区分能力。
5. 训练过程中的自适应调整
在训练过程中,模型会通过反向传播不断调整共享权重矩阵 WQ、WK 和 WV,使得这些权重矩阵能够在不同的输入场景下生成有意义的查询、键、值向量。换句话说,模型会逐步学习到不同单词之间的语义关系,调整权重以确保在共享矩阵的前提下,依然能区分出输入序列中各个单词的不同特性。
综上所述:
- 虽然 Transformer 共享 WQ、WK 和 WV 矩阵,但通过自注意力机制、多头注意力、位置编码、层叠网络等设计,它能够有效地区分不同输入的特征。
- 共享权重矩阵并不意味着区分能力会下降,反而让模型可以在合理的参数量下捕捉到丰富的上下文信息和全局依赖关系。
四、位置编码
在 Transformer 模型中,位置编码(Positional Encoding) 的作用是引入序列信息,因为 Transformer 本身并没有像 RNN 那样的顺序依赖结构。因此,位置编码的设计是为了将位置信息传递给模型,同时尽可能保持输入语义的完整性。
你提到的位置编码和词向量的相加方式,确实是 Transformer 中常见的做法之一。那么我们来看一下,为什么这种相加方式不会将原始词向量 “I” 变成 “you” 或其他完全不同的词向量。
1. 位置编码的本质
==位置编码(Positional Encoding)是根据每个输入词在序列中的位置生成的,通常使用正弦和余弦函数。这些函数基于位置生成具有规律性的向量,这些向量并不携带特定的语义信息,而是为模型提供相对位置信息。==例如,如果第一个词的位置是1,第二个词的位置是2,它们对应的编码向量在数值上会不同,但这些值不会显著改变词本身的语义特征。
正弦和余弦函数的一个重要特点是:
- 不同位置生成的编码有不同的频率,但它们是平滑和周期性的。这个平滑的特性有助于模型保持词向量之间的关系,而不会将词向量变得完全不同。
2. 位置编码与词向量相加
相加的方式本质上是将位置编码当作一种“微调”信号添加到词向量中,使得模型在处理时既能利用词向量的语义信息,也能捕获到位置信息。这样不会改变词向量的主要特征(即词的语义),因为位置编码的数值通常较小,并且是以相对规律的方式加到词向量的每个维度上。
例如:
- 假设输入向量 “I” 和位置编码的某一维度加起来的结果可能会让向量稍微发生变化,但这种变化不会使它变成与 “you” 对应的向量,因为语义信息仍主要来自原始词向量。
3. 为什么不会变成另一个词?
-
加法带来的影响有限:位置编码的数值在数值上通常较小,相对较大的语义信息仍保留在词向量中。因此,位置编码的作用是“增强”信息,而不是“替换”信息。
-
语义特征仍占主导:词向量的主要成分仍然来自原始的词语语义。例如,词向量 “I” 和 “you” 在嵌入空间中有不同的位置,它们的向量差异很大。而位置编码只是引入一些位置信息,它的数值无法大到将 “I” 转变为 “you”。因此,位置编码不会将一个词的含义彻底改变成另一个词。
-
模型的理解能力:Transformer 模型通过多层注意力机制和前馈神经网络来学习语义关系,位置编码只是为每一层提供位置参考信息。最终模型通过整体训练来理解序列信息,而不是简单地依赖相加后的词向量。
实例:
1. 词向量 (Embedding) 示例
我们假设词 “I” 和 “you” 的词向量分别如下:
- “I” 的词向量:
[0.2, 0.4, 0.1, 0.3]
- “you” 的词向量:
[0.6, 0.8, 0.7, 0.9]
这些词向量可能是从 Word2Vec 或 GloVe 预训练模型中学到的,表示每个词在嵌入空间中的语义特征。
2. 位置编码 (Positional Encoding) 示例
假设我们使用正弦和余弦函数生成的 4 维位置编码,并将其赋予序列中的两个位置:
- 第一个位置的编码:
[0.01, 0.02, 0.03, 0.04]
(对应于词 “I”)- 第二个位置的编码:
[0.05, 0.06, 0.07, 0.08]
(对应于词 “you”)位置编码的值较小,通常在 0 到 1 的范围内,它们只是对序列中每个词的位置进行编码,告诉模型这些词分别位于第 1 个和第 2 个位置。
3. 位置编码与词向量相加
我们将位置编码与词向量逐元素相加:
对于词 “I”:
[ 0.2 , 0.4 , 0.1 , 0.3 ] + [ 0.01 , 0.02 , 0.03 , 0.04 ] = [ 0.21 , 0.42 , 0.13 , 0.34 ] [0.2, 0.4, 0.1, 0.3] + [0.01, 0.02, 0.03, 0.04] = [0.21, 0.42, 0.13, 0.34] [0.2,0.4,0.1,0.3]+[0.01,0.02,0.03,0.04]=[0.21,0.42,0.13,0.34]
对于词 “you”:
[ 0.6 , 0.8 , 0.7 , 0.9 ] + [ 0.05 , 0.06 , 0.07 , 0.08 ] = [ 0.65 , 0.86 , 0.77 , 0.98 ] [0.6, 0.8, 0.7, 0.9] + [0.05, 0.06, 0.07, 0.08] = [0.65, 0.86, 0.77, 0.98] [0.6,0.8,0.7,0.9]+[0.05,0.06,0.07,0.08]=[0.65,0.86,0.77,0.98]
4. 解释相加结果
在相加位置编码之后,得到的新向量仍然非常接近原始词向量:
- “I” 由
[0.2, 0.4, 0.1, 0.3]
变成了[0.21, 0.42, 0.13, 0.34]
,这个变化非常小,并没有改变原始词向量的语义特征。- “you” 也只是稍微偏移了一点,仍然保持其原始的语义信息。
这表明,相加位置编码只是在词向量的基础上增加了位置信息,而不是对词向量进行大幅修改。这使得模型既可以保留每个词的语义信息,也能够理解每个词在序列中的相对位置。
5. 为何不会把 “I” 变成 “you”
位置编码的数值通常比词向量要小很多,它只是作为位置参考,并不会对词向量的主要特征产生显著的影响。例如,“I” 和 “you” 的词向量差异远大于位置编码带来的微小变化。即使加上位置编码,它们的区别仍然非常明显,因此不会因为相加位置编码而导致 “I” 被模型理解为 “you”。
总结:
位置编码与词向量的相加不会将原始的语义信息彻底改变。位置编码的目的是提供位置信息,并帮助模型更好地理解序列的顺序和依赖关系。由于位置编码的数值较小,且是基于位置生成的平滑函数,它不会导致语义信息被破坏或使词向量变成其他词的向量。
扩展:拼接方式
有些变体模型会选择将位置编码与词向量 拼接 而不是相加,这样可以更加明确地将位置信息和语义信息区分开来。然而,拼接方式并不常见,因为它会增大输入维度,从而增加计算复杂度。
五、ADD&norm
在 Transformer 模型中,Add & Norm(加法和归一化)是一个重要的组成部分,它帮助模型更稳定和更有效地训练。这一模块的主要作用是在每个 Encoder 和 Decoder 的子层之间进行残差连接和层归一化(Layer Normalization),具体可以分为以下两步:
1. Add(加法 / 残差连接)
残差连接(Residual Connection)最初由 He 等人提出,目的是为了解决深度网络训练中梯度消失的问题。具体做法是将输入直接与该子层的输出相加。这确保了模型在每一层后,原始输入信息可以直接传递到后续层,避免信息在深层网络中丢失。
在 Transformer 中,残差连接主要作用于:
- 多头注意力机制之后:多头注意力机制的输出与它的输入进行相加。
- 前馈神经网络之后:前馈神经网络的输出与它的输入进行相加。
具体形式为:
output = sublayer(x) + x
其中 sublayer(x)
是某个子层的输出(比如多头注意力机制或前馈网络的输出),x
是该子层的输入。
作用:
- 信息保留:确保输入信息不被丢失,尤其是在深层网络中,输入可以通过残差直接传递到后续层。
- 梯度流动:帮助解决深度网络中的梯度消失问题,使得深层网络也能被有效训练。
2. Norm(归一化 / 层归一化)
在每次进行残差连接后,模型会进行 层归一化(Layer Normalization),它的作用是归一化输入的每个元素,使其具有相同的均值和方差,确保模型在不同批次的输入之间表现稳定。与批归一化(Batch Normalization)不同,层归一化是在特征维度上进行的归一化,它更适用于序列模型。
假设输入向量是 x
,层归一化的操作如下:
Norm(x) = γ * (x - mean(x)) / sqrt(var(x) + ϵ) + β
mean(x)
和var(x)
是对x
进行求均值和方差。ϵ
是一个小常数,防止除以零。γ
和β
是可学习的参数,用于缩放和平移归一化后的结果。
作用:
- 加速训练:归一化有助于减小梯度爆炸和梯度消失的现象,模型训练更快。
- 稳定性:使每一层的输出在不同的训练批次之间更加一致,增强了模型的鲁棒性。
总结
在 Transformer 模型中的 Add & Norm 模块,主要用于增强模型的深度训练能力和稳定性。通过残差连接,模型能够保留重要的输入信息并避免梯度消失;而通过层归一化,模型能够加速训练并提高输出的一致性。
具体来说:
- Add(加法):通过残差连接直接将输入与输出相加,防止信息丢失。
- Norm(归一化):通过层归一化确保模型在不同批次的输入之间表现稳定,并加快训练。
通常,Add & Norm 模块会出现在多头注意力和前馈神经网络的输出之后。
六、transformer里存在的全连接
全连接层(Fully Connected Layer, FC Layer) 是神经网络中最基本的一种层,通常用于对输入进行线性变换并引入非线性。在全连接层中,每一个输入节点与每一个输出节点之间都有一个连接,因此被称为“全连接”。
CNN 中全连接层的作用
在 CNN 中,全连接层通常位于网络的最后几层,它的主要功能是将卷积层和池化层提取到的高维空间特征向量转化为分类任务的类别概率。具体流程是:
- 卷积和池化操作 提取输入图片的局部特征,产生一个多通道的特征图。
- Flatten(展平):在全连接层之前,特征图(通常是一个三维的张量,如 C×H×WC \times H \times WC×H×W)会被展平成一个一维向量,这个一维向量作为全连接层的输入。
- 全连接层:这个展平后的向量进入全连接层,通过线性变换,将高维特征映射到分类标签的维度。
- Softmax 层(或其他激活函数):最后一个全连接层的输出通常会经过 Softmax 函数,将线性输出转化为概率分布,以确定图像属于哪个类别。
在 Transformer 模型中,全连接层(也称为线性层)在多个地方都会出现,主要用于对向量进行线性变换。在不同的阶段,线性层起到了不同的作用,主要包括在以下几个地方:
1. 前馈神经网络中的全连接层
在每个 Encoder 和 Decoder 模块中,都会包含一个前馈神经网络(Feed-Forward Network,FFN),它是一个典型的全连接神经网络。这个部分是对每个位置的向量进行独立的非线性变换。前馈神经网络通常包含两层全连接层:
- 第一层是线性变换,扩展向量的维度。
- 通过非线性激活函数(通常是ReLU)。
- 第二层是线性变换,缩回到原始维度。
每个 Transformer 的 Encoder 和 Decoder 中都有一个前馈神经网络(FFN),它实际上是一个典型的两层全连接网络,用于对输入的每个位置的向量进行非线性映射。FFN 的输入和输出都是独立作用于序列中的每个位置的向量。它的形式如下:
FFN ( x ) = ReLU ( x W 1 + b 1 ) W 2 + b 2 \text{FFN}(x) = \text{ReLU}(xW_1 + b_1)W_2 + b_2 FFN(x)=ReLU(xW1+b1)W2+b2
- x 是输入向量。
- W 1 W_1 W1 和 W 2 W_2 W2 是权重矩阵(全连接层的权重)。
- b 1 b_1 b1 和 b 2 b_2 b2 是偏置项。
- ReLU \text{ReLU} ReLU是激活函数,用于引入非线性。
前馈神经网络的步骤:
-
第一层全连接层:将输入向量 x 乘以权重矩阵 W 1 W_1 W1 并加上偏置 b 1 b_1 b1,然后通过 ReLU 激活函数进行非线性变换。
h = ReLU ( x W 1 + b 1 ) h = \text{ReLU}(xW_1 + b_1) h=ReLU(xW1+b1)
- 这里的 W 1 W_1 W1 通常会将输入维度从 d model d_{\text{model}} dmodel 映射到一个更高的维度(如 2048 维),以增加模型的表达能力。
-
第二层全连接层:对经过 ReLU 激活后的中间结果 hhh 进行一次线性变换,映射回原始的 d model d_{\text{model}} dmodel维度:
FFN ( x ) = h W 2 + b 2 \text{FFN}(x) = hW_2 + b_2 FFN(x)=hW2+b2
- 这一步的目的是将高维空间中的特征重新映射回原始维度,以便与其他网络层的输入输出保持一致。
-
逐位置计算:FFN 对序列中每个位置的向量独立计算,因此每个位置的特征不会在 FFN 中发生交互。
作用:前馈神经网络是对自注意力机制的输出做进一步的非线性映射,帮助模型更好地捕捉和表达数据的高级特征。
2. 多头注意力机制后的线性变换
在 多头注意力机制(Multi-Head Attention) 之后,会有一个线性层来整合来自多个注意力头的结果。在多头注意力中,每个头会计算出一个向量 Z
,这些 Z
向量会被拼接(concatenate)在一起,然后通过一个全连接层来压缩回原始的维度 d_model
。
在 多头注意力机制(Multi-Head Attention) 中,我们会将输入的查询(Q)、键(K)和值(V)矩阵经过多个注意力头的并行计算。每个注意力头会独立生成一个输出向量。为了将这些多个注意力头的结果整合为一个输出,我们需要通过全连接层进行线性变换。
步骤如下:
-
并行计算多头注意力:假设有 n 个注意力头,每个注意力头输出一个 d model / n d_{\text{model}}/n dmodel/n 维度的向量。将这些头的输出拼接起来,形成一个大小为 d model d_{\text{model}} dmodel的向量。
- 如果 d model = 512 d_{\text{model}} = 512 dmodel=512,有 8 个头,每个头的输出大小为 64 维。拼接后输出的大小仍然是 512 维。
-
线性变换(全连接层):为了整合多头注意力的结果,并将其映射回原始的输入维度 d model d_{\text{model}} dmodel,我们需要对拼接后的输出应用一个全连接层。这个全连接层的形式是(拼接后的 512 维向量再乘以权重矩阵 W O W_O WO,产生一个新的 512 维输出向量。假设经过变换后的新向量为):
MultiHeadOutput = Concat ( h e a d 1 , h e a d 2 , … , h e a d n ) W O \text{MultiHeadOutput} = \text{Concat}(head_1, head_2, \dots, head_n)W_O MultiHeadOutput=Concat(head1,head2,…,headn)WO
- 其中 W O W_O WO 是一个全连接层的权重矩阵,负责将拼接后的多头注意力输出转换为与输入相同维度的向量。该过程保持模型的维度一致性。
作用:这一步将来自多个头的注意力结果结合在一起,保证输出的维度与输入的一致,便于后续的处理。
3. Transformer 最后的线性层 + Softmax
Transformer 模型的最后部分,也就是在 Decoder 输出得到最终预测结果时,会有一个线性层(Linear)和Softmax层。这个步骤通常用于分类或者生成任务,例如机器翻译或文本生成。
在 Transformer 的 Decoder 最终需要生成预测结果,这通常通过一个全连接层和 Softmax 层来实现。
步骤如下:
-
线性变换到词汇表维度:Decoder 的输出向量经过多层计算之后,我们需要将其映射到词汇表的大小。假设词汇表大小为 V,那么我们会通过一个全连接层将输出向量从 d model d_{\text{model}} dmodel 维度转换到 V 维度:
Logits = DecoderOutput W vocab + b vocab \text{Logits} = \text{DecoderOutput}W_{\text{vocab}} + b_{\text{vocab}} Logits=DecoderOutputWvocab+bvocab
- 这里 W vocab W_{\text{vocab}} Wvocab 是一个大小为 d model × V d_{\text{model}} \times V dmodel×V的权重矩阵,负责将 Decoder 的输出映射到词汇表的维度。
-
Softmax 生成概率分布:最后,对映射到词汇表维度的向量(Logits)应用 Softmax 函数,生成词汇表中每个词的概率分布,用于预测下一个词:
P ( w ) = exp ( Logits w ) ∑ w ′ ∈ Vocab exp ( Logits w ′ ) \text{P}(w) = \frac{\exp(\text{Logits}_w)}{\sum_{w' \in \text{Vocab}} \exp(\text{Logits}_{w'})} P(w)=∑w′∈Vocabexp(Logitsw′)exp(Logitsw)
- 这里的 Softmax 将 Logits 转换为一个合法的概率分布,表示在词汇表中每个词作为当前词的概率。
- 作用:Softmax 用于将模型的输出转化为一个可解释的概率分布。在机器翻译或文本生成中,Softmax 的输出就是每个单词在词汇表中的概率,模型会选择概率最高的词作为下一个预测词。
4. 总结:Transformer 中的全连接层位置
- 前馈神经网络中的全连接层:每个 Encoder 和 Decoder 内部都包含一个 FFN,它是典型的两层全连接网络,负责对每个位置的向量进行非线性映射。
前馈神经网络(Feedforward Neural Network, FFN) 是一种最基础的神经网络架构,也是所有深度学习模型的基本构成单元之一。前馈神经网络的关键特征是信息从输入层经过隐藏层到输出层是单向的、前向传播的,没有反馈或循环。这意味着输入数据只会经过一次从前到后的传播过程,不会回到前面的层。
- 多头注意力机制后的线性变换:在多头注意力机制中,每个头的输出会经过一个线性层进行整合,以保持维度一致。
- 最终输出层的线性层:在 Decoder 的输出层,经过线性层将模型的输出映射到词汇表的维度,再通过 Softmax 生成每个词的概率分布,用于预测最终的输出结果。
图示总结:
- 输入序列通过编码器,每一层编码器都会有自注意力机制和前馈神经网络(全连接层)。
- 多头注意力的结果通过一个全连接层整合不同头的输出。
- 在模型最后的输出阶段,线性层用于将向量投影到词汇表大小,Softmax 生成概率分布,用于预测输出。