基于Hierarchical softmax的word2vec模型

word2vec有两个重要的模型:CBOW模型和Skip-gram模型。如下图所示:

基于Hierarchical softmax的word2vec模型
这两个模型都包括输入层,投影层,输出层,如上右图CBOW模型时在已知当前词wtw_t的上下文wt2,wt1,wt+1,wt+2w_{t-2},w_{t-1},w_{t+1},w_{t+2}的前提下预测当前词wtw_t。而Skip-gram模型是在已知wtw_t的前提下,预测其上下文wt2,wt1,wt+1,wt+2w_{t-2},w_{t-1},w_{t+1},w_{t+2}

在神经网络语言模型中,目标函数通常取对数似然函数:
L=wClogp(wcontext(w)) \mathcal L = \sum_{w \in C} \log p(w|context(w))
CBOW模型的目标函数也是上式。其中的关键是条件概率函数logp(wcontext(w))\log p(w|context(w))的构造。

而Skip-gram模型的优化目标则是:
L=wClogp(context(w)w) \mathcal L = \sum_{w \in C} \log p(context(w)|w)

CBOW模型

基本结构

CBOW模型的网络结构包括三层:输入层,投影层,输出层。

基于Hierarchical softmax的word2vec模型

(1)输入层:包含comtext(w)comtext(w)中的2c2c个词向量v(context(w)1),v(context(w)2),,v(context(w)2c)Rm\mathbf v(context(w)_1),\mathbf v(context(w)_2),\ldots,\mathbf v(context(w)_{2c}) \in \mathbf R^m ,每个词向量的长度是mm

(2)投影层:将输入层的2c2c个词向量累加求和,即xw=i=12cv(context(w)i)\mathbf x_w = \sum_{i=1}^{2c}\mathbf v(context(w)_i)

(3)输出层:输出层对应一颗二叉树,这是一颗Huffman树,其叶子结点是语料库中的所有词,叶子个数N=|D|,分别对应词典D中的词。以各词在语料中出现的次数作为权值构建出来的Huffman树。(构建过程可参考:Huffman编码 )

CBOW模型与神经网络语言模型对比,主要有三个不同 :

(1)(从输入层到投影层的操作)前者是通过拼接,后者通过累加求和.

(2)(隐藏层)前者有隐藏层,后者无隐藏层.

(3)(输出层)前者是线性结构,后者是树形结构.

神经网络语言模型中大部分计算集中在隐藏层和输出层之间的矩阵向量运算,以及输出层上的softmax归一化运算,CBOW模型对这些计算复杂度高的地方有针对性地进行了改变,首先,去掉了隐藏层,其次,输出层改用了Huffman树,从而为利用Hierarchical softmax技术奠定了基础。

梯度计算

假设2014 年世界杯期间,从新浪微博中抓取了若干条与足球相关的微博,经统计,“我”、“喜欢”、“观看”、“巴西”、“足球”、“世界杯”这六个词出现的次数分别为15, 8, 6, 5,3, 1。用这些语料构建Huffman树,并将其作为CBOW模型的输出层。如下图所示:

基于Hierarchical softmax的word2vec模型

针对上图,规定:

pwp^w 表示从根结点出发到达ww对应叶子结点的路径,

lwl^w 表示这个路径中包含结点的个数,

plwp_{l}^w 表示路径 pwp^w中的第ll个结点,

djwd_j^w 表示路径pwp^w中第jj个结点对应的编码(0或1),

θjw\theta^w_j 表示路径pwp^w中第jj个结点对应向量(可以理解图中每一条边的都有一个权值向量)。

我们的目标是利用输入向量XwX_w 和Huffman树来定义函数p(wcontext(w))p(w|context(w))

以图中的词w=""w="足球"为例,从Huffman树的根结点出发到“足球”,中间经历了4个分支,每一次分支,都可以看成进行了一次二分类。那么从二分类的角度来看,对于每个非叶子结点,就需要为其左右孩子指定类别。我们规定:编码为1的结点定义为负类,编码为0的结点定义为正类。也就是说,将一个结点进行二分类,分到左边是负类,分到右边是正类。所以有:
Label(piw)=1diw,i=1,2,,lw Label(p_i^w) = 1- d_i^w, \quad i=1,2,\ldots,l^w
我们用逻辑斯蒂回归进行二分类,一个结点被分为正类的概率是:
σ(xwTθ)=11+exwTθ \sigma(\mathbf x_w^T\theta) = \frac{1}{1+e^{-\mathbf x_w^T\theta}}
被分成负类的概率为:
1σ(xwTθ) 1-\sigma(\mathbf x_w^T\theta)
这里的θ\theta指图中每一条边的都有一个权值向量。是个待定参数。

