共计 2229 个字符,预计需要花费 6 分钟才能阅读完成。
背景介绍
词嵌入是自然语言处理(NLP)中的核心技术之一,它将词语映射到低维连续向量空间,使得语义相似的词在向量空间中距离相近。CBOW(Continuous Bag of Words)模型是词嵌入的经典实现之一,由 Mikolov 等人在 2013 年提出。与 Skip-gram 模型不同,CBOW 模型通过上下文词预测中心词,特别适合处理小型数据集。

核心原理
CBOW 模型的核心架构包括输入层、隐藏层和输出层。输入层接收上下文词的 one-hot 编码,隐藏层通过权重矩阵计算上下文词向量的平均值,输出层通过另一个权重矩阵计算中心词的概率分布。
- 输入层到隐藏层的权重矩阵计算 :
- 输入层是一个大小为 V 的 one-hot 向量(V 是词汇表大小)。
- 隐藏层是一个大小为 N 的向量(N 是嵌入维度)。
- 输入层到隐藏层的权重矩阵 W 是一个 V×N 的矩阵,每一行对应一个词的嵌入向量。
-
隐藏层的输出是上下文词向量的平均值。
-
隐藏层到输出层的权重矩阵计算 :
- 输出层是一个大小为 V 的向量,表示中心词的概率分布。
- 隐藏层到输出层的权重矩阵 W ’ 是一个 N×V 的矩阵。
- 输出层的计算涉及 softmax 函数,但实际训练中常使用负采样优化。
训练细节
- 上下文窗口处理 :
- CBOW 模型通过滑动窗口获取上下文词。例如,窗口大小为 2 时,上下文词包括中心词左右各 2 个词。
-
上下文词的数量和窗口大小会影响模型性能。
-
负采样优化 :
- 传统的 softmax 计算复杂度高,负采样通过采样少量负样本(非目标词)来近似优化目标。
- 负采样的概率分布通常与词频相关,高频词更容易被采样为负样本。
代码实现
以下是一个简化版 CBOW 模型的 Python 实现,使用 NumPy 库:
import numpy as np
# 参数设置
vocab_size = 1000 # 词汇表大小
embedding_dim = 100 # 嵌入维度
window_size = 2 # 上下文窗口大小
learning_rate = 0.01 # 学习率
# 初始化权重矩阵
W1 = np.random.randn(vocab_size, embedding_dim) # 输入层到隐藏层
W2 = np.random.randn(embedding_dim, vocab_size) # 隐藏层到输出层
# 训练函数
def train_cbow(context_words, target_word):
# 上下文词的 one-hot 编码
context_vectors = np.zeros((len(context_words), vocab_size))
for i, word in enumerate(context_words):
context_vectors[i, word] = 1
# 隐藏层计算:上下文词向量的平均值
hidden_layer = np.mean(np.dot(context_vectors, W1), axis=0)
# 输出层计算
output = np.dot(hidden_layer, W2)
# 计算损失(使用负采样简化)loss = -output[target_word] + np.log(np.sum(np.exp(output)))
# 反向传播
grad_output = np.exp(output) / np.sum(np.exp(output))
grad_output[target_word] -= 1
grad_W2 = np.outer(hidden_layer, grad_output)
grad_hidden = np.dot(grad_output, W2.T)
grad_W1 = np.zeros_like(W1)
for i, word in enumerate(context_words):
grad_W1[word, :] += grad_hidden / len(context_words)
# 更新权重
W1 -= learning_rate * grad_W1
W2 -= learning_rate * grad_W2
return loss
# 示例训练数据
context_words = [1, 2, 3, 4] # 上下文词的索引
target_word = 5 # 目标词的索引
# 训练一步
loss = train_cbow(context_words, target_word)
print(f"Loss: {loss}")
性能考量
- 计算复杂度 :
- CBOW 模型的计算复杂度主要取决于词汇表大小 V 和嵌入维度 N。
-
使用负采样可以将复杂度从 O(V) 降低到 O(k),其中 k 是负样本数量。
-
内存消耗 :
- 权重矩阵 W 和 W ’ 的大小分别为 V×N 和 N×V,可能占用大量内存。
- 对于大规模词汇表,可以采用分布式训练或模型压缩技术。
避坑指南
- 数据预处理 :
- 确保文本数据经过清洗(去除标点、停用词等)。
-
对低频词进行过滤或替换,避免噪声干扰。
-
超参数调优 :
- 嵌入维度过小可能导致信息丢失,过大可能增加计算负担。
-
学习率过高可能导致模型不稳定,过低可能导致训练缓慢。
-
训练技巧 :
- 使用动态窗口大小增加数据多样性。
- 采用自适应学习率优化器(如 Adam)加速收敛。
总结与展望
CBOW 模型是词嵌入技术的经典实现,适合处理小型数据集和上下文丰富的任务。然而,它也存在一些局限性,例如对低频词的处理不足。近年来,更先进的词嵌入技术(如 BERT、GPT)通过上下文感知的嵌入方式取得了更好的性能。未来,结合预训练和微调的词嵌入方法将成为主流。
思考题
- 如何通过调整 CBOW 模型的窗口大小来平衡模型的局部和全局语义捕捉能力?
- 负采样中的概率分布如何影响模型的训练效果?是否可以设计更优的采样策略?
- CBOW 模型在处理多义词时有哪些局限性?如何改进?
正文完
