基于分层Softmax的连续词袋模型(CBOW)训练算法详解
字数 2952 2025-12-14 06:55:46

基于分层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,而是构建一棵二叉树(通常是哈夫曼树)。

  • 树的构建

    1. 将所有词汇表中的词作为叶子节点。
    2. 根据词频构建哈夫曼树(高频词路径短)。
    3. 每个内部节点(共V-1个)有一个待学习的向量θ。
  • 关键思想
    预测一个词w的概率,转化为从根节点走到该词对应的叶子节点的路径概率。路径长度约为log₂(V),而不是V,极大减少了计算量。


三、算法逐步推演

3.1 前向传播过程

步骤1:输入上下文
假设上下文窗口大小为2C(左右各C个词)。取上下文词的one-hot向量:\(x_{1}, x_{2}, ..., x_{C}\)(每个维度为V)。

步骤2:计算隐藏层向量

  1. 每个输入词向量通过输入权重矩阵 \(W_{in}\)(维度V×N)查找对应的词向量(即矩阵的一行)。
  2. 将C个上下文词的词向量求和(CBOW的平均操作在后续改进中常见):
    \(h = \sum_{i=1}^{C} W_{in}^{T} x_{i}\)
    这里h是N维向量,是上下文的综合表示。

步骤3:沿分层Softmax树计算路径概率
假设要预测的目标词是w。

  1. 从根节点开始。
  2. 对于路径上的每个内部节点i:
    • 获取该节点的向量表示θ_i(维度为N)。
    • 计算节点i的“二分类”概率:
      \(\sigma(u_i) = \frac{1}{1 + e^{-u_i}}\), 其中 \(u_i = h^T θ_i\)
    • 如果下一步需要走向左子节点,则当前步的概率为σ(u_i)。
    • 如果下一步需要走向右子节点,则当前步的概率为1 - σ(u_i)。
  3. 将路径上所有节点的概率连乘,得到词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 反向传播与参数更新

需要更新的参数有两组:

  1. 输入权重矩阵W_in(即我们最终要获得的词向量)。
  2. 分层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算法,通过将庞大的多分类问题转化为一系列二分类问题,巧妙地解决了词向量训练的计算瓶颈。它的核心贡献在于:

  1. 计算高效:将复杂度从O(V)降至O(log V)。
  2. 物理意义明确:高频词路径短,学习更快。
  3. 词向量质量高:学习到的词向量能很好捕捉语义和句法规律。

尽管在超大规模训练中,负采样因其简单性更受欢迎,但分层Softmax的理论价值和在某些场景下的优势(如处理极高频词)使其仍然是自然语言处理基础中的重要算法。理解它为后续学习更复杂的词表示和预训练模型打下了坚实基础。

基于分层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的理论价值和在某些场景下的优势(如处理极高频词)使其仍然是自然语言处理基础中的重要算法。理解它为后续学习更复杂的词表示和预训练模型打下了坚实基础。