本模块预计时长: 1.5-2小时
目标: 理解单词的初始表示是如何构建的,为什么知道它们在句子中的位置至关重要,以及Transformer如何同时从多个角度"查看"文本。
在Transformer应用注意力机制之前,它需要将单词转换为计算机理解的东西:数字。
但不是任何数字。不是分配任意ID(如"猫=1","狗=2")。这无法捕捉含义。
这就是嵌入的作用。
🔹 简单定义:
嵌入是单词(或标记)的密集向量表示,其中含义或用法相似的单词具有相似的向量。
示例:
- "国王" → [0.85, -0.2, 0.67, ...]
- "王后" → [0.82, -0.18, 0.65, ...]
- "桌子" → [-0.3, 0.9, 0.1, ...]
"国王"和"王后"在向量空间中接近。"桌子"很远。
想象所有单词都在巨大的意义地图上定位。
嵌入就像单词在该地图上的GPS坐标。
当模型看到"猫"这个词时,它不会看到字母'c'或'a'。它看到它的向量:地图上的一个点。因此,它可以推理:
"如果'猫'接近'狗',而'狗'经常与'皮带'相关,也许'猫'也与'皮带'有关...尽管不完全相同。"
这张地图不是手工编码的。它在训练期间自动学习!
有两种主要方式:
如Word2Vec或GloVe。在大型文本语料库上训练一次,然后用作固定层。限制:每个单词只有一个向量,无论上下文如何。
"银行"总是有相同的向量,无论是"金融"还是"公园长椅"。
这就是Transformer的亮点!不是分配固定向量,模型为每个上下文生成特定的嵌入。
在"我去银行存款"中,"银行"获得接近"金钱"的向量。
在"我坐在公园长椅上"中,获得接近"木头"或"休息"的向量。
这是通过组合实现的:
这里有一个关键挑战:
如果Transformer同时处理所有单词...它如何知道哪个在前,哪个在中间,哪个在最后?
位置很重要!
"狗咬了人" ≠ "人咬了狗"
在RNN中,顺序在处理序列中是隐含的。在Transformer中不是。
解决方案:位置编码
想法很简单:在每个单词的嵌入中添加一个数字信号,指示其在序列中的位置。
但不是任何信号。简单的计数器(位置1、2、3...)不能很好地扩展,也不能捕捉相对关系("第5个单词接近第6个")。
原始Transformer的解决方案:正弦函数。
🔹 公式(仅供参考):
对于位置pos和向量的维度i:
PE(pos, 2i) = sin(pos / 10000^(2i/d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))
其中d_model是嵌入维度(例如512或768)。
想象句子中的每个位置广播一个"独特频率",就像电台一样。
每个单词接收其语义嵌入+其"位置波"。
当模型相加两者时,它得到一个向量,说:
"我是单词'银行',我在句子的第5个位置。"
最聪明的部分:这些正弦函数允许模型学习相对关系。
"第5个位置的单词可以学习第6个位置的单词是'接近的',即使它从未在训练中见过100个单词的句子。"
想象你正在分析一部戏剧。
他们都在看同一部戏...但从不同角度。所有这些都是有效的。
这就是多头注意力的作用。
不是计算单个注意力矩阵,Transformer并行计算多个"注意力头",每个头都有自己的学习Q、K、V矩阵。
h个不同空间(例如8个头)。🔹 结果: 模型不仅仅有一种"看"句子的方式。它有多个专门的镜头。
考虑句子:
"发现疫苗的科学家获得了奖项。"
每个头贡献拼图的一块。一起,它们产生完整理解。
取句子:"演奏小提琴的音乐家感动了观众。"
想象三个不同的"注意力头"。描述每个头会连接哪些单词以及为什么。使用类别如:句法、语义、情感、乐器等。
单词: "科学家"
嵌入: [0.7, -0.3, 0.5, ...] → "基本含义"
位置3: [0.1, 0.05, -0.2, ...] → "位置3的正弦波"
初始向量 = 嵌入 + 位置 → [0.8, -0.25, 0.3, ...]
投影到3个头:
头1: Q1, K1, V1 → 对动词的注意力
头2: Q2, K2, V2 → 对对象的注意力
头3: Q3, K3, V3 → 对奖项/成就的注意力
头输出:
头1: [0.6, 0.1, ...]
头2: [-0.2, 0.8, ...]
头3: [0.4, 0.5, ...]
连接: [0.6, 0.1, -0.2, 0.8, 0.4, 0.5, ...]
最终投影: [0.55, 0.3, 0.45, ...] → 丰富的最终表示
Transformer不是从零开始。它分层构建理解:
- 嵌入给出初始语义含义。
- 位置编码给出顺序意识。
- 多头注意力允许同时从多个角度查看文本。
就像专家团队分析文本:每个人都贡献自己的视角,产生的理解比任何单个分析师都能实现的更丰富、更细致。
现在我们理解了基本组件,是时候组装它们了:这些组件如何组织成完整的Transformer?编码器和解码器有什么区别?为什么BERT和GPT虽然都使用Transformers,但工作方式如此不同?
我们将在下一个模块中探讨这个问题。