共计 2071 个字符,预计需要花费 6 分钟才能阅读完成。
CBOW 模型架构回顾
CBOW(Continuous Bag-of-Words)是 Word2Vec 的两种经典模型之一,其核心思想是通过上下文词预测目标词。模型结构分为三层:

- 输入层 :接收上下文词的 one-hot 编码。例如窗口大小为 2 时,会同时输入目标词前后各 2 个词的 one-hot 向量
- 投影层(隐藏层):将多个上下文词的 one-hot 向量通过共享的嵌入矩阵转换为词向量,并取平均作为隐藏层输出
- 输出层 :通过另一个词向量矩阵将隐藏层表示映射到词汇表空间,最终通过 softmax 得到预测概率
词嵌入矩阵的数学表示
词嵌入矩阵本质上是模型训练过程中学习到的参数矩阵:
- 输入矩阵 W :维度为 [V×N],V 是词汇表大小,N 是嵌入维度。每一行对应一个词的输入向量表示
- 输出矩阵 W ’:维度为 [N×V],用于将隐藏层输出转换为词汇表空间
初始化通常采用随机小数值,如从均匀分布 U(-0.5/N, 0.5/N) 中采样。
词向量更新公式推导
核心是通过梯度下降更新矩阵参数:
-
前向传播:
$$ h = \frac{1}{C} \sum_{c=1}^C W^T x_c $$
$$ u = W’^T h $$
$$ y = \text{softmax}(u) $$ -
损失函数(交叉熵):
$$ L = -\log P(w_O|w_{I,1},…,w_{I,C}) $$ -
反向传播时,通过链式法则计算梯度并更新参数:
$$ \frac{\partial L}{\partial W’} = \sum_{j=1}^V (y_j – t_j)h $$
$$ \frac{\partial L}{\partial W} = \frac{1}{C} \sum_{c=1}^C x_c (y – t) W’ $$
Python 实现示例
import numpy as np
from collections import defaultdict
class CBOW:
def __init__(self, vocab_size, embedding_dim):
# 初始化权重矩阵
self.W1 = np.random.uniform(-0.5/embedding_dim, 0.5/embedding_dim,
(vocab_size, embedding_dim))
self.W2 = np.random.uniform(-0.5/embedding_dim, 0.5/embedding_dim,
(embedding_dim, vocab_size))
def forward(self, context_indices):
# 上下文词向量的均值作为隐藏层输出
h = np.mean(self.W1[context_indices], axis=0)
u = np.dot(self.W2.T, h)
y_pred = self._softmax(u)
return h, y_pred
def _softmax(self, x):
e_x = np.exp(x - np.max(x))
return e_x / e_x.sum()
def train(self, context_indices, target_index, lr=0.01):
# 前向传播
h, y_pred = self.forward(context_indices)
# 计算梯度
t = np.zeros_like(y_pred)
t[target_index] = 1
delta = y_pred - t
# 反向传播更新参数
dW2 = np.outer(h, delta)
dW1 = np.zeros_like(self.W1)
for i in context_indices:
dW1[i] += np.dot(self.W2, delta) / len(context_indices)
self.W1 -= lr * dW1
self.W2 -= lr * dW2
优化技术分析
- 负采样 :将 softmax 计算简化为对少量负样本的二元分类,大幅提升训练效率
- 采样概率:$$ P(w_i) = \frac{f(w_i)^{3/4}}{\sum_j f(w_j)^{3/4}} $$
-
目标函数变为:$$ \log \sigma(v’{w_O}^T h) + \sum}^k \mathbb{E{w_i} [\log \sigma(-v’^T h)] $$
-
层次 softmax:使用霍夫曼树将计算复杂度从 O(V) 降到 O(logV)
- 每个节点表示二分类概率:$$ P(d_j|w_j,\theta_j) = [\sigma(\theta_j^T h)]^{1-d_j} [1-\sigma(\theta_j^T h)]^{d_j} $$
生产环境最佳实践
- 维度选择 :
- 一般任务:50-300 维
-
专业领域:需更大的维度捕捉细微语义
-
训练数据量 :
- 至少需要千万级别的 token
-
专业领域建议领域内数据 + 通用语料混合
-
超参数调优 :
- 学习率:初始 0.025,线性衰减到 0.0001
- 窗口大小:简单任务用 3 -5,短语识别用 5 -10
- 负采样:5-20 个负样本,大数据集可减少
开放性问题
在不同应用场景下(如推荐系统、机器翻译、情感分析),CBOW 与 Skip-gram 哪种表现更好?为什么在某些场景下预训练词嵌入(如 GloVe)可能比 Word2Vec 更合适?这涉及到词嵌入方法对词频分布、语义组合等特性的捕捉差异。