所以,从Huffman树的根结点出发到“足球”,中间经历了4个二分类,每个分类的结果如下:

第一次:p(d2wxw,θ1w)=1σ(xwTθ1w)p(d_2^w|\mathbf x_w,\theta_1^w) = 1- \sigma(\mathbf x_w^T\theta_1^w)

第二次:p(d3wxw,θ2w)=σ(xwTθ2w)p(d_3^w|\mathbf x_w,\theta_2^w) = \sigma(\mathbf x_w^T\theta_2^w)

第三次:p(d4wxw,θ3w)=σ(xwTθ3w)p(d_4^w|\mathbf x_w,\theta_3^w) = \sigma(\mathbf x_w^T\theta_3^w)

第四次:p(d5wxw,θ4w)=1σ(xwTθ4w)p(d_5^w|\mathbf x_w,\theta_4^w) = 1- \sigma(\mathbf x_w^T\theta_4^w)

这四个概率的乘积就是p(context())p(足球|context(足球)),即:
p(context())=j=25p(djwxw,θj1w) p(足球|context(足球)) = \prod_{j=2}^5 p(d_j^w|\mathbf x_w,\theta_{j-1}^w)
总结:对于词典D中的任意词w, Huffman树中必存在一条从根结点到词w对应结点的路径pwp^w (且这条路径是唯一的)。路径pwp^w上存在lw1l^w -1个分支,将每个分支看做一次二分类,每一次分类就产生一个概率, 将这些概率乘起来,就是所需的p(wContext(w))p(w|Context(w))

