Transformer:多头注意力驱动的编码器-解码器架构
1.循环神经网络
前文有实现过一个基于循环神经网络的文本分类实践任务,循环神经网络(Recurrent Neural Network, RNN)也叫递归神经网络,是专门处理序列数据的神经网络架构,其核心思想是通过循环连接使网络具备“记忆”能力,从而构建序列中时序之间的依赖关系。而处理具有时序或顺序关系的数据(如语言、语音、基因序列等)的核心挑战是理解序列中的上下文依赖关系,这就涉及到序列建模问题。
1.序列建模问题
与图像处理不同,序列建模关注的是输入数据的时序特性。例如:
- 在时间序列预测中,我们可以根据前几天的指标(如身高、体重、年龄、饮食情况等)来预测未来的身体状态
- 在文本建模任务中,输入为一个个按顺序排列的单词或字符,模型需要捕捉语言的上下文关系
这类任务的共同特点是:输入之间存在时间/位置上的顺序关系,即当前状态往往依赖于过去的信息。
2. RNN 的基本结构与前向传播机制
为了解决这类时序相关问题,RNN 通过引入“记忆”机制,在每个时间步上对当前输入和上一个时间步的隐藏状态共同进行建模。
以时间序列为例,模型的输入如下:
- 在第一个时间步$x_0$:通过线性变换(如 $h_0 = f(Wx_0 + b))$得到隐藏状态 $h_0$,可以输出一个中间预测值
- 在第二个时间步 $x_1$:模型不仅接收当前输入 $x_1$,还会接收前一时刻的隐藏状态 $h_0$,组合后作为输入生成 $h_1$,继续输出
- 以此类推,到第 t 个时间步 $x_t$,模型会基于当前输入和前一隐藏状态来生成 $h_t$
这一结构意味着,后续的每个隐藏状态都隐式包含了之前所有时间步的信息。例如:
$$h_3 = f(x_3, h_2) \Rightarrow f(x_3, f(x_2, h_1)) \Rightarrow f(x_3, f(x_2, f(x_1, h_0)))$$
最终可以使用最后一个时间步的隐藏状态 $h_t$ 来表示整段序列的语义,从而用于后续分类、回归等任务。
3. RNN 的主要问题
尽管 RNN 在设计上适应了时序数据的建模需求,但在实际应用中却暴露出许多关键性问题:
问题一:长期依赖难以捕捉
当输入序列较长时,早期的信息(如 $x_0$)需要通过多个非线性变换传递到后续节点。由于梯度在反向传播过程中会不断衰减(即梯度消失问题),模型往往难以有效记住较早时间步的信息。
这一现象会导致RNN 无法有效捕捉长期依赖关系,只能关注较近的上下文。
问题二:计算过程为串行,难以并行化
RNN 的每个时间步必须依赖前一时间步的计算结果,因此其计算过程是串行的,不能像 CNN 那样并行处理所有输入。
这会显著限制模型的训练效率,尤其在处理长序列时,训练成本和时间开销变得极高。
问题三:难以堆叠更深层结构
由于其串行依赖性,RNN 通常只能堆叠极少的层数(如 2~3 层),一旦层数过多,训练难度迅速上升,模型性能还会下降。因此,与 CNN 等深层结构相比,RNN 的建模能力受到限制。
问题四:结构为单向,缺乏对未来信息的利用
标准的 RNN 仅能从前向后建模(即从 $x_0$ 到 $x_t$),只能考虑历史信息,而无法利用“未来的信息”对当前施加影响。这在某些自然语言处理任务中尤为致命——因为当前词的含义往往依赖于后文。
4. 双向 RNN(Bidirectional RNN)
为解决上述单向性问题,提出了双向 RNN(BiRNN)结构:
- 先构建一条前向 RNN 处理从 $x_0$ 到 $x_t$ 的顺序
- 再构建另外一条反向 RNN 处理从 $x_t$ 到 $x_0$ 的逆序
- 最后把两条路径的隐藏状态进行拼接(或加权融合),作为最终的表示
这样,模型在每个时间步都能同时获得前文与后文的信息,从而可以更全面地理解上下文。然而,这一结构确还是不能从根本上解决“长期依赖”和“串行计算”的问题。
5. 信息获取机制的思考:局部 vs 全局影响
在 BiRNN 中,模型认为当前位置的语义最主要受邻近位置的影响。比如对于时间步 $x_3$,它主要融合来自 $x_2$ 和 $x_4$ 的信息。但实际上,某些远距离信息可能对当前任务具有更重要的影响,例如“某个关键事件”可能发生在很早以前。因此我们应该思考的是:
当前时刻的信息,应该由模型自主动态决定该关注谁,而不是依赖固定的结构性传播。
这种需要“动态决定关注谁”的思想,为后续的注意力机制(Attention)与 Transformer 架构的出现奠定了基础。
2.Transformer概述
这篇发表于 2017 年的论文《Attention is All You Need》是一篇里程碑之作,它不仅提出了 Transformer 这一全新的架构,更彻底改变了自然语言处理乃至整个人工智能的发展方向。
1. Transformer 的提出:从“注意力”到“结构性突破”
2017 年,Google 团队在论文《Attention is All You Need》中提出了一种全新的模型架构——Transformer。这项工作最初的灵感源于“注意力机制”的有效性,而后作者们又进一步发展出了一种完全基于注意力机制、摒弃传统递归(RNN)和卷积结构的深度学习架构。
Transformer 的核心创新在于:
- 去除序列间的依赖结构(如 RNN 的串行处理),转而依赖自注意力机制进行信息交互
- 提高了并行处理能力,可以大幅加速训练
- 有更强的上下文建模能力,使得模型能够灵活捕捉长距离依赖关系
2. BERT 的问世:从架构到预训练范式的统一
虽然 Transformer 的结构十分先进,但真正让它走向工业应用、普及到主流研究的,是 2018 年 Google 提出的 BERT(Bidirectional Encoder Representations from Transformers) 模型。
BERT 的重要意义体现在两点:
- 采用了纯 Transformer 编码器架构
- 提出了通用的预训练 + 微调范式,通过大规模语料进行预训练,再针对下游任务进行微调,这样显著提升了各类自然语言处理任务的最终效果
预训练的思想本质上解决了“从零开始训练”的困难。就像建筑施工如果完全从头开始搭建会耗时耗力,而如果提供一套成熟的“图纸”和“模板”,再在其基础上构建,就会高效许多。同样,预训练模型为下游任务提供了强大的“知识迁移”能力。
BERT 的发布引发了一波空前的研究热潮,大量学者基于 BERT 架构进行下游任务优化,刷新了几乎所有公开数据集的基准性能。可以说,BERT 将 Transformer 的潜力推向了一个新的高峰,也标志着 NLP 进入了“预训练语言模型”时代。
3. GPT 系列的崛起:从边缘探索者到时代主角
与 BERT 同期诞生的还有 OpenAI 的 GPT(Generative Pre-trained Transformer)。不过,相较于 BERT 的“完形填空式”输入-输出结构,GPT 更专注于 语言生成任务,采用单向结构,通过自回归方式生成文本。起初,GPT 系列并未引起足够关注,市场和学界的重心几乎全部集中在 BERT 及其变体上。但 GPT 并未停止演进,反而持续扩大模型规模、优化训练方式,最终在 GPT-3、GPT-4 的阶段迎来爆发,成为今日大模型浪潮的中心。
这也反映出一个事实:在 2018 年,BERT 主导了 NLP 领域几乎 99% 的关注,而 GPT 系列在当时被广泛忽视。然而如今,GPT 已成为引领行业发展的旗帜,反观 BERT 架构已逐渐退居二线。由此可见,技术演进的路径并非线性,而是由架构、预训练方式、数据规模和应用场景共同推动的。
4. Transformer 的本质任务:特征建模与表达重塑
在深入理解 Transformer 架构前,我们首先需要明确一个基本问题:Transformer 到底在做什么?
我们可以将 Transformer 看作一个特征重塑器。它的目标是接收一组原始输入特征,通过多层注意力机制进行全局信息建模与交互,最终输出一组更加棱角分明、语义丰富的表示。
举个类比:假设每个输入向量是一个平平无奇的人物,缺乏特点,模型很难分辨;而 Transformer 的作用就是通过“问一问周围的人怎么说”、“看看全局谁更重要”等机制,重新塑造每个人的性格标签,让他们在模型眼中变得鲜明可辨。这种机制极大提升了模型对上下文的理解能力,也为下游任务提供了更具判别力的输入表示。
因此,Transformer 的核心工作是:
- 建立输入之间的全局关系
- 强化有意义的特征维度,抑制冗余信息
- 输出适用于分类、生成等任务的高质量表示
5. AI 的范式迁移与启示
从 RNN 到 Transformer,不仅仅是结构的替换,更是计算范式的根本转变:
- 从串行到并行
- 从局部依赖到全局建模
- 从“手工设计结构”到“数据驱动表示学习”
2017 年的 Transformer 是一场变革的起点,2018 年的 BERT 是推广的催化剂,而今天的 GPT 系列与多模态模型则将这一技术带入了前所未有的高度。可以说,Transformer 不仅定义了 NLP,也逐渐在视觉、音频、强化学习等多个领域建立统治地位,成为真正的“通用架构”。
接下来,我们将深入分析 Transformer 的具体结构,包括多头注意力机制、位置编码方式、前馈神经网络与残差连接等模块,剖析其如何高效地实现上下文建模与语义表示学习。
3.Transformer整体架构
1.核心结构
编码器(左侧)
- 包含 N个相同层(图中
ENCODER #1
,ENCODER #2
) - 每层含:自注意力层 + 残差连接 & 层归一化 + 前馈网络
解码器(右侧)
- 包含 N个相同层(图中
DECODER #1
,DECODER #2
) - 每层比编码器多一层:编码器-解码器注意力层
- 结构顺序 :
掩码自注意力 → 残差&归一化 → 编码器-解码器注意力 → 残差&归一化 → 前馈网络
堆叠设计:
多个编码器/解码器层堆叠(图中为2层)是为了构建深层网络,这样就可以学习更复杂的特征表示。
2.输入如何编码?
1. 输入预处理流程
1 | 输入序列 = ["Thinking", "Machines"] |
- 词嵌入(Word Embedding):每个单词映射为稠密向量(如512维向量
[0.3, -0.8, ..., 0.1]
) - 位置编码(Positional Encoding):再为每个位置生成位置向量(正弦/余弦函数)
- 例:
1
2"Thinking" (位置0) → [sin(0), cos(0), sin(0.01), cos(0.01), ...]
"Machines" (位置1) → [sin(1), cos(1), sin(0.0001), cos(0.0001), ...] - 融合输入:
$$最终输入向量=词嵌入向量+位置编码向量$$
这样可以同时保留语义信息和顺序信息,供编码器处理。
3.输出结果是什么?
1. 输出生成逻辑
1 | while 未生成结束符: |
2. 输出层结构
- 线性层(Linear):将解码器输出的高维向量映射到词汇表大小维度
- Softmax:计算每个单词的生成概率
$$ P(下一个单词=wi)=∑jexp(zj)exp(zi) $$
📌 示例输出:输入:”Thinking Machines”
输出可能是:”思考” → “机器” →<end>
(机器翻译场景)
4.Attention的核心目的
1. 三种注意力机制
类型 | 目的 | 计算差异 |
---|---|---|
自注意力(Self-Attention) | 让每个词动态地看整个句子,从而捕捉上下文关系 | Query、Key、Value 都来自同一个序列 |
掩码自注意力(Masked Self-Attention) | 防止解码器“偷看”未来信息,只能关注当前位置及之前的词 | 在自注意力计算中对未来位置加掩码(mask) |
编码器-解码器注意力(Encoder-Decoder Attention) | 让解码器在生成每个词时去关注编码器输出,即源句子内容 | Query 来自解码器,Key 和 Value 来自编码器 |
2. 核心价值
- 解决长距离依赖:直接关联任意距离的两个词(无需RNN的逐步传递)
- 可解释性:注意力权重可视化(例:翻译”Machines”时关注”机器”)
- 并行计算:所有位置注意力同时计算(极大加速训练)
5.组件如何协作?端到端流程
1. 完整流程(以机器翻译为例)
2. 关键协作设计
- 残差连接(Add):每层输出 = 原始输入 + 本层变换 → 防止深层网络梯度消失
- 层归一化(Normalize):对每层输出归一化 → 稳定训练过程
- 信息传递路径:编码器输出 → 每个解码器的编码器-解码器注意力层 → 对齐输入输出关键信息
以”Thinking Machines”英译中为例:
- 编码器分析”Thinking”与”Machines”的语义关系
- 解码器生成”思考”时,通过编码器-解码器注意力聚焦”Thinking”
- 生成”机器”时,注意力同时聚焦”Machines”和已生成的”思考”
总结:Transformer如何突破传统?
维度 | 传统模型(RNN) | Transformer |
---|---|---|
顺序处理 | 逐步计算(无法并行) | 全序列并行计算 |
长距离依赖 | 需多次传递(易丢失信息) | 注意力一步直达 |
位置建模 | 天然顺序(但慢) | 显式位置编码(快且灵活) |
架构本质 | 时间驱动 | 空间关联驱动(注意力矩阵) |
4.自注意力机制(处理序列内部关系)
1.自注意力的目标
解决序列的核心问题:如何让序列中的每个元素(如单词)理解自身与其他元素之间的关系?
例:在句 “The cat did not catch the mouse because it was tired” 中,“it” 需要知道它指代的是 “cat”(而非 “mouse”)这就需要依赖上下文关联。
自注意力的本质:动态计算序列内任意两个元素的相关性权重。
2.自注意力在架构中的位置
- 编码器(ENCODER):每个编码器层中的 Self-Attention 模块
- 解码器(DECODER):每个解码器层中的 Masked Self-Attention 模块
图中路径:
输入序列 → 位置编码 → 编码器 Self-Attention → 解码器 Masked Self-Attention
3.自注意力运行机制(3步)
1.生成查询向量(Query)、键向量(Key)、值向量(Value)
对序列中 每个单词的嵌入向量(如 “Thinking”)做线性变换:
- $Q = W_q · x_i$ 主动“询问”向量,表示当前词想“了解什么”
- $K = W_k · x_i$ 被检索的“标识”向量,表示其他词“能提供什么”
- $V = W_v · x_i$ 实际携带信息的向量,是最终被提取的语义信息
2.计算注意力权重(序列元素间的关联强度)
通过 点积(Dot-Product) 计算词与词之间的相关性分数:
- $分数 = Q_i · K_j / √d_k$ // $d_k$为K的维度(缩放避免梯度消失)
对分数做 Softmax 归一化 → 得到概率分布 - $权重 α_{ij} = softmax(分数_ij)$ // $α_{ij}$表示第j个词对第i个词的重要性
示例:当处理 “it” 时,$α_{it,cat} ≈ 0.9, α_{it,mouse} ≈ 0.1$
3.加权聚合值向量(V)
用权重 $α_{ij}$ 对 所有词的 V 向量加权求和,生成当前词的新表示:
$$z_i = ∑{j=1}^n α{ij} V_j$$
输出:
$z_i$ 是融合了全局上下文信息的新向量(如“it”的向量中包含了“cat”的信息)
4.举例“今天晚上吃啥”
1.每个词先被映射成三个向量:Query、Key、Value
对于序列 [“今天”, “晚上”, “吃”, “啥”],每个词都会被分别映射成:Q(Query)、K(Key)、V(Value)
比如:
1 | Q_今天 = W_Q × Emb("今天") |
2.“今天”去和每个词计算相关性:点积 + softmax
我们想更新“今天”这个词的信息表示,那么我们用它的 Query 去和所有词的 Key 做点积:
1 | Score_今天-今天 = Q_今天 · K_今天 |
然后把这些分数做一个 softmax 归一化,生成一组权重:
1 | Softmax([Score_今天-今天, Score_今天-晚上, Score_今天-吃, Score_今天-啥]) |
最终就得到了 “注意力百分比”
3.用这组权重去加权 Value 向量
最后,“今天”这个词的最终表示就变成:
1 | 新的今天 = 0.5 × V_今天 + 0.1 × V_晚上 + 0.3 × V_吃 + 0.1 × V_啥 |
这里的“今天”、“晚上”等等都是对应词的 Value 向量(而不是原始文字)。
4.类比一下
你可以把这个过程想成“今天”这个词要做一次信息融合,它在“问大家”:
“我‘今天’想重新理解自己,我该参考谁多一点?”
- 它看自己(50%),因为“今天”对自身有最强的语义绑定
- 看“吃”(30%),因为“吃饭”时间通常和“今天”有时序关系
- 看“晚上”(10%),“今天晚上”是一个常见搭配
- “啥”(10%)可能关系较弱
这个“参考比例”也就是 attention score。
你看到的“0.5、0.1、0.3、0.1”的权重,是由:
Query(今天) 和所有 Key 做点积 → 再经过 softmax → 得到的一组概率分布,这些概率就决定了“今天”这个词在自注意力中融合哪些词的内容、要融合多少。
5.注意点
在实际训练或使用预训练模型时,这些权重(比如注意力机制中的 $W_Q, W_K, W_V$)都不需要我们手动初始化。因为 预训练模型已经学好了这些参数,我们只需要加载并使用即可。
5.自注意力如何解决序列问题?(对比RNN)
能力 | RNN/LSTM | 自注意力 |
---|---|---|
建模长距离依赖 | 需逐步传递(信息易丢失/稀释) | 一步直达,直接计算任意距离关联(任意位置连线) |
并行计算 | 严格时间序,不可并行 | 所有位置QKV同时计算(矩阵并行) |
语义关联可视化 | 隐状态难以解释 | 注意力权重$α_{ij}$可直观解释 |
计算复杂度 | $O(T·d)$ | $O(T²·d)$(但GPU并行效率更高) |
关键优势: 上下文感知(Context-Aware)
每个词的输出向量(如 $z_i$)都融合了整个序列的信息 → 动态理解多义词(如“bank”在“river bank” vs “bank account”中不同含义)
6.自注意力的输入→输出
以编码器中的 Self-Attention为例:
- 输入:词嵌入向量 + 位置编码(
Thinking
,Machines
的向量) - 过程:自注意力计算
Thinking
与Machines
的相互影响权重,生成新的上下文向量(包含两者关系) - 输出:传入下一层(
Add & Normalize → Feed Forward
)继续抽象
7.自注意力的本质
- 技术意义:抛弃循环,用 Query-Key-Value 三明治机制 实现全局语义融合。
- 架构地位:图中 Self-Attention 模块是 Transformer 的CPU,承担核心计算任务。
- 扩展影响:后续大模型如 BERT(仅用自注意力编码器)、GPT(用掩码自注意力解码器),均以此为基础。
5.多头注意力(并行捕捉不同维度的关联)
1. 多头注意力(Multi-Head Attention)作用
就是让模型在多个子空间中并行地观察词与词之间的关系,捕捉不同角度的信息。 单头注意力只看一个“角度”或一种“相似度”,而多头注意力就像请了多个专家,各自用不同的标准分析句子中词之间的关系,并行、多元、综合。
2. 原理
1.单头 vs 多头
单头注意力:
1 | Q = X @ W_Q # X: 输入序列,W_Q: 权重矩阵 |
多头注意力(以 8 头为例):
把 Q/K/V 分别用 8 套不同的投影矩阵做线性变换:
1 | for i in range(8): # 8个头 |
然后把 8 个头的输出拼在一起:
1 | Concat(Attention_1, ..., Attention_8) → 再通过一个线性层 |
这个线性层就是 $W_O$,可以想象成“专家总结”。
3.模型参数
假设输入维度是 512
1 | W_Q_i / W_K_i / W_V_i // [512, 64](每个头 64 维) |
4. 类比:小组讨论的直觉比喻
你有一个句子「今天晚上吃啥」,你想分析“今天”这个词该关注谁。
于是请来了 8 位专家,每位都从不同角度给建议:
- 第一个专注时间线(今天←→晚上)
- 第二个关注动作(吃)
- 第三个关注主宾关系(吃←→啥)
- ……其余人从语法、句法、话题等维度看
每个人(注意力头)单独打分,再分别输出他们的建议,最后把这些拼在一起,再交给一个“综合裁判”整合信息。
多头注意力可以从不同头关注不同信息,这样就不容易“信息冲突”或“遗漏关键线索”,提高了表达能力。即使某一头注意力失败,其他头可以弥补,实际更稳定/灵活。
多头注意力 = 多个注意力专家并行工作,分别分析不同语义维度,最后综合出一个更全面的理解。
6.位置编码(注入序列顺序信息)
1.为什么需要位置编码?
Transformer 结构完全没有 RNN / CNN 中的“顺序感”。原始的 Transformer 是基于 Attention 的,它不管输入词的前后顺序,全靠计算相互之间的注意力。
那么问题来了,我怎么知道“今天晚上吃啥”跟“吃啥今天晚上”是不同的?
位置编码就是给每个词加上“位置信息”,让模型知道哪个词在第几个位置。我们给每个词的 embedding 向量中 添加一段专门的“位置信息向量”,这样词的表示就和它的位置挂钩了。
2.两种常见方法:
1.Sinusoidal Encoding(正余弦函数编码)——Transformer 原版
不依赖学习,使用公式构造,适合泛化到更长句子
对于位置 $pos$ 和维度 $i$,定义:
$$PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d}}\right)$$
$$PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d}}\right)$$
- 偶数维用 $sin$,奇数维用 $cos$
- 低维度捕捉短期关系,高维度捕捉长期位置关系
- 向量之间的差值有意义,便于模型学习“相对位置信息”
每个位置会对应一个固定的向量,直接加到词向量上。
2.Learnable Position Embedding(可学习的位置向量)
直接把位置当作一个“词”一样来训练,比如说最多处理 512 个位置,就定义一个:
1 | pos_embedding = nn.Embedding(512, d_model) |
每个位置 0~511 都有一个向量,随着训练自动学。
优点:灵活、能拟合训练语料的结构
缺点:泛化能力差,位置超过训练长度可能表现差
怎么加到词上?
1 | x = word_embedding + positional_encoding |
词的语义 + 位置信息 = 带位置信息的输入表示
3.类比:拼火车
假设句子是“今天 晚上 吃 啥”,每个词是一节火车车厢。
你给每节车厢都贴个编号(1、2、3、4),贴的标签就是位置编码。
没有标签 → 模型只知道“有这几节车厢”
加上标签 → 模型知道“车厢的顺序”
7.编码器-解码器结构(核心框架)
编码器把输入句子变成信息浓缩的“理解结果”,解码器基于这个理解一步步“生成”目标句子。
1 | 输入句子(源语言) ─→ 编码器(Encoder) ─→ 编码结果 |
比如输入:“今天晚上吃啥?”,生成:“What shall we eat tonight?”
1.编码器(Encoder)
由多个 Encoder Layer 叠加组成,每层结构如下:
1 | [输入词向量 + 位置编码] |
每个词在理解过程中不会只关注自己,而是会参考句子中其他词的信息,综合上下文后更新自己的表示,使得每个词的向量都包含了整句话的语义线索。
编码器的任务不是生成词语或句子,而是将输入句子转换为一组表达其含义的高维向量,用于后续生成阶段使用。
2.解码器(Decoder)
由多个 Decoder Layer 叠加组成,每层结构会复杂一些:
1 | [目标词向量 + 位置编码] |
掩码自注意力的作用是在生成一个词的时候,只允许模型查看它前面已经生成的词,故意遮住后面的词,防止提前知道答案、出现“抄袭”现象。
编码器-解码器注意力是指当模型要生成一个词时,就会去“参考”输入句子中哪些词最相关,借此更好地决定该输出什么,从而提升翻译或生成的准确性。
3.类比:翻译员结构
你可以把 Transformer 想象成一个翻译过程:
- 编码器 = 一个理解中文的人,他把“今天晚上吃啥”理解成一份压缩的语义笔记
- 解码器 = 一个会英文的说话者,他一边看这份笔记一边逐字翻译出:“What shall we eat tonight?”
其中解码器不能一次性生成所有单词,它是“边看边说”。每生成一个词(比如 “What”),它会重新计算注意力、生成下一个词(“shall”)
4.编码器 vs 解码器 对比
模块 | 输入 | 注意力类型 | 目的 |
---|---|---|---|
编码器 | 源语言(比如中文) | 自注意力 | 理解上下文 |
解码器 | 已生成的目标词(英文)+ 编码器输出 | 掩码自注意力 + 编码器-解码器注意力 | 生成新词、参考输入 |
8.层标准化(稳定训练过程)
在每一层网络中,可以把输出“调成标准状态”(均值为0,方差为1),这样可以让训练更平稳,减少震荡,更快收敛。
就像一群学生考试,有人考90分,有人考30分,差距太大,老师很难统一讲解。层标准化就像是先把分数都“标准化”,大家都围绕平均线波动,这样更容易统一训练策略,也能避免某些值太大或太小影响整个模型。
9.残差连接(缓解梯度消失)
给每一层加一条“捷径”,让原始信息绕过复杂计算,直接传给后面的层,帮助模型更容易训练,不容易梯度消失。
想象你在传话,一个人一句地传,很容易出错。残差连接就像是你偷偷把原话也发了条微信备份,最后的人可以同时听到“中间人转述的版本”和“原话”,即使中间转述有点偏,也不至于彻底误解。
10.前馈神经网络(非线性特征变换)
在注意力机制之后,加一层小型的神经网络,对每个词的表示再加工一次,让它学到更复杂的特征和语义关系。
你可以把前面的注意力比作“信息收集”,而前馈网络就像“深加工工厂”——收集到的信息还比较粗糙,前馈网络用非线性函数再精细处理,让每个词的表示更聪明、更有表现力。
11.总结
Transformer本质:通过注意力机制重构序列建模,从“逐步传递”到“动态关联”,最终成为大模型时代的基础架构。
- 自注意力机制:动态计算序列元素间关联(QKV矩阵),直接建模长距离依赖,替代RNN的串行传递
- 编码器-解码器结构
- 编码器:自注意力+前馈网络,提取输入特征
- 解码器:掩码自注意力(防信息泄露)+ 编码器交互注意力(对齐输入)
- 关键技术点
- 多头注意力:并行多组注意力,捕捉不同维度关系
- 位置编码:注入位置信息,弥补注意力缺失的时序感知
- 残差连接+层标准化:稳定深层训练,缓解梯度消失
- 突破性优势
- 全局建模:任意位置直接关联,解决长距离依赖
- 并行计算:矩阵运算替代串行处理,大幅提升效率
- 可解释性:注意力权重可视化,揭示模型决策逻辑
11.备注
Attention is All You Need : https://arxiv.org/pdf/1706.03762