深入解析CBOW模型中的反向传播算法:从数学推导到代码实现

1次阅读
没有评论

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

image.webp

CBOW 模型与反向传播的必要性

CBOW(Continuous Bag of Words)是 Word2Vec 中的经典模型,通过上下文词预测中心词来学习词向量。它的核心优势在于对高频词处理更高效,适合大规模语料训练。反向传播算法则是训练神经网络的关键,通过计算损失函数对模型参数的梯度来更新权重。理解 CBOW 的反向传播过程,不仅能帮助调试模型,还能为后续优化(如负采样、层次 softmax)打下基础。

深入解析 CBOW 模型中的反向传播算法:从数学推导到代码实现

数学推导:从损失函数到梯度计算

1. 损失函数定义

CBOW 的损失函数采用交叉熵,对于单个训练样本:
$$ J = -\sum_{w \in V} y_w \log(\hat{y}w) $$
其中 $y_w$ 是真实标签(one-hot 向量),$\hat{y}_w$ 是预测概率(softmax 输出):
$$ \hat{y}_w = \frac{\exp(z_w)}{\sum
$$} \exp(z_{w’})

2. 输出层梯度计算

首先求损失对输出层得分 $z_j$ 的偏导:
$$ \frac{\partial J}{\partial z_j} = \hat{y}j – y_j $$
然后通过链式法则得到输出层权重 $W
$ 的梯度:
$$ \frac{\partial J}{\partial W_{ij}} = (\hat{y}_j – y_j) \cdot h_i $$
其中 $h_i$ 是隐藏层第 $i$ 维的输出。

3. 隐藏层梯度传播

隐藏层的梯度是所有输出神经元梯度的加权和:
$$ \frac{\partial J}{\partial h_i} = \sum_{j \in V} (\hat{y}j – y_j) \cdot W $$

Python 实现与优化

基础实现(向量化版本)

import numpy as np

# 初始化参数
vocab_size = 10000
embed_dim = 300
W1 = np.random.randn(vocab_size, embed_dim) * 0.01  # 输入层到隐藏层
W2 = np.random.randn(embed_dim, vocab_size) * 0.01  # 隐藏层到输出层

# 前向传播
def forward(context_ids):
    h = np.mean(W1[context_ids], axis=0)  # 平均上下文词向量
    z = np.dot(h, W2)
    y_hat = np.exp(z) / np.sum(np.exp(z))
    return h, y_hat

# 反向传播
def backward(context_ids, target_id, h, y_hat, learning_rate=0.01):
    # 计算梯度
    y = np.zeros(vocab_size)
    y[target_id] = 1
    dz = y_hat - y

    # 更新输出层权重
    dW2 = np.outer(h, dz)
    W2 -= learning_rate * dW2

    # 传播到隐藏层并更新输入层权重
    dh = np.dot(W2, dz)
    for word_id in context_ids:
        W1[word_id] -= learning_rate * dh / len(context_ids)

性能对比测试

# 非向量化实现(对比用)def slow_backward(context_ids, target_id, h, y_hat):
    # 此处省略实现细节
    # 实测在 vocab_size=10000 时比向量化版本慢约 50 倍
    pass

实践避坑指南

梯度爆炸处理

  • 现象:损失值突然变为 NaN
  • 解决:梯度裁剪(添加np.clip(grad, -1, 1))或权重初始化缩小 10 倍

学习率设置

  • 推荐初始值:0.025(随迭代线性递减到 0.001)
  • 监控指标:每 1000 词损失下降幅度应在 5%~15% 之间

稀疏矩阵优化

  1. 使用 scipy.sparse 存储词频矩阵
  2. 对高频词进行下采样(概率 $1-\sqrt{t/f(w)}$)
  3. 采用负采样替代全词表 softmax

思考题

  1. 如何修改代码支持负采样优化?
  2. 提示:只需采样少量负例,修改损失函数为 sigmoid 交叉熵

  3. 对比 Skip-gram 的反向传播差异

  4. 提示:Skip-gram 是中心词预测上下文,梯度会反向传播到多个输出节点

  5. 在大语料下的分布式训练方案

  6. 提示:考虑参数服务器架构或使用 Horovod 框架

总结

通过本文的推导和代码实践,我们拆解了 CBOW 反向传播的 ” 黑箱 ” 过程。建议读者尝试在小型语料(如 IMDB 数据集)上从头实现,逐步添加负采样等优化。理解这些基础原理后,学习更复杂的词嵌入模型(如 GloVe、BERT)会轻松许多。

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