Transformer基础入门:从词嵌入到注意力机制 | 吴恩达2025最新课程笔记
本文基于吴恩达2025年最新Transformer课程,深入浅出地讲解大语言模型如何"理解"语言。从最朴素的词袋模型到革命性的注意力机制,通过可视化图表和代码示例,帮助初学者快速掌握Transformer的核心基础。涵盖词嵌入原理、上下文编码、语义相似度计算等关键技术点,是入门现代LLM必读教程。
一、为什么要学习Transformer?
如果说深度学习是AI的引擎,那么Transformer就是这个引擎的核心。从ChatGPT到GPT-4,从Claude到文心一言,几乎所有现代大语言模型都建立在Transformer架构之上。
1.1 LLM发展简史
1.2 Transformer的革命性优势
与传统RNN/LSTM相比:
| 特性 | RNN/LSTM | Transformer |
|---|---|---|
| 计算方式 | 串行计算,必须按时序 | 并行计算,可同时处理 |
| 长距离依赖 | 梯度消失,难以捕捉 | 自注意力直连,轻松捕捉 |
| 训练速度 | 慢(无法并行) | 快(GPU加速显著) |
| 可扩展性 | 难以扩展到超大规模 | 可扩展到千亿参数 |
二、语言模型如何"看懂"文字?
2.1 最简单的方法:词袋模型(Bag of Words)
核心思想:把句子看成一个"词的袋子",不考虑顺序,只统计词频。
问题示例:
python
sentence1 = "狗咬了人" → [1, 1, 1]
sentence2 = "人咬了狗" → [1, 1, 1] # 完全相同!
❌ 致命缺陷:
- 丢失词序信息
- 无法区分"狗咬人"和"人咬狗"
- 无法理解上下文
2.2 进化:词嵌入(Word Embeddings)
核心思想:把每个词映射到高维向量空间,让语义相近的词在空间中靠近。
2.3 经典的词向量关系
最著名的例子:King - Man + Woman = Queen
python
# 词嵌入的神奇特性
vector("国王") - vector("男人") + vector("女人") ≈ vector("女王")
vector("中国") - vector("北京") + vector("东京") ≈ vector("日本")
可视化理解:
2.4 词嵌入的训练方式
Word2Vec (2013)
两种训练方法:
- CBOW: 用上下文预测中心词
- Skip-gram: 用中心词预测上下文
三、上下文的重要性:从静态到动态
3.1 词嵌入的局限性
考虑"银行"这个词:
python
sentence1 = "我去银行取钱" # 金融机构
sentence2 = "河流的银行很陡" # 河岸
# 传统词嵌入的问题:
embedding("银行") = [0.5, 0.3, 0.7, ...] # 永远是同一个向量!
❌ 问题:一词多义无法区分
3.2 上下文感知的词向量
ELMo (2018) 的突破:根据上下文动态生成词向量
四、注意力机制的诞生
4.1 为什么需要注意力?
翻译句子时,不同的词需要关注不同的上下文:
vbnet
英文: The animal didn't cross the street because it was too tired.
中文: 动物没有过马路,因为它太累了。
问题:"it" 指的是什么?
4.2 注意力机制的直观理解
核心思想:在处理每个词时,让模型自动计算该词应该"关注"哪些其他词。
处理"爱"这个词时:
- 对"我"的注意力: 0.1 (低)
- 对"学习"的注意力: 0.5 (高)
- 对"AI"的注意力: 0.4 (高)
最终表示 = 0.1 × vector(我) + 0.5 × vector(学习) + 0.4 × vector(AI)
五、编码器与解码器:Seq2Seq架构
5.1 机器翻译的挑战
5.2 编码器-解码器架构
六、代码实战:词嵌入入门
6.1 使用Gensim加载预训练词向量
python
from gensim.models import KeyedVectors
import numpy as np
# 加载Word2Vec预训练模型(需要下载)
# 下载地址: https://github.com/Embedding/Chinese-Word-Vectors
model = KeyedVectors.load_word2vec_format('sgns.zhihu.word', binary=False)
# 获取词向量
king_vector = model['国王']
print(f"'国王'的向量维度: {king_vector.shape}") # (300,)
# 计算词语相似度
similarity = model.similarity('国王', '女王')
print(f"'国王'与'女王'的相似度: {similarity:.4f}") # 0.7234
# 找出最相似的词
similar_words = model.most_similar('国王', topn=5)
print("与'国王'最相似的词:")
for word, score in similar_words:
print(f" {word}: {score:.4f}")
# 输出示例:
# 女王: 0.7234
# 王后: 0.6892
# 皇帝: 0.6543
# 君主: 0.6321
# 统治者: 0.6102
6.2 词向量的算术运算
python
# 经典例子: King - Man + Woman = Queen
result = model.most_similar(positive=['女王', '男人'],
negative=['国王'],
topn=1)
print(result) # [('女王', 0.8234)]
# 中国之于北京 = 日本之于?
result = model.most_similar(positive=['日本', '北京'],
negative=['中国'],
topn=1)
print(result) # [('东京', 0.7654)]
6.3 可视化词嵌入
python
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt
# 选择一些词
words = ['国王', '女王', '男人', '女人', '王子', '公主',
'苹果', '香蕉', '汽车', '飞机']
# 获取词向量
vectors = [model[word] for word in words]
# 使用t-SNE降维到2D
tsne = TSNE(n_components=2, random_state=42)
vectors_2d = tsne.fit_transform(vectors)
# 绘图
plt.figure(figsize=(10, 8))
for i, word in enumerate(words):
x, y = vectors_2d[i]
plt.scatter(x, y, marker='o', s=100)
plt.annotate(word, (x, y), fontsize=12, ha='center')
plt.title('词嵌入空间可视化 (t-SNE降维)')
plt.xlabel('维度 1')
plt.ylabel('维度 2')
plt.grid(True, alpha=0.3)
plt.show()
输出效果:你会看到"国王/女王"、"男人/女人"聚在一起,而"苹果/香蕉"在另一个区域。
七、上下文编码实战
7.1 使用PyTorch实现简单的上下文编码器
python
import torch
import torch.nn as nn
class ContextEncoder(nn.Module):
def __init__(self, vocab_size, embedding_dim, hidden_dim):
super().__init__()
# 词嵌入层
self.embedding = nn.Embedding(vocab_size, embedding_dim)
# 双向LSTM捕捉上下文
self.lstm = nn.LSTM(embedding_dim, hidden_dim,
bidirectional=True, batch_first=True)
def forward(self, x):
# x: [batch_size, seq_len]
embedded = self.embedding(x) # [batch_size, seq_len, embedding_dim]
output, (h_n, c_n) = self.lstm(embedded)
# output: [batch_size, seq_len, hidden_dim*2] (双向)
return output
# 示例使用
vocab_size = 10000 # 词汇表大小
embedding_dim = 128 # 词嵌入维度
hidden_dim = 256 # LSTM隐藏层维度
model = ContextEncoder(vocab_size, embedding_dim, hidden_dim)
# 模拟输入 [batch_size=2, seq_len=10]
sample_input = torch.randint(0, vocab_size, (2, 10))
context_output = model(sample_input)
print(f"输入形状: {sample_input.shape}") # torch.Size([2, 10])
print(f"上下文编码形状: {context_output.shape}") # torch.Size([2, 10, 512])
7.2 注意力权重可视化
python
import torch.nn.functional as F
import seaborn as sns
def compute_attention(query, keys):
"""
计算注意力权重
query: [hidden_dim]
keys: [seq_len, hidden_dim]
"""
# 点积注意力
scores = torch.matmul(keys, query) # [seq_len]
# Softmax归一化
attention_weights = F.softmax(scores, dim=0)
return attention_weights
# 模拟例子
seq_len = 7
hidden_dim = 64
words = ['我', '爱', '学习', '人工', '智能', '技术', '!']
# 随机生成keys和query(实际中由神经网络生成)
keys = torch.randn(seq_len, hidden_dim)
query = torch.randn(hidden_dim)
# 计算注意力
attention = compute_attention(query, keys)
# 可视化
plt.figure(figsize=(10, 2))
sns.heatmap([attention.numpy()],
xticklabels=words,
yticklabels=['注意力'],
cmap='YlOrRd',
annot=True,
fmt='.3f')
plt.title('注意力权重分布')
plt.show()
# 输出示例:
# 我 爱 学习 人工 智能 技术 !
# 0.08 0.25 0.31 0.15 0.12 0.07 0.02
八、关键概念总结
8.1 核心技术对比
8.2 重要公式
词嵌入相似度(余弦相似度)
similarity(A,B)=∣∣A∣∣⋅∣∣B∣∣A⋅B=∑i=1nAi2 ⋅∑i=1nBi2 ∑i=1nAiBi
注意力权重
Attention(Q,K,V)=softmax(dk QKT)V
其中:
- Q (Query): 查询向量
- K (Key): 键向量
- V (Value): 值向量
- dk: 键向量的维度
九、学习路径与资源
9.1 推荐学习路线
9.2 实践建议
初学者(第1-2周)
- ✅ 理解词袋模型 → 词嵌入的进化
- ✅ 动手实践Word2Vec
- ✅ 可视化词向量空间
- ✅ 理解上下文的重要性
进阶学习(第3-4周)
- ✅ 深入学习注意力机制
- ✅ 实现简单的Seq2Seq模型
- ✅ 对比RNN与Transformer
- ✅ 阅读经典论文
9.3 常见问题FAQ
Q1: 词嵌入的维度如何选择?
A: 常见选择:
- 小数据集: 50-128维
- 中等数据集: 256-512维
- 大规模预训练: 768维(BERT)、1024维(GPT-2)
Q2: 为什么需要上下文感知?
A:
python
# 一词多义问题
"我去银行取钱" # 银行 = 金融机构
"河流的银行很陡" # 银行 = 河岸
# 静态词嵌入无法区分,上下文编码可以根据周围词汇动态调整
Q3: 注意力机制与全连接层的区别?
A:
- 全连接: 固定权重,所有输入同等重要
- 注意力: 动态权重,根据输入自适应调整
十、下一步学习
恭喜你完成了Transformer基础入门!接下来我们将深入学习: