0x02 Hierarchical Softmax

原因

无论是CBOW模型还是Skip-gram模型, 输出层都是预测出一个单词. 由于语料库中词语的数量巨大, 因此直接使用softmax输出预测结果是几乎不可行的. 所以需要使用Hierarchical Softmax方法对输出层结构进行优化.

霍夫曼树

Hierarchical Softmax结构使用霍夫曼树来进行优化, 有必要了解霍夫曼树的原理.

霍夫曼树的构建过程如下:

  • 输入: nn个结点(这里每个结点代表一个单词), 对应的权值向量为(w1,w2,,wn)(w_1, w_2, \cdots, w_n)

  • 输出: 霍夫曼树

  • 过程

    • 将所有的nn个结点每一个看成一棵, 共有nn棵树, 每棵树的结点都只有一个. 组成森林

    • 在森林中选取根节点权值最小的两棵树进行合并, 得到一棵新的树. 原来的两棵树分别作为新书的左右子树, 新树的根节点权重为左右子树的根节点权重之和. 然后将原来的两棵树删除

    • 重复上一步, 直到只有一棵树为止

霍夫曼树的特点: 权重高的叶子结点靠近根节点, 编码值较短; 权重低的远离根节点, 编码值较长. 因此整体的编码效率会提高.

霍夫曼树应用于word2vec

将霍夫曼树应用在投影层(Projection Layer)到输出层之间, 用霍夫曼树的结构代替了softmax层的映射. 避免了计算字典中所有单词的softmax概率, 在每个结点只需要判断左右两个行进方向, 沿着树一直走到样本单词对应的叶子结点, 整体结构示例如下:

这种霍夫曼树形状的神经网络结构为:

  • 非叶子结点相当于一个神经元, 有自身的参数向量, 长度与设定的词嵌入向量的长度相同. 二分类决策输出01, 0表示选择左子树, 1表示选择右子树.

  • 每个叶子结点代表语料库中的一个单词, 因此叶子结点的数量就是语料库词汇表中单词的数量.

  • 每个结点(除了根节点, 包括非叶子结点和叶子结点)都可以用01唯一地编码

  • 投影层输出层不是一下完成的, 而是沿着树一步步完成的, 结果的路径对应着一个结点的编码序列

Hierarchical Softmax模型的梯度计算

引入符号

  • ww: 中心词

  • xwx_w: 中心词对应的参数向量

  • pwp^w: 从根节点出发到达词ww对应的叶子结点的路径

  • lwl^w: 路径pwp^w中包含的结点个数, 也即是层数

  • p1w,p2w,,plwwp_1^w,p_2^w,\cdots,p_{l^w}^w: 路径pwp^w中包含的结点

  • d2w,,dlwwd_2^w,\cdots,d_{l^w}^w: djw{0,1}, j=1,2,,lwd^w_j\in\{0,1\},\ j=1,2,\cdots,l^w, djwd^w_j表示路径pwp^w中第jj个结点对应的编码(根节点无编码)

  • θ1w,θ2w,,θlw1w\theta^w_1,\theta^w_2,\cdots,\theta^w_{l^{w-1}}: 路径pwp^w中对应的非叶子结点的参数向量

对于每个非叶子结点, 判断下一步的行进方向. 由于每个非叶子结点都是一个神经元, 因此每个神经元都会进行感知机+sigmoid激活函数的操作, 即:

P(+)=σ(xwTθ)=11+exwTθP(+) = \sigma(x_w^T\theta) = \frac{1}{1+e^{-x_w^T\theta}}

因此对应一个(w, Context(w))(w,\ \text{Context}(w))样本, 对应的条件概率(似然函数)为:

p(wContext(w))=j=2lwp(djwxw,θj1w)p(w|\text{Context}(w))=\prod\limits_{j=2}^{l^w}p(d^w_j|x_w,\theta^w_{j-1})

从根节点到叶子结点经历了lw1l^{w-1}个结点. 而其中的每一项都是一个逻辑回归:

