共计 2779 个字符,预计需要花费 7 分钟才能阅读完成。
背景介绍
CBOW(Continuous Bag of Words)模型是自然语言处理(NLP)中常用的词嵌入技术之一。它的核心思想是通过上下文预测当前词,从而学习到词的分布式表示。CBOW 模型在文本分类、机器翻译等任务中表现出色,因为它能够捕捉词语之间的语义关系。

与 Skip-gram 模型相比,CBOW 模型更适合处理小型数据集和频繁出现的词汇,因为它通过平均上下文信息来预测目标词,从而减少了噪声的影响。
CBOW 与 Skip-gram 的对比
- CBOW:通过上下文预测目标词,适合处理高频词,训练速度较快。
- Skip-gram:通过目标词预测上下文,适合处理低频词,训练速度较慢但效果更好。
核心实现
1. 词嵌入矩阵的初始化
词嵌入矩阵是 CBOW 模型的核心组件,通常使用随机初始化方法。矩阵的维度为 (词汇表大小, 嵌入维度)。
import numpy as np
vocab_size = 10000 # 词汇表大小
embedding_dim = 300 # 嵌入维度
# 随机初始化词嵌入矩阵
embedding_matrix = np.random.randn(vocab_size, embedding_dim) * 0.01
2. 前向传播计算过程
前向传播的目的是计算目标词的预测概率。具体步骤如下:
- 获取上下文词的嵌入向量。
- 计算上下文向量的平均值。
- 通过 softmax 函数计算目标词的概率分布。
def forward_pass(context_indices, embedding_matrix):
# 获取上下文词的嵌入向量
context_vectors = embedding_matrix[context_indices]
# 计算平均值
avg_vector = np.mean(context_vectors, axis=0)
# 计算目标词的概率分布
scores = np.dot(embedding_matrix, avg_vector)
probs = np.exp(scores) / np.sum(np.exp(scores))
return probs
3. 损失函数的选择与计算
CBOW 模型通常使用交叉熵损失函数,衡量预测概率与真实分布的差异。
def compute_loss(probs, target_index):
return -np.log(probs[target_index])
4. 反向传播中的梯度计算
反向传播的目的是计算损失函数对词嵌入矩阵的梯度,以便更新参数。
def backward_pass(context_indices, target_index, embedding_matrix, probs):
# 计算梯度
grad_embedding = np.zeros_like(embedding_matrix)
grad_embedding[target_index] = probs - 1
# 更新上下文词的梯度
for idx in context_indices:
grad_embedding[idx] += (probs - 1) / len(context_indices)
return grad_embedding
5. 参数更新策略
使用随机梯度下降(SGD)或其他优化算法更新词嵌入矩阵。
def update_embedding(embedding_matrix, grad_embedding, learning_rate=0.01):
embedding_matrix -= learning_rate * grad_embedding
return embedding_matrix
完整 Python 实现
以下是一个完整的 CBOW 模型实现,包含训练循环和评估代码。
import numpy as np
class CBOW:
def __init__(self, vocab_size, embedding_dim):
self.vocab_size = vocab_size
self.embedding_dim = embedding_dim
self.embedding_matrix = np.random.randn(vocab_size, embedding_dim) * 0.01
def forward(self, context_indices):
context_vectors = self.embedding_matrix[context_indices]
avg_vector = np.mean(context_vectors, axis=0)
scores = np.dot(self.embedding_matrix, avg_vector)
probs = np.exp(scores) / np.sum(np.exp(scores))
return probs
def backward(self, context_indices, target_index, probs):
grad_embedding = np.zeros_like(self.embedding_matrix)
grad_embedding[target_index] = probs - 1
for idx in context_indices:
grad_embedding[idx] += (probs - 1) / len(context_indices)
return grad_embedding
def train(self, context_indices, target_index, learning_rate=0.01):
probs = self.forward(context_indices)
loss = -np.log(probs[target_index])
grad_embedding = self.backward(context_indices, target_index, probs)
self.embedding_matrix -= learning_rate * grad_embedding
return loss
性能优化建议
1. 处理大规模词汇表
- 使用负采样(Negative Sampling)替代 softmax,减少计算量。
- 采用分层 softmax(Hierarchical Softmax)加速训练。
2. 加速训练过程
- 使用小批量(mini-batch)训练。
- 采用并行计算或 GPU 加速。
避坑指南
1. 数值不稳定问题
- 使用对数概率避免数值下溢。
- 对梯度进行裁剪,防止梯度爆炸。
2. 学习率选择
- 初始学习率设置为 0.01,根据训练效果动态调整。
- 使用学习率衰减策略。
3. 词嵌入质量评估
- 使用余弦相似度衡量词向量之间的语义关系。
- 通过下游任务(如文本分类)评估词嵌入效果。
结尾思考
CBOW 模型虽然简单,但在实际项目中仍有广泛应用。例如,可以将其用于推荐系统中的用户兴趣建模,或结合其他深度学习模型提升性能。未来,可以尝试结合注意力机制或预训练技术进一步改进模型效果。
希望本文能帮助你理解 CBOW 模型的实现细节,并在实际项目中灵活应用。
正文完