所以条件概率的定义如下:
p(wcontext(w))=j=2lwp(djwxw,θj1w) p(w|context(w)) = \prod_{j=2}^{l^w} p(d_j^w|\mathbf x_w,\theta_{j-1}^w)
其中:
p(djwxw,θj1w)={σ(xwTθj1w)djw=01σ(xwTθj1w)djw=1 p(d_j^w|\mathbf x_w,\theta_{j-1}^w) = \begin{cases} \sigma(\mathbf x_w^T\theta_{j-1}^w) \qquad d_j^w=0 \\ 1-\sigma(\mathbf x_w^T\theta_{j-1}^w) \quad d_j^w=1 \end{cases}
写成总体表达式如下:
p(djwxw,θj1w)=[σ(xwTθj1w)]1djw[1σ(xwTθj1w)]djw p(d_j^w|\mathbf x_w,\theta_{j-1}^w) = [\sigma(\mathbf x_w^T\theta_{j-1}^w)]^{1-d_j^w}\cdot[1-\sigma(\mathbf x_w^T\theta_{j-1}^w)]^{d_j^w}
所以我们的优化目标是:
L=wClogj=2lw{[σ(xwTθj1w)]1djw[1σ(xwTθj1w)]djw}=wCj=2lw{(1djw)log[σ(xwTθj1w)]+djwlog[1σ(xwTθj1w)]}=wCj=2lwL(w,j) \begin{aligned} \mathcal L &= \sum_{w \in C} log\prod_{j=2}^{l^w}\{ [\sigma(\mathbf x_w^T\theta_{j-1}^w)]^{1-d_j^w}\cdot[1-\sigma(\mathbf x_w^T\theta_{j-1}^w)]^{d_j^w}\} \\ &= \sum_{w \in C} \sum_{j=2}^{l^w}\{ ({1-d_j^w})\log[\sigma(\mathbf x_w^T\theta_{j-1}^w)]+d_j^w\log[1-\sigma(\mathbf x_w^T\theta_{j-1}^w)]\} \\ &= \sum_{w \in C} \sum_{j=2}^{l^w} \mathcal L(w,j) \end{aligned}
其中:$ \mathcal L(w,j) = ({1-d_j^w})\log[\sigma(\mathbf x_wT\theta_{j-1}w)]+d_j^w\log[1-\sigma(\mathbf x_wT\theta_{j-1}w)]$

这就是CBOW的目标函数。采用随机梯度上升法将这个函数最大化。

注:随机梯度上升法:随机取一个样本(context(w),w)(context(w),w),对目标函数中的所有的参数行一次更新。

(1)更新θj1w\theta_{j-1}^w

因为:
L(w,j)θj1w={(1djw)log[σ(xwTθj1w)]+djwlog[1σ(xwTθj1w)]}θj1w=(1djw)[1σ(xwTθj1w)]xwdjwσ(xwTθj1w)xw={(1djw)[1σ(xwTθj1w)]djwσ(xwTθj1w)}xw=[1djwσ(xwTθj1w)]xw\begin{aligned} \frac{\partial \mathcal L(w,j)}{\partial \theta_{j-1}^w} &= \frac{\partial \{ ({1-d_j^w})\log[\sigma(\mathbf x_w^T\theta_{j-1}^w)]+d_j^w\log[1-\sigma(\mathbf x_w^T\theta_{j-1}^w)]\} }{\partial \theta_{j-1}^w} \\ &= ({1-d_j^w})[1-\sigma(\mathbf x_w^T\theta_{j-1}^w)]\mathbf x_w - d_j^w\sigma(\mathbf x_w^T\theta_{j-1}^w) \mathbf x_w \\ &=\{(1-d_j^w)[1-\sigma(\mathbf x_w^T\theta_{j-1}^w)] - d_j^w\sigma(\mathbf x_w^T\theta_{j-1}^w) \}\mathbf x_w \\ & = [1-d_j^w-\sigma(\mathbf x_w^T\theta_{j-1}^w)]\mathbf x_w \end{aligned}
所以 θj1w\theta_{j-1}^w更新公式为:
θj1w:=θj1w+η[1djwσ(xwTθj1w)]xw \theta_{j-1}^w:=\theta_{j-1}^w + \eta [1-d_j^w-\sigma(\mathbf x_w^T\theta_{j-1}^w)]\mathbf x_w
其中η\eta为学习率。

(2)更新xw\mathbf x_w

因为L(w,j)\mathcal L(w,j) 关于变量xw\mathbf x_wθj1w\theta_{j-1}^w是对称的。所以:
L(w,j)xw=[1djwσ(xwTθj1w)]θj1w \begin{aligned} \frac{\partial \mathcal L(w,j)}{\partial \mathbf x_w} = [1-d_j^w-\sigma(\mathbf x_w^T\theta_{j-1}^w)]\theta_{j-1}^w \end{aligned}
这里存在一个问题:我们的最终目的是要求词典D中每个词的词向量,而这里的 xw\mathbf x_w 表示的是context(w)context(w)中各词词向量的累加。那么,如何利用L(w,j)xw\frac{\partial \mathcal L(w,j)}{\partial \mathbf x_w}来对v(w),wD\mathbf v(w),w \in D 进行更新呢? word2vec中的做法很简单, 直接取
v(w):=v(w)+ηj=2lwL(w,j)xw,wcontext(w) \mathbf v(w) := \mathbf v(w) + \eta \sum_{j=2}^{l^w} \frac{\partial \mathcal L(w,j)}{\partial \mathbf x_w},\quad w \in context(w)
注:既然xw\mathbf x_w 本身就是context(w)context(w)中各个词向量的累加,求完梯度后也应该将其贡献到每个分量上。

下面是CBOW模型中采用的随机梯度上升法伪代码:

基于Hierarchical softmax的word2vec模型

Skip-gram模型

基本结构

Skip-gram母模型的结构也是三层,下面以样本(w,context(w))(w,context(w))为例说明。如下图所示:

基于Hierarchical softmax的word2vec模型

(1)输入层:只包含当前样本中心词ww词向量v(w)Rm\mathbf v(w) \in \mathbf R^m ,每个词向量的长度是mm

(2)投影层:恒等投影,保留是为了与CBOW对比。

(3)输出层:与CBOW类似。

对于Skip-gram模型,已知的是当前词ww,需要对其上下文context(w)context(w)中的词进行预测,所以:
p(context(w)w)=ucontext(w)p(uw) p(context(w)|w) = \prod_{u \in context(w)} p(u|w)
类似于CBOW,所以:
p(uw)=j=2lup(djuv(w),θj1u) p(u|w) = \prod_{j=2}^{l^u}p(d_j^u|\mathbf v(w),\theta_{j-1}^u)
其中:
p(djuv(w),θj1u)=[σ(v(w)Tθj1u)]1dju[1σ(v(w)Tθj1u)]dju p(d_j^u|\mathbf v(w),\theta_{j-1}^u) = [\sigma(\mathbf v(w)^T\theta_{j-1}^u)]^{1-d_j^u}\cdot[1-\sigma(\mathbf v(w)^T\theta_{j-1}^u)]^{d_j^u}

所以我们的优化目标是:
L=wClogucontext(w)j=2lu{[σ(v(w)Tθj1u)]1dju[1σ(v(w)Tθj1u)]dju}=wCucontext(w)j=2lu{(1dju)log[σ(v(w)Tθj1u)]+djulog[1σ(v(w)Tθj1u)]}=wCucontext(w)j=2lu L(w,u,j) \begin{aligned} \mathcal L &= \sum_{w \in C} \log \prod_{u \in context(w)} \prod_{j=2}^{l^u} \{ [\sigma(\mathbf v(w)^T\theta_{j-1}^u)]^{1-d_j^u}\cdot[1-\sigma(\mathbf v(w)^T\theta_{j-1}^u)]^{d_j^u}\} \\ &= \sum_{w \in C} \sum_{u \in context(w)} \sum_{j=2}^{l^u} \{ (1-d_j^u) \log [\sigma(\mathbf v(w)^T\theta_{j-1}^u)]+d_j^ulog[1-\sigma(\mathbf v(w)^T\theta_{j-1}^u)] \}\\ &= \sum_{w \in C} \sum_{u \in context(w)} \sum_{j=2}^{l^u} \mathcal L(w,u,j) \end{aligned}
采用随机梯度上升法将这个函数最大化。

梯度更新

(1)更新θj1u\theta_{j-1}^u

因为:
L(w,u,j)θj1u={[σ(v(w)Tθj1u)]1dju[1σ(v(w)Tθj1u)]dju}θj1u=(1dju)[1σ(v(w)Tθj1u)]v(w)djuσ(v(w)Tθj1u)v(w)={(1dju)[1σ(v(w)Tθj1u)]djuσ(v(w)Tθj1u)}v(w)=[1djuσ(v(w)Tθj1u)]v(w) \begin{aligned}\frac{\partial \mathcal L(w,u,j)}{\partial \theta_{j-1}^u} &= \frac{\partial \{ [\sigma(\mathbf v(w)^T\theta_{j-1}^u)]^{1-d_j^u}\cdot[1-\sigma(\mathbf v(w)^T\theta_{j-1}^u)]^{d_j^u}\} }{\partial \theta_{j-1}^u} \\ &= ({1-d_j^u})[1-\sigma(\mathbf v(w)^T\theta_{j-1}^u)]\mathbf v(w) - d_j^u\sigma(\mathbf v(w)^T\theta_{j-1}^u) \mathbf v(w)\\ &=\{(1-d_j^u)[1-\sigma(\mathbf v(w)^T\theta_{j-1}^u)] - d_j^u\sigma(\mathbf v(w)^T\theta_{j-1}^u) \}\mathbf v(w) \\& = [1-d_j^u-\sigma(\mathbf v(w)^T\theta_{j-1}^u)]\mathbf v(w) \end{aligned}
所以 θj1w\theta_{j-1}^w更新公式为:
θj1u:=θj1u+η[1djuσ(v(w)Tθj1u)]v(w) \theta_{j-1}^u:=\theta_{j-1}^u + \eta [1-d_j^u-\sigma(\mathbf v(w)^T\theta_{j-1}^u)]\mathbf v(w)
其中η\eta为学习率。

(2)更新v(w)\mathbf v(w)

因为L(w,u,j)\mathcal L(w,u,j) 关于变量v(w)\mathbf v(w)θj1w\theta_{j-1}^w是对称的。所以:
L(w,u,j)v(w)=[1djuσ(v(w)Tθj1u)]θj1u \begin{aligned}\frac{\partial \mathcal L(w,u,j)}{\partial \mathbf v(w)} = [1-d_j^u-\sigma(\mathbf v(w)^T\theta_{j-1}^u)]\theta_{j-1}^u \end{aligned}
所以,v(w)\mathbf v(w)更新公式为:
v(w):=v(w)+ηucontext(w)j=2lwL(w,u,j)v(w),wcontext(w) \mathbf v(w) := \mathbf v(w) + \eta \sum_{u \in context(w)} \sum_{j=2}^{l^w} \frac{\partial \mathcal L(w,u,j)}{\partial \mathbf v(w)},\quad w \in context(w)
具体伪代码如下:

基于Hierarchical softmax的word2vec模型

优缺点

使用霍夫曼树来代替传统的神经网络,避免了从隐藏层到输出的softmax层这里的计算。也避免计算所有词的softmax概率。但是如果我们的训练样本里的中心词ww是一个很生僻的词,那么就得在霍夫曼树中辛苦的向下走很久了。解决这个问题则是采用基于Negative Sampling的模型。