共计 1634 个字符,预计需要花费 5 分钟才能阅读完成。
背景介绍
词嵌入技术是自然语言处理(NLP)中的基础技术之一,它将词语映射到低维连续向量空间,使得语义相似的词在向量空间中距离相近。CBOW(Continuous Bag-of-Words)模型是词嵌入的经典算法之一,广泛应用于文本分类、机器翻译等任务。

CBOW 模型的核心思想是通过上下文词语预测中心词,从而学习词向量表示。与 Skip-gram 模型不同,CBOW 更适合处理小型数据集和频繁词语。
算法原理
CBOW 模型的工作流程可以分为以下几个步骤:
- 输入层:将上下文词语的 one-hot 编码输入模型
- 投影层:通过词嵌入矩阵将 one-hot 向量转换为稠密向量
- 输出层:将投影层的向量平均后通过另一个矩阵转换,得到预测结果
词嵌入矩阵调整的核心在于通过反向传播算法更新两个矩阵的权重:
- 输入矩阵 W(大小为 |V|×d,|V| 是词汇表大小,d 是嵌入维度)
- 输出矩阵 W ’(大小为 d×|V|)
数学推导过程如下:
给定上下文词集合 C,中心词为 w,目标是最小化负对数似然:
L = -log P(w|C)
其中概率通过 softmax 计算:
P(w|C) = exp(v'_w·h)/Σ_j exp(v'_j·h)
h 是上下文向量的平均:
h = 1/|C| Σ_{c∈C} v_c
实现细节
以下是使用 PyTorch 实现 CBOW 模型的完整代码:
import torch
import torch.nn as nn
import torch.optim as optim
class CBOW(nn.Module):
def __init__(self, vocab_size, embedding_dim):
super(CBOW, self).__init__()
self.embeddings = nn.Embedding(vocab_size, embedding_dim)
self.linear = nn.Linear(embedding_dim, vocab_size)
def forward(self, inputs):
embeds = self.embeddings(inputs)
out = torch.mean(embeds, dim=1)
out = self.linear(out)
return out
# 示例用法
vocab_size = 10000
embedding_dim = 300
model = CBOW(vocab_size, embedding_dim)
loss_function = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 训练循环
for epoch in range(100):
# 假设 inputs 是上下文词索引,targets 是中心词索引
outputs = model(inputs)
loss = loss_function(outputs, targets)
optimizer.zero_grad()
loss.backward()
optimizer.step()
性能优化
- 向量化实现 :使用矩阵运算替代循环,充分利用 GPU 并行计算能力
- 负采样 :替代计算量大的全 softmax,显著提升训练速度
- 分层 softmax:使用二叉树结构减少计算复杂度
- 学习率调度 :采用自适应学习率方法如 Adam
避坑指南
- 窗口大小选择 :
- 太小的窗口会丢失全局语义
- 太大的窗口会增加噪音
-
通常 2 - 5 效果较好
-
学习率设置 :
- 初始学习率建议 0.025
-
随着训练逐渐衰减
-
词频处理 :
- 对低频词进行下采样
- 对高频词进行截断
进阶思考
CBOW 模型虽然简单有效,但也存在一些局限性:
- 无法处理词序信息
- 对低频词学习效果较差
- 无法捕捉多义词的不同含义
改进方向包括:
- 结合上下文信息(如 ELMo)
- 使用更复杂的网络结构(如 Transformer)
- 融入外部知识(如知识图谱)
实践建议
建议读者尝试在以下数据集上复现实验:
- PTB(Penn Treebank)
- Text8
- 自定义领域语料
可以调整的参数包括:
- 窗口大小
- 词向量维度
- 负采样数量
- 学习率
欢迎读者分享实验结果和优化心得,共同探讨词嵌入技术的最佳实践。
正文完
