CBOW模型手算词嵌入步骤详解:从梯度计算到实现优化

1次阅读
没有评论

共计 1862 个字符,预计需要花费 5 分钟才能阅读完成。

image.webp

背景介绍

CBOW(Continuous Bag of Words)模型是 Word2Vec 的两种主要架构之一,它通过上下文词汇预测当前词来学习词向量。与 Skip-gram 模型不同,CBOW 更适合处理小型数据集,且在小规模语料上收敛更快。其核心思想是:给定一个中心词周围的上下文窗口,模型学习预测该中心词。这种方法的优势在于能有效捕捉词汇的语义和语法关系,广泛应用于词义相似度计算、文本分类等下游任务。

CBOW 模型手算词嵌入步骤详解:从梯度计算到实现优化

核心计算步骤

1. 词向量初始化

  • 为词汇表中的每个词随机初始化两个向量:
  • 输入向量(context vector):当词作为上下文时使用
  • 输出向量(target vector):当词作为目标词时使用
  • 假设词汇表大小为 V,嵌入维度为 d,则初始化两个 V×d 的矩阵 W 和 W ’

2. 上下文窗口处理

  • 定义窗口大小 k(通常取 2 -5),对每个中心词取其前后各 k 个词作为上下文
  • 对上下文词进行 one-hot 编码,形成向量 x_i ∈ R^V
  • 计算上下文词向量的平均值:
    h = (1/C) * Σ(W^T * x_i)

    其中 C 是上下文词数量

3. 前向传播

  • 将平均向量 h 与输出矩阵 W ’ 相乘得到分数向量:
    u = W' * h
  • 通过 softmax 计算预测概率分布:
    ŷ = softmax(u)

4. 损失计算

  • 使用交叉熵损失函数:
    L = -Σ y_i * log(ŷ_i)

    其中 y 是真实标签的 one-hot 向量

5. 梯度反向传播

  • 计算输出层梯度:
    ∂L/∂u = ŷ - y
  • 更新输出矩阵 W ’:
    ∂L/∂W' = h * (ŷ - y)^T
  • 计算隐藏层梯度:
    ∂L/∂h = W' * (ŷ - y)
  • 更新输入矩阵 W:
    ∂L/∂W = (1/C) * Σ x_i * (∂L/∂h)^T

Python 实现示例

import numpy as np

# 超参数设置
V = 10000  # 词汇表大小
d = 300    # 嵌入维度
lr = 0.01  # 学习率

# 初始化权重矩阵
W = np.random.randn(V, d) * 0.01  # 输入矩阵
W_prime = np.random.randn(d, V) * 0.01  # 输出矩阵

# 模拟数据:上下文词索引和中心词索引
context_indices = [10, 20, 30]  # 假设窗口大小为 3
center_index = 15               # 目标词索引

# 前向传播
# 1. 构造上下文向量
context_vectors = W[context_indices, :]  # 获取上下文词向量
h = np.mean(context_vectors, axis=0)     # 平均上下文向量

# 2. 计算分数
u = np.dot(W_prime.T, h)

# 3. softmax 计算
exp_u = np.exp(u - np.max(u))  # 数值稳定处理
y_hat = exp_u / np.sum(exp_u)

# 构造真实标签
Y = np.zeros(V)
Y[center_index] = 1

# 计算损失
loss = -np.sum(Y * np.log(y_hat + 1e-10))  # 加小量防止 log(0)

# 反向传播
# 1. 输出层梯度
du = y_hat - Y

# 2. 更新输出矩阵
W_prime -= lr * np.outer(h, du)

# 3. 隐藏层梯度
dh = np.dot(W_prime, du)

# 4. 更新输入矩阵
for idx in context_indices:
    W[idx, :] -= lr * (1/len(context_indices)) * dh

性能考量

  1. 计算复杂度分析
  2. softmax 计算复杂度为 O(V),当词汇表很大时成为瓶颈
  3. 每次更新需要修改 |C|+ 1 个词向量(上下文词 + 中心词)

  4. 优化方法

  5. 负采样:将 softmax 替换为多个二分类问题
  6. 层次 softmax:使用霍夫曼树减少计算量
  7. 异步 SGD:允许并行更新不同词向量
  8. 向量化实现:利用 numpy 广播机制加速矩阵运算

避坑指南

  1. 数值不稳定问题
  2. 在计算 softmax 时先减去最大值
  3. 对 log 计算添加小量(如 1e-10)防止 NaN

  4. 梯度爆炸 / 消失

  5. 初始化权重时使用较小方差(如 0.01)
  6. 实施梯度裁剪(gradient clipping)

  7. 收敛缓慢

  8. 适当增大学习率(尝试 0.025-0.05)
  9. 使用 Adagrad 或 Adam 优化器

  10. 效果不佳

  11. 检查窗口大小是否合适(常用 5)
  12. 确保训练迭代次数足够(通常需要 5 -50 个 epoch)

总结与延伸

通过手动实现 CBOW 模型,我们深入理解了词嵌入的训练机制。对于大规模应用,建议:
1. 使用 gensim 或 TensorFlow 等框架的优化实现
2. 尝试在大型语料(如 Wikipedia)上训练
3. 结合 subword 信息处理 OOV 问题
4. 探索与 BERT 等新型架构的对比差异

CBOW 作为词嵌入的基础模型,其思想在当今预训练模型中仍有体现。理解其计算过程有助于掌握更复杂的 NLP 模型。

正文完
 0
评论(没有评论)