词嵌入与语言建模入门
词嵌入(Word Embedding)把离散词表中的每个词映射为一个可学习的稠密向量,使语义相近的词在向量空间相近;语言建模(Language Modeling)则以「预测下一个词」为监督任务训练这种表示,困惑度是其标准评估。
一句话定义
词嵌入(Word Embedding)把离散词表中的每个词映射为一个可学习的稠密向量,使语义相近的词在向量空间相近;语言建模(Language Modeling)则以「预测下一个词」为监督任务训练这种表示,困惑度是其标准评估。
直觉
one-hot 像给每人发一个互不相干的门牌号,「国王」和「皇帝」的门牌毫无关系;词嵌入像「把所有人按性格安置进一座城市」——住得近的语义近,「国王 − 男人 + 女人 ≈ 女王」相当于城市里可推算的门牌代数。
为什么重要
它是「离散符号 → 可微向量」的转换器:没有它,kp-009 的交叉熵与 kp-022 的 RNN 都无从处理文本。语言建模则是自监督学习的祖师爷——用文本自身当标签、免费获得无限监督信号,这条路线一路演化成 BERT/GPT 的预训练范式(kp-032 的主角,细节指路大模型站点)。
前置知识
- kp-002(张量与索引)、kp-009(softmax 交叉熵)。
核心概念
- 词表(vocabulary):语料去重后的词集合,每个词一个整数 id。
- one-hot 表示:维度 = 词表大小的稀疏向量,任何两词都正交(无相似度)。
- 嵌入矩阵(embedding matrix):E ∈ R^{V×d},查表(lookup)即取第 id 行。
- 分布假说(distributional hypothesis):「看一个词的邻居,就知道它的意思」——嵌入可学习的理论根基。
- skip-gram / CBOW:word2vec 的两种任务形式——由中心词猜邻居 / 由邻居猜中心词。
- 困惑度(perplexity, PPL):语言模型标准指标,PPL = exp(平均交叉熵),可读作「每次预测平均在多少个词里犹豫」。
原理与机制
one-hot 的三重困境:维度随词表线性膨胀(10 万词 → 10 万维);任意两词距离恒等,语义结构为零;稀疏导致下游层参数爆炸(V×H 矩阵)。嵌入层查表后这些矩阵仍存在,但作为可学习参数被任务梯度共同塑形:常一起出现的词被推近(同现统计的稠密压缩)。word2vec(Mikolov 2013)把塑形任务单独拎出来:skip-gram 用中心词预测窗口内邻居,训练完成后 E 即为嵌入;其数学是一个 V 类 softmax 分类(与 kp-009 的公式同构,只是「类」是词表里的词),工程上用负采样近似以绕开 V 万级 softmax。语言建模(Bengio 2003 神经概率语言模型 → RNN 版)则不满足于静态嵌入,让 RNN 隐状态融入上下文:P(w_t | w_<t) = softmax(W_o h_t),损失即整句的平均交叉熵(kp-009 的逐词版本)。评估用困惑度:PPL = exp(−(1/T)Σ log p(w_t)),直觉解释是「模型的平均犹豫广度」——PPL=50 表示每一步模型的有效选择约相当于在 50 个词中猜。级联结构:嵌入层(查表)→ 循环层(kp-022/023 混合上下文)→ 输出投影(权重可与嵌入矩阵共享,省参数且小词表上有效)。当代地位:word2vec 的静态嵌入已被上下文相关表示取代,但「以预测词为监督学表示」的思想正是 kp-032 预训练范式的内核,GPT 系的自回归目标与本节的下一个词预测完全同构。
公式或模型
语言建模目标与困惑度:
概率分解: P(w_1,…,w_T) = Π_{t=1..T} P( w_t | w_<t )
训练损失: L = −(1/T) Σ_t log p_θ( w_t | w_<t ) (逐词交叉熵)
困 惑 度: PPL = exp( L ) = exp( −(1/T) Σ_t log p(w_t|·) )
skip-gram: max Σ_t Σ_{−w≤j≤w} log p( w_{t+j} | w_t ) (负采样近似)变量说明:V 为词表大小、d 为嵌入维度、T 为序列长。PPL 与 kp-009 的 L 是同一事物的两种坐标(对数/指数)。
图示
词表: {我:0, 爱:1, 深度:2, 学习:3, …} V=50000, d=64
one-hot(2) = [0,0,1,0,…,0] (50000维) ──查 E 行──► e_2 ∈ R^64
E ∈ R^{50000×64}(可学习嵌入矩阵)
RNN 主干: e_1 → e_2 → e_3 → … (kp-022 隐状态混合上下文)
输出: h_t ──W_o──► logits ∈ R^V ──softmax──► P(下一个词)直观类比
困惑度像「完形填空的犹豫度」:PPL=1.2 的模型几乎闭眼填对(过拟合或记忆),PPL=1000 的模型基本在瞎猜;人类水平在 10~20 一带(视语料而定)。
实例或案例
字符级 LM 的最小可运行片段(与 kp-022 的 TinyRNN 拼装即完整):
class CharLM(nn.Module):
def __init__(self, vocab, d=128):
super().__init__()
self.emb = nn.Embedding(vocab, d) # 查表嵌入
self.rnn = nn.LSTM(d, d, batch_first=True) # 上下文(kp-023)
self.out = nn.Linear(d, vocab) # V 类 softmax 头
def forward(self, x):
h, _ = self.rnn(self.emb(x))
return self.out(h) # [B,T,V] 逐位 logits
# 训练:输入 = 文本错位一格;损失 = 逐位置交叉熵的平均
logits = model(x[:, :-1]); target = x[:, 1:]
loss = nn.functional.cross_entropy(
logits.reshape(-1, vocab), target.reshape(-1))词向量语义检查:训练好的 skip-gram 上计算 cos(国王−男人+女人, 女王) 显著高于随机词对——「向量算术」是嵌入质量最有趣的快速体检。kp-032 将指出:把这里的「字符/词级小模型」放大到千亿参数,就是 GPT 的骨架。
常见误区
- 「词嵌入学出的是词义本体」:它学的是同现统计,反映语料偏见(性别/职业刻板印象会原样进入向量,kp-033 的入口问题)。
- 「嵌入维度越大一定越好」:小语料高维嵌入严重过拟合,d 应与数据量匹配。
- 忘记输出投影可与嵌入共享权重(tied embedding):小词表场景白白多 V×d 参数。
- 用 PPL 跨语料/跨分词直接比较:不同词表大小下 PPL 不可比,只能同协议内比较。
与其他知识点的关系
kp-009 的交叉熵在本节逐词化;kp-022/023 提供上下文主干;kp-026 的注意力是「上下文混合」的另一种(最终胜出的)方式;kp-032 把本节的下一词预测放大为预训练范式;kp-033 从嵌入偏见进入伦理讨论。
自测题
- one-hot 相比稠密嵌入的两大缺陷?
答案要点:维度=词表大小且极度稀疏;任意两词正交,无法表达语义相似度。
- PPL=80 意味着什么?它与交叉熵的关系式?
答案要点:模型每步预测等效在约 80 个词中犹豫;PPL=exp(平均交叉熵)。
- skip-gram 的训练目标是什么?为什么需要负采样?
答案要点:由中心词预测邻居词;完整 V 类 softmax 代价过高,用少量负例近似二分类化。
延伸阅读
- Mikolov 等 2013《Efficient Estimation of Word Representations in Vector Space》(word2vec 原文)。
- Bengio、Ducharme、Vincent、Jauvin JMLR 2003(神经语言建模开山作)。
学习状态
状态保存在浏览器本地,用于首页与路径页的进度统计。