基于分层Softmax的连续词袋模型(CBOW)训练算法详解
我将为你详细讲解基于分层Softmax的CBOW训练算法。这个算法是Word2Vec的两种主要架构之一,用于高效学习词向量。
一、算法背景与问题描述
1.1 核心问题
我们想要把词汇表中的每个词(比如“apple”、“computer”)表示成一个固定维度的实数向量(词向量)。这些向量应该能捕捉语义关系,比如相似词的向量距离近,而且能满足“king - man + woman ≈ queen”这样的向量运算。
1.2 核心挑战
传统Softmax的问题:假设词汇表大小为V(如10万),那么每个训练步骤计算全词汇表的概率分布需要O(V)时间,计算量极大,训练非常慢。
1.3 CBOW模型的基本思想
CBOW(Continuous Bag-of-Words)模型通过上下文词预测中心词。例如,给定上下文“the cat sits on the”,预测中心词“mat”。
二、模型架构与核心组件
2.1 模型整体架构
输入层 -> 投影层 -> 输出层
- 输入层:上下文的C个词的one-hot向量(维度为V)。
- 投影层:将C个输入向量求和(或平均),得到一个隐藏层向量h(维度为N,如300维)。
- 输出层:由分层Softmax树构成,用于计算目标词的概率。
2.2 分层Softmax树的结构原理
这是算法的核心创新。我们不是直接计算10万个词的Softmax,而是构建一棵二叉树(通常是哈夫曼树)。
-
树的构建:
- 将所有词汇表中的词作为叶子节点。
- 根据词频构建哈夫曼树(高频词路径短)。
- 每个内部节点(共V-1个)有一个待学习的向量θ。
-
关键思想:
预测一个词w的概率,转化为从根节点走到该词对应的叶子节点的路径概率。路径长度约为log₂(V),而不是V,极大减少了计算量。
三、算法逐步推演
3.1 前向传播过程
步骤1:输入上下文
假设上下文窗口大小为2C(左右各C个词)。取上下文词的one-hot向量:\(x_{1}, x_{2}, ..., x_{C}\)(每个维度为V)。
步骤2:计算隐藏层向量
- 每个输入词向量通过输入权重矩阵 \(W_{in}\)(维度V×N)查找对应的词向量(即矩阵的一行)。
- 将C个上下文词的词向量求和(CBOW的平均操作在后续改进中常见):
\(h = \sum_{i=1}^{C} W_{in}^{T} x_{i}\)
这里h是N维向量,是上下文的综合表示。
步骤3:沿分层Softmax树计算路径概率
假设要预测的目标词是w。
- 从根节点开始。
- 对于路径上的每个内部节点i:
- 获取该节点的向量表示θ_i(维度为N)。
- 计算节点i的“二分类”概率:
\(\sigma(u_i) = \frac{1}{1 + e^{-u_i}}\), 其中 \(u_i = h^T θ_i\)。 - 如果下一步需要走向左子节点,则当前步的概率为σ(u_i)。
- 如果下一步需要走向右子节点,则当前步的概率为1 - σ(u_i)。
- 将路径上所有节点的概率连乘,得到词w的预测概率:
\(P(w | context) = \prod_{i=1}^{L(w)-1} \sigma([·] h^T θ_i)\)
其中L(w)是路径长度,[·]在向左时取+1,向右时取-1。
3.2 损失函数
使用对数似然损失。对于单个训练样本(上下文,目标词w):
\(Loss = -\log P(w | context) = -\sum_{i=1}^{L(w)-1} \log \sigma([·] h^T θ_i)\)
3.3 反向传播与参数更新
需要更新的参数有两组:
- 输入权重矩阵W_in(即我们最终要获得的词向量)。
- 分层Softmax树中所有内部节点的向量θ_i。
对θ_i的梯度:
令 \(d_i = [·] \in \{+1, -1\}\) 表示路径方向。
\(\frac{\partial Loss}{\partial θ_i} = [\sigma(d_i · h^T θ_i) - 1] · d_i · h\)
然后通过梯度下降更新:\(θ_i := θ_i - η · \frac{\partial Loss}{\partial θ_i}\)
对输入词向量的梯度:
损失函数对隐藏层h的梯度为:
\(\frac{\partial Loss}{\partial h} = \sum_{i=1}^{L(w)-1} [\sigma(d_i · h^T θ_i) - 1] · d_i · θ_i\)
由于h是C个输入词向量的和,这个梯度会均等地反向传播给这C个上下文词的输入向量。
因此,对于每个上下文词向量 \(v_{context}\):
\(\frac{\partial Loss}{\partial v_{context}} = \frac{1}{C} · \frac{\partial Loss}{\partial h}\)
然后更新:\(v_{context} := v_{context} - η · \frac{\partial Loss}{\partial v_{context}}\)
四、算法特点与深入理解
4.1 为什么能加速?
传统Softmax:每个样本计算需要与V个输出神经元交互,复杂度O(V)。
分层Softmax:每个样本只需与路径上约log₂(V)个内部节点交互,复杂度O(log V)。当V=10万时,log₂(V)≈17,加速近6000倍。
4.2 树的构建细节
通常使用哈夫曼树,依据词频构建。高频词路径短,更新更快;低频词路径长,更新稍慢。这符合信息论最优编码,也符合语言先验知识。
4.3 与原始Softmax的本质区别
原始Softmax是一种“平坦”结构,所有词相互竞争。
分层Softmax是一种“层次”结构,通过一系列二分类决策逐步缩小范围。这类似于在分类时先问“是动物吗?”,再问“是猫科吗?”,最后问“是猫吗?”。
4.4 与负采样(Negative Sampling)的对比
- 分层Softmax:用树结构避免全词汇计算,但需要维护和更新树节点向量。
- 负采样:用少量负样本近似损失函数,更简单直观,常用于大规模语料。
两者都是解决Softmax计算瓶颈的工程技巧,效果通常相当。
五、总结与应用
基于分层Softmax的CBOW算法,通过将庞大的多分类问题转化为一系列二分类问题,巧妙地解决了词向量训练的计算瓶颈。它的核心贡献在于:
- 计算高效:将复杂度从O(V)降至O(log V)。
- 物理意义明确:高频词路径短,学习更快。
- 词向量质量高:学习到的词向量能很好捕捉语义和句法规律。
尽管在超大规模训练中,负采样因其简单性更受欢迎,但分层Softmax的理论价值和在某些场景下的优势(如处理极高频词)使其仍然是自然语言处理基础中的重要算法。理解它为后续学习更复杂的词表示和预训练模型打下了坚实基础。