p(djwxw,θj1w)={σ(xwTθj1w),djw=01σ(xwTθj1w),djw=1p(d^w_j|x_w,\theta^w_{j-1}) = \begin{cases} \sigma(x_w^T\theta^w_{j-1}), \quad & d^w_j=0 \\ 1- \sigma(x_w^T\theta^w_{j-1}), \quad & d^w_j=1 \end{cases}

用逻辑回归常用的形式, 写在一起有:

p(djwxw,θj1w)=[σ(xwTθj1w)]1djw[1σ(xwTθj1w)]djwp(d^w_j|x_w,\theta^w_{j-1})=[\sigma(x_w^T\theta^w_{j-1})]^{1 - d^w_j}[1-\sigma(x_w^T\theta^w_{j-1})]^{d^w_j}

对于一个中心词ww求最大似然:

L=logj=2lwP(djwxw,θj1w)=j=2lw((1djw)log[σ(xwTθj1w)]+djwlog[1σ(xwTθj1w)])\mathcal{L}=\log \prod_{j=2}^{l_w}P(d_j^w|x_w, \theta_{j-1}^w) = \sum\limits_{j=2}^{l_w} ((1-d_j^w) \log [\sigma(x_w^T\theta_{j-1}^w)] + d_j^w \log[1-\sigma(x_w^T\theta_{j-1}^w)])

最大似然, 对每个样本, 带入偏导数表达式求得函数在该参数上的增长梯度, 使用梯度上升法更新参数. 这里有两个参数:

  • 每个结点的参数向量θj1w\theta^w_{j-1}, 求得偏导数为:

    Lθj1w=(1djw)(σ(xwTθj1w)(1σ(xwTθj1w)σ(xwTθj1w)xwdjw(σ(xwTθj1w)(1σ(xwTθj1w)1σ(xwTθj1w)xw=(1djw)(1σ(xwTθj1w))xwdjwσ(xwTθj1w)xw=(1djwσ(xwTθj1w))xw\begin{aligned} \frac{\partial L}{\partial \theta_{j-1}^w} & = (1-d_j^w)\frac{(\sigma(x_w^T\theta_{j-1}^w)(1-\sigma(x_w^T\theta_{j-1}^w)}{\sigma(x_w^T\theta_{j-1}^w)}x_w - d_j^w \frac{(\sigma(x_w^T\theta_{j-1}^w)(1-\sigma(x_w^T\theta_{j-1}^w)}{1- \sigma(x_w^T\theta_{j-1}^w)}x_w \\ & = (1-d_j^w)(1-\sigma(x_w^T\theta_{j-1}^w))x_w - d_j^w\sigma(x_w^T\theta_{j-1}^w)x_w \\& = (1-d_j^w-\sigma(x_w^T\theta_{j-1}^w))x_w \end{aligned}

  • 单词ww对应的嵌入参数向量xwx_w, 这就是我们最终需要的单词对应的词向量. 求得到偏导数为

    Lxw=j=2lw(1djwσ(xwTθj1w))θj1w\frac{\partial L}{\partial x_w} = \sum\limits_{j=2}^{l_w}(1-d_j^w-\sigma(x_w^T\theta_{j-1}^w))\theta_{j-1}^w

关于Hierarchical Softmax结构还有几点需要注意的地方:

  • 作为一个层级形式的神经网络结构, 与平常使用的结构(DNN)不同的地方是, 每一层神经元的输出结果都是一个标量, 用作选择下一步前进的方法, 而不是产生向量继续输入到这个结点的子树中去

  • 因此每个结点的输入也就不是上层的结果, 而都是输入层单词ww对应的嵌入参数向量xwx_w, 整个路径中的所有神经元的输入都是这个向量

基于Hierarchical Softmax的CBOW模型

CBOW模型结合Hierarchical Softmax中需要注意的部分.

定义上下文的单侧窗口大小cc, 对于每个中心词, 其前面的cc个词和后面的cc个词都作为CBOW模型的输入.

输入层隐藏层的映射为对中心词ww周围的2c2c个词的词向量求和并平均, 也可以只求和不平均, 并没有什么区别, 因此在最后梯度上升时学习率与这里求平均可以结合在一起. 因此得到:

xw=i=12cxix_w=\sum\limits_{i=1}^{2c}x_i

然后通过梯度上升法来更新θj1w\theta^w_{j-1}xwx_w, 这里的xwx_w向量是2c2c个单词之和. 更新形式为:

θj1w=θj1w+η(1djwσ(xwTθj1w))xw\theta_{j-1}^w = \theta_{j-1}^w + \eta (1-d_j^w-\sigma(x_w^T\theta_{j-1}^w))x_w

xw=xw+ηj=2lw(1djwσ(xwTθj1w))θj1w  (i=1,2..,2c)x_w= x_w +\eta \sum\limits_{j=2}^{l_w}(1-d_j^w-\sigma(x_w^T\theta_{j-1}^w))\theta_{j-1}^w \;(i =1,2..,2c)

其中的η\eta就是学习率.

整体总结如下:

  • 输入: 训练语料样本, 上下文单侧窗口长度cc, 学习率η\eta

  • 输出: 所有词ww的词向量xwx_w; 非叶子结点参数θ\theta

  • 过程

    • 基于语料建立霍夫曼树, 主要是根据词频

    • 随机初始化所有词的词向量, 所有非叶子结点的参数向量

    • 对于训练集中的每一个样本(w, Context(w))(w,\ \text{Context}(w)), 使用梯度上升法进行求解. 这里的Context(w)\text{Context}(w)不是一个单词, 而是中心词ww附近的2c2c个上下文单词

      • 中间变量e=0e=0

      • xw=i=12cxix_w=\sum\limits_{i=1}^{2c}x_i

      • for j=2 to lw\text{for } j =2 \text{ to } l^w, 计算:

        • f=σ(xwTθj1w)f = \sigma(x_w^T\theta_{j-1}^w)

        • g=(1djwf)ηg = (1-d_j^w-f)\eta

        • e=e+gθj1we = e + g\theta_{j-1}^w

        • θj1w=θj1w+gxw\theta_{j-1}^w= \theta_{j-1}^w + gx_w

      • 对于Context(w)\text{Context}(w)中包含的每一个词对应的词向量xi,i=1,2,,2cx_i,\quad i=1,2,\cdots,2c进行相同的更新:

        xi=xi+ex_i = x_i + e

    • 梯度收敛则停止迭代, 否则继续循环上一步

基于Hierarchical Softmax的Skip-Gram模型

Skip-gram只是逆转了CBOW的因果关系而已, 对于CBOW, 我们对p(wContext(w))p(w|\text{Context}(w))进行最大似然, 对于Skip-Gram就要对p(Context(w)w)p(\text{Context}(w)|w)进行最大似然了:

p(Context(w)w)=uContext(w)p(uw)p(\text{Context}(w)|w)=\prod\limits_{u\in{\text{Context(w)}}}p(u|w)

即求中心词ww和上下中每一个词uu的条件概率. 这点与CBOW不同. CBOW是将上下文中所有的词加和起来与中心词产生条件概率, 相当于是两个词之间的关系. 而Skip-gram中是中心词与上下文中每一个词的关系, 因此计算要多一层对上下文词的循环.

另外由于CBOW的条件概率为p(wContext(w))p(w|\text{Context}(w)), 是上下文词预测中心词, 所以每一轮梯度上升中更新的是上下文中所有词的词向量. Skip-gram的条件概率为p(Context(w)w)p(\text{Context}(w)|w), 是中心词预测上下文词, 那么对于上下午中的所有词, 更新的都是中心词ww对应的词向量xwx_w. 这样在迭代的过程可能出现不均衡的现象.

从期望条件概率p(uw)p(u|w)的角度来讲, 上下文是相互的, 因此对于uuww两个词来说, 相互的条件概率是相同的, 因此就可以转换为对条件概率p(wu)p(w|u)期望最大. 这样我们就可以跟CBOW模型一样, 在一个中心词样本中, 对所有上下文词对应的向量进行更新了. 区别只在于多了一个对于上下文词的循环层.

因此整个过程总结如下:

  • 输入: 训练语料样本, 上下文单侧窗口长度cc, 学习率η\eta

  • 输出: 所有词ww的词向量xwx_w; 非叶子结点参数θ\theta

  • 过程:

    • 基于语料建立霍夫曼树, 主要是根据词频

    • 随机初始化所有词的词向量, 所有非叶子结点的参数向量

    • 对于训练集中的每一个样本(w, Context(w))(w,\ \text{Context}(w)), 使用梯度上升法进行求解. 这里的Context(w)\text{Context}(w)不是一个单词, 而是中心词ww附近的2c2c个上下文单词

      • for i=1 to 2c\text{for } i =1 \text{ to } 2c, 即对上下文中的每个词:

        • 中间变量e=0e=0

        • for j=2 to lw\text{for } j =2 \text{ to } l^w, 计算:

          • f=σ(xwTθj1w)f = \sigma(x_w^T\theta_{j-1}^w)

          • g=(1djwf)ηg = (1-d_j^w-f)\eta

          • e=e+gθj1we = e + g\theta_{j-1}^w

          • θj1w=θj1w+gxw\theta_{j-1}^w= \theta_{j-1}^w + gx_w

        • xi=xi+ex_i = x_i + e

    • 梯度收敛则停止迭代, 否则继续循环上一步

参考

word2vec原理推导与代码分析

word2vec原理(二) 基于Hierarchical Softmax的模型

最后更新于

这有帮助吗?