共计 2274 个字符,预计需要花费 6 分钟才能阅读完成。
为什么需要词向量?
在自然语言处理(NLP)中,计算机需要将词语转换为数值形式才能进行处理。传统的表示方法如 one-hot 编码存在明显缺陷:

- 维度灾难:词汇表越大,向量维度越高
- 无法表达语义关系:所有词向量都是正交的
- 无法处理未登录词(OOV)
CBOW vs Skip-gram
Word2Vec 家族中两个主要模型对比:
- CBOW(Continuous Bag-of-Words)
- 通过上下文预测当前词
- 训练速度更快
-
对高频词表现更好
-
Skip-gram
- 通过当前词预测上下文
- 更适合处理低频词
- 需要更多训练时间
实际选择建议:
– 小型数据集优先考虑 CBOW
– 需要捕捉细粒度语义时选择 Skip-gram
PyTorch 实现详解
数据预处理
import torch
import torch.nn as nn
import torch.optim as optim
from collections import Counter
import numpy as np
# 构建词汇表
def build_vocab(corpus, min_freq=5):
vocab = Counter()
for sentence in corpus:
vocab.update(sentence.split())
# 过滤低频词
vocab = {word:idx for idx, (word, count) in enumerate(vocab.items())
if count >= min_freq}
# 添加特殊 token
vocab['<unk>'] = len(vocab)
vocab['<pad>'] = len(vocab)
return vocab
模型架构
class CBOW(nn.Module):
def __init__(self, vocab_size, embedding_dim, context_size):
super(CBOW, self).__init__()
self.embeddings = nn.Embedding(vocab_size, embedding_dim)
self.linear = nn.Linear(embedding_dim, vocab_size)
self.context_size = context_size
def forward(self, inputs):
# inputs 形状: [batch_size, 2*context_size]
embeds = self.embeddings(inputs) # [batch_size, 2*context_size, emb_dim]
out = torch.mean(embeds, dim=1) # 平均池化 [batch_size, emb_dim]
out = self.linear(out) # [batch_size, vocab_size]
return out
训练循环
def train_model(model, data_loader, epochs=10, lr=0.001):
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)
optimizer = optim.Adam(model.parameters(), lr=lr)
criterion = nn.CrossEntropyLoss()
for epoch in range(epochs):
total_loss = 0
for batch in data_loader:
context, target = batch
context, target = context.to(device), target.to(device)
optimizer.zero_grad()
output = model(context)
loss = criterion(output, target)
loss.backward()
optimizer.step()
total_loss += loss.item()
print(f"Epoch {epoch+1}, Loss: {total_loss/len(data_loader):.4f}")
性能优化技巧
- 批处理大小
- 一般从 64 开始尝试
- 较大 batch size(256+)可以提升 GPU 利用率
-
但可能降低模型泛化能力
-
学习率调整
- 初始学习率建议 0.001
-
配合 ReduceLROnPlateau 使用效果更佳
-
GPU 加速
- 使用混合精度训练(AMP)
- 预取数据(DataLoader 的 pin_memory=True)
生产环境部署
内存优化
- 量化模型权重(FP16->INT8)
- 使用 ONNX Runtime 加速推理
- 对高频词单独缓存其向量
处理 OOV 词
- 字符级嵌入补充
- 使用 FastText 的 subword 特性
- 相似词向量聚合
常见问题解决
维度不匹配错误
– 检查 embedding 层输入输出维度
– 确保 DataLoader 返回的数据形状一致
梯度爆炸
– 添加梯度裁剪(gradient clipping)
– 适当减小学习率
– 添加 BatchNorm 层
扩展思考
对于超大规模语料处理建议:
1. 分布式训练(Horovod 或 PyTorch DDP)
2. 增量训练(继续训练已有模型)
3. 层次 softmax 加速训练
实践建议
尝试在自己的业务数据上:
1. 比较不同窗口大小(context_size)的效果
2. 测试不同 embedding 维度(50/100/200/300)
3. 可视化词向量(TSNE 降维)观察聚类效果
CBOW 模型特别适合这些场景:
– 搜索 query 理解
– 推荐系统的内容表征
– 对话系统的意图识别
希望这篇实践指南能帮助你快速掌握 CBOW 模型的精髓,在实际业务中发挥词向量的强大威力。
正文完
