共计 2024 个字符,预计需要花费 6 分钟才能阅读完成。
背景痛点
在自然语言处理中,传统 one-hot 编码存在明显的维度爆炸问题。假设词汇表大小为 $V$,每个词都需要一个 $V$ 维的向量表示,当 $V$ 达到百万级别时,存储和计算成本变得不可接受。此外,one-hot 编码无法捕捉词与词之间的语义关系。

CBOW(Continuous Bag-of-Words)模型相比 Skip-gram 在训练效率上具有明显优势,主要体现在:
- CBOW 通过上下文预测中心词,可以更好地利用上下文信息,训练过程更稳定
- 在小规模数据集上,CBOW 通常能更快收敛
- 对于高频词,CBOW 能产生更准确的词向量表示
数学原理
CBOW 模型的核心思想是通过上下文词预测中心词。给定一个上下文窗口大小为 $2m$,模型将上下文词向量求平均后映射到隐藏层:
$$
h = \frac{1}{2m} \sum_{i=1}^{2m} x_i
$$
其中 $x_i$ 是第 $i$ 个上下文词的词向量。然后通过 softmax 计算目标词的概率分布:
$$
p(w_j|context) = \frac{\exp(h^T v_{w_j})}{\sum_{k=1}^V \exp(h^T v_{w_k})}
$$
损失函数采用负对数似然:
$$
\mathcal{L} = -\log p(w_j|context)
$$
梯度更新公式为:
$$
\frac{\partial \mathcal{L}}{\partial v_{w_j}} = (p(w_j|context) – 1)h
$$
$$
\frac{\partial \mathcal{L}}{\partial h} = \sum_{j=1}^V (p(w_j|context) – 1)v_{w_j}
$$
工程实现
以下是基于 PyTorch 的 CBOW 实现示例:
import torch
import torch.nn as nn
import torch.optim as optim
from collections import Counter
import numpy as np
class CBOWModel(nn.Module):
def __init__(self, vocab_size, embedding_dim):
super(CBOWModel, self).__init__()
# 使用 EmbeddingBag 实现高效上下文聚合
self.embeddings = nn.EmbeddingBag(vocab_size, embedding_dim, mode='mean')
self.linear = nn.Linear(embedding_dim, vocab_size)
def forward(self, inputs, offsets):
embeds = self.embeddings(inputs, offsets)
out = self.linear(embeds)
return out
# 负采样策略
def get_negative_samples(word_counts, num_negatives=5):
total = sum(word_counts.values())
word_probs = {word: count/total for word, count in word_counts.items()}
words = list(word_probs.keys())
probs = np.array(list(word_probs.values()))**0.75 # 平滑处理
probs /= probs.sum()
return lambda: np.random.choice(words, num_negatives, p=probs)
# 词频统计与降采样
def subsample_words(word_counts, threshold=1e-5):
total = sum(word_counts.values())
word_probs = {word: 1 - np.sqrt(threshold/(count/total)) for word, count in word_counts.items()}
return word_probs
优化策略
词向量维度选择需要权衡:
- 50 维 :计算效率高,适合实时应用,但语义捕捉能力有限
- 100 维 :平衡点,适合大多数通用任务
- 300 维 :语义表示最丰富,但计算成本高
学习率衰减策略建议采用:
- 初始学习率设为 0.025
- 每处理 10000 个词,学习率线性衰减
- 最终学习率不低于 0.0001
避坑指南
实践中常见错误包括:
- 未归一化的词频统计 :会导致高频词主导训练过程,解决方案是应用上述降采样策略
- 小批量训练时上下文窗口不对称 :确保每个 batch 中的样本具有相同窗口大小
- 评估时误用余弦相似度 :应结合下游任务效果评估,而非仅依赖相似度指标
延伸思考
可以将 CBOW 与 GloVe 的共现矩阵进行特征融合:
- 先分别训练 CBOW 和 GloVe 模型
- 对得到的词向量进行拼接或加权平均
- 使用 PCA 降维保持最终维度不变
这种方法可以结合局部上下文信息(CBOW)和全局统计信息(GloVe),在多项 NLP 任务中表现优于单一模型。
