本篇是介绍基于Hierarchical Softmax的 CBOW 模型和 Skip-gram 模型。
CBOW 模型是在已知当前词 w t w_t wt的上下文 w t − 2 , w t − 1 , w t + 1 , w t + 2 w_{t-2},w_{t-1},w_{t+1},w_{t+2} wt−2,wt−1,wt+1,wt+2的前提下预测当前词 w t w_t wt。后面我们用 c o m t e x t ( w ) comtext(w) comtext(w)来表示词w的上下文中的词,通常,我们取词 w 前后 2c 个单词来组成 c o m t e x t ( w ) comtext(w) comtext(w)。下图给出了 CBOW 模型的网络结构:
它包括三层:输入层,投影层,输出层。
(1)输入层:包含 c o m t e x t ( w ) comtext(w) comtext(w)中的 2 c 2c 2c个词向量 v ( c o n t e x t ( w ) 1 ) , v ( c o n t e x t ( w ) 2 ) , … , v ( c o n t e x t ( w ) 2 c ) ∈ R m \mathbf v(context(w)_1),\mathbf v(context(w)_2),\ldots,\mathbf v(context(w)_{2c}) \in \mathbf R^m v(context(w)1),v(context(w)2),…,v(context(w)2c)∈Rm ,每个词向量的长度是 m m m。
(2)投影层:将输入层的 2 c 2c 2c个词向量累加求和,即 x w = ∑ i = 1 2 c v ( c o n t e x t ( w ) i ) \mathbf x_w = \sum_{i=1}^{2c}\mathbf v(context(w)_i) xw=∑i=12cv(context(w)i) 。
(3)输出层:输出层是用哈夫曼算法以各词在语料中出现的次数作为权值生成的一颗二叉树,其叶子结点是语料库中的所有词,叶子个数N=|D|,分别对应词典D中的词。
神经网络语言模型(NNLM)中大部分计算集中在隐藏层和输出层之间的矩阵向量运算,以及输出层上的softmax归一化运算,CBOW模型对此进行了改进。与传统的神经网络语言模型相比:
假设对于给定的文本,“我”、“喜欢”、“观看”、“巴西”、“足球”、“世界杯”这六个词出现的次数分别为15, 8, 6, 5,3, 1。于是可以用这些语料构建霍夫曼树,并将其作为CBOW模型的输出层。如下图所示:
注意:与常规的霍夫曼树不同,左子树用1编码,右子树用0编码。
接下来,我们用 p w p^w pw 表示从根结点出发到达 w w w对应叶子结点的路径, l w l^w lw 表示这个路径中包含结点的个数, p l w p_{l}^w plw 表示路径 p w p^w pw中的第 l l l个结点, d j w d_j^w djw 表示路径 p w p^w pw中第 j j j个结点对应的编码(0或1), θ j w \theta^w_j θjw 表示路径 p w p^w pw中第 j j j个非叶子结点对应向量。
我们的目标是利用输入向量 X w X_w Xw 和霍夫曼树来定义函数 p ( w ∣ c o n t e x t ( w ) ) p(w|context(w)) p(w∣context(w))。
以图中的词 w = " 足 球 " w="足球" w="足球"为例,从霍夫曼树的根结点出发到“足球”,中间经历了4个分支,每一次分支,都可以看成进行了一次二分类。那么从二分类的角度来看,对于每个非叶子结点,就需要为其左右孩子指定类别。我们规定:编码为1的结点定义为负类,编码为0的结点定义为正类。也就是说,将一个结点进行二分类,分到左边是负类,分到右边是正类。所以有:
L a b e l ( p i w ) = 1 − d i w , i = 1 , 2 , … , l w Label(p_i^w) = 1- d_i^w, \quad i=1,2,\ldots,l^w Label(piw)=1−diw,i=1,2,…,lw
我们用逻辑斯蒂回归进行二分类,一个结点被分为正类的概率是:
σ ( x w T θ ) = 1 1 + e − x w T θ \sigma(\mathbf x_w^T\theta) = \frac{1}{1+e^{-\mathbf x_w^T\theta}} σ(xwTθ)=1+e−xwTθ1
被分成负类的概率为:
1 − σ ( x w T θ ) 1-\sigma(\mathbf x_w^T\theta) 1−σ(xwTθ)
这里的 θ \theta θ就是非叶子节点对应的向量,是个待定参数。
所以,从霍夫曼树的根结点出发到“足球”,中间经历了4个二分类,每个分类的结果如下:
第一次: p ( d 2 w ∣ x w , θ 1 w ) = 1 − σ ( x w T θ 1 w ) p(d_2^w|\mathbf x_w,\theta_1^w) = 1- \sigma(\mathbf x_w^T\theta_1^w) p(d2w∣xw,θ1w)=1−σ(xwTθ1w)
第二次: p ( d 3 w ∣ x w , θ 2 w ) = σ ( x w T θ 2 w ) p(d_3^w|\mathbf x_w,\theta_2^w) = \sigma(\mathbf x_w^T\theta_2^w) p(d3w∣xw,θ2w)=σ(xwTθ2w)
第三次: p ( d 4 w ∣ x w , θ 3 w ) = σ ( x w T θ 3 w ) p(d_4^w|\mathbf x_w,\theta_3^w) = \sigma(\mathbf x_w^T\theta_3^w) p(d4w∣xw,θ3w)=σ(xwTθ3w)
第四次: p ( d 5 w ∣ x w , θ 4 w ) = 1 − σ ( x w T θ 4 w ) p(d_5^w|\mathbf x_w,\theta_4^w) = 1- \sigma(\mathbf x_w^T\theta_4^w) p(d5w∣xw,θ4w)=1−σ(xwTθ4w)
这四个概率的乘积就是 p ( 足 球 ∣ c o n t e x t ( 足 球 ) ) p(足球|context(足球)) p(足球∣context(足球)),即:
p ( 足 球 ∣ c o n t e x t ( 足 球 ) ) = ∏ j = 2 5 p ( d j w ∣ x w , θ j − 1 w ) p(足球|context(足球)) = \prod_{j=2}^5 p(d_j^w|\mathbf x_w,\theta_{j-1}^w) p(足球∣context(足球))=j=2∏5p(djw∣xw,θj−1w)
总结:对于词典D中的任意词w, 霍夫曼树中必存在一条从根结点到词w对应结点的路径 p w p^w pw (且这条路径是唯一的)。路径 p w p^w pw上存在 l w − 1 l^w -1 lw−1个分支,将每个分支看做一次二分类,每一次分类就产生一个概率, 将这些概率乘起来,就是所需的 p ( w ∣ C o n t e x t ( w ) ) p(w|Context(w)) p(w∣Context(w))。
所以条件概率的定义如下:
p ( w ∣ c o n t e x t ( w ) ) = ∏ j = 2 l w p ( d j w ∣ x w , θ j − 1 w ) p(w|context(w)) = \prod_{j=2}^{l^w} p(d_j^w|\mathbf x_w,\theta_{j-1}^w) p(w∣context(w))=j=2∏lwp(djw∣xw,θj−1w)
其中:
p ( d j w ∣ x w , θ j − 1 w ) = { σ ( x w T θ j − 1 w ) d j w = 0 1 − σ ( x w T θ j − 1 w ) d j w = 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(djw∣xw,θj−1w)={σ(xwTθj−1w)djw=01−σ(xwTθj−1w)djw=1
于是整体表达式如下:
p ( d j w ∣ x w , θ j − 1 w ) = [ σ ( x w T θ j − 1 w ) ] 1 − d j w ⋅ [ 1 − σ ( x w T θ j − 1 w ) ] d j w 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} p(djw∣xw,θj−1w)=[σ(xwTθj−1w)]1−djw⋅[1−σ(xwTθj−1w)]djw
所以我们的优化目标是:
L = ∑ w ∈ C l o g ∏ j = 2 l w { [ σ ( x w T θ j − 1 w ) ] 1 − d j w ⋅ [ 1 − σ ( x w T θ j − 1 w ) ] d j w } = ∑ w ∈ C ∑ j = 2 l w { ( 1 − d j w ) log [ σ ( x w T θ j − 1 w ) ] + d j w log [ 1 − σ ( x w T θ j − 1 w ) ] } = ∑ w ∈ C ∑ j = 2 l w L ( 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} L=w∈C∑logj=2∏lw{[σ(xwTθj−1w)]1−djw⋅[1−σ(xwTθj−1w)]djw}=w∈C∑j=2∑lw{(1−djw)log[σ(xwTθj−1w)]+djwlog[1−σ(xwTθj−1w)]}=w∈C∑j=2∑lwL(w,j)
其中: L ( w , j ) = ( 1 − d j w ) log [ σ ( x w T θ j − 1 w ) ] + d j w log [ 1 − σ ( x w T θ j − 1 w ) ] \mathcal L(w,j) = ({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)] L(w,j)=(1−djw)log[σ(xwTθj−1w)]+djwlog[1−σ(xwTθj−1w)]
这就是CBOW的目标函数。
采用随机梯度上升法将这个函数最大化。
注:随机梯度上升法:随机取一个样本 ( c o n t e x t ( w ) , w ) (context(w),w) (context(w),w),对目标函数中的所有的参数行一次更新。
(1)更新 θ j − 1 w \theta_{j-1}^w θj−1w
因为:
∂ L ( w , j ) ∂ θ j − 1 w = ∂ { ( 1 − d j w ) log [ σ ( x w T θ j − 1 w ) ] + d j w log [ 1 − σ ( x w T θ j − 1 w ) ] } ∂ θ j − 1 w = ( 1 − d j w ) [ 1 − σ ( x w T θ j − 1 w ) ] x w − d j w σ ( x w T θ j − 1 w ) x w = { ( 1 − d j w ) [ 1 − σ ( x w T θ j − 1 w ) ] − d j w σ ( x w T θ j − 1 w ) } x w = [ 1 − d j w − σ ( x w T θ j − 1 w ) ] x w \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} ∂θj−1w∂L(w,j)=∂θj−1w∂{(1−djw)log[σ(xwTθj−1w)]+djwlog[1−σ(xwTθj−1w)]}=(1−djw)[1−σ(xwTθj−1w)]xw−djwσ(xwTθj−1w)xw={(1−djw)[1−σ(xwTθj−1w)]−djwσ(xwTθj−1w)}xw=[1−djw−σ(xwTθj−1w)]xw
所以 θ j − 1 w \theta_{j-1}^w θj−1w更新公式为:
θ j − 1 w : = θ j − 1 w + η [ 1 − d j w − σ ( x w T θ j − 1 w ) ] x w \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 θj−1w:=θj−1w+η[1−djw−σ(xwTθj−1w)]xw
其中 η \eta η为学习率。
(2)更新 x w \mathbf x_w xw
因为 L ( w , j ) \mathcal L(w,j) L(w,j) 关于变量 x w \mathbf x_w xw和 θ j − 1 w \theta_{j-1}^w θj−1w是对称的。所以:
∂ L ( w , j ) ∂ x w = [ 1 − d j w − σ ( x w T θ j − 1 w ) ] θ j − 1 w \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} ∂xw∂L(w,j)=[1−djw−σ(xwTθj−1w)]θj−1w
这里存在一个问题:我们的最终目的是要求词典D中每个词的词向量,而这里的 x w \mathbf x_w xw 表示的是 c o n t e x t ( w ) context(w) context(w)中各词词向量的累加。那么,如何利用 ∂ L ( w , j ) ∂ x w \frac{\partial \mathcal L(w,j)}{\partial \mathbf x_w} ∂xw∂L(w,j)来对 v ( w ) , w ∈ D \mathbf v(w),w \in D v(w),w∈D 进行更新呢? word2vec中的做法很简单, 直接取
v ( w ) : = v ( w ) + η ∑ j = 2 l w ∂ L ( w , j ) ∂ x w , w ∈ c o n t e x t ( 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) v(w):=v(w)+ηj=2∑lw∂xw∂L(w,j),w∈context(w)
注:既然 x w \mathbf x_w xw 本身就是 c o n t e x t ( w ) context(w) context(w)中各个词向量的累加,求完梯度后也应该将其贡献到每个分量上。
下面是CBOW模型中采用的随机梯度上升法伪代码:
Skip-gram 模型的结构也是三层,下面以样本 ( w , c o n t e x t ( w ) ) (w,context(w)) (w,context(w))为例说明。如下图所示:
(1)输入层:只包含当前样本中心词 w w w词向量 v ( w ) ∈ R m \mathbf v(w) \in \mathbf R^m v(w)∈Rm ,每个词向量的长度是 m m m。
(2)投影层:恒等投影,即和输入层一样,保留是为了与CBOW对比。
(3)输出层:与CBOW类似。
对于Skip-gram模型,已知的是当前词 w w w,需要对其上下文 c o n t e x t ( w ) context(w) context(w)中的词进行预测,所以:
p ( c o n t e x t ( w ) ∣ w ) = ∏ u ∈ c o n t e x t ( w ) p ( u ∣ w ) p(context(w)|w) = \prod_{u \in context(w)} p(u|w) p(context(w)∣w)=u∈context(w)∏p(u∣w)
类似于CBOW,所以:
p ( u ∣ w ) = ∏ j = 2 l u p ( d j u ∣ v ( w ) , θ j − 1 u ) p(u|w) = \prod_{j=2}^{l^u}p(d_j^u|\mathbf v(w),\theta_{j-1}^u) p(u∣w)=j=2∏lup(dju∣v(w),θj−1u)
其中:
p ( d j u ∣ v ( w ) , θ j − 1 u ) = [ σ ( v ( w ) T θ j − 1 u ) ] 1 − d j u ⋅ [ 1 − σ ( v ( w ) T θ j − 1 u ) ] d j u 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} p(dju∣v(w),θj−1u)=[σ(v(w)Tθj−1u)]1−dju⋅[1−σ(v(w)Tθj−1u)]dju
所以我们的优化目标是:
L = ∑ w ∈ C log ∏ u ∈ c o n t e x t ( w ) ∏ j = 2 l u { [ σ ( v ( w ) T θ j − 1 u ) ] 1 − d j u ⋅ [ 1 − σ ( v ( w ) T θ j − 1 u ) ] d j u } = ∑ w ∈ C ∑ u ∈ c o n t e x t ( w ) ∑ j = 2 l u { ( 1 − d j u ) log [ σ ( v ( w ) T θ j − 1 u ) ] + d j u l o g [ 1 − σ ( v ( w ) T θ j − 1 u ) ] } = ∑ w ∈ C ∑ u ∈ c o n t e x t ( w ) ∑ j = 2 l u 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} L=w∈C∑logu∈context(w)∏j=2∏lu{[σ(v(w)Tθj−1u)]1−dju⋅[1−σ(v(w)Tθj−1u)]dju}=w∈C∑u∈context(w)∑j=2∑lu{(1−dju)log[σ(v(w)Tθj−1u)]+djulog[1−σ(v(w)Tθj−1u)]}=w∈C∑u∈context(w)∑j=2∑lu L(w,u,j)
采用随机梯度上升法将这个函数最大化。
(1)更新 θ j − 1 u \theta_{j-1}^u θj−1u
因为:
∂ L ( w , u , j ) ∂ θ j − 1 u = ∂ { [ σ ( v ( w ) T θ j − 1 u ) ] 1 − d j u ⋅ [ 1 − σ ( v ( w ) T θ j − 1 u ) ] d j u } ∂ θ j − 1 u = ( 1 − d j u ) [ 1 − σ ( v ( w ) T θ j − 1 u ) ] v ( w ) − d j u σ ( v ( w ) T θ j − 1 u ) v ( w ) = { ( 1 − d j u ) [ 1 − σ ( v ( w ) T θ j − 1 u ) ] − d j u σ ( v ( w ) T θ j − 1 u ) } v ( w ) = [ 1 − d j u − σ ( v ( w ) T θ j − 1 u ) ] 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} ∂θj−1u∂L(w,u,j)=∂θj−1u∂{[σ(v(w)Tθj−1u)]1−dju⋅[1−σ(v(w)Tθj−1u)]dju}=(1−dju)[1−σ(v(w)Tθj−1u)]v(w)−djuσ(v(w)Tθj−1u)v(w)={(1−dju)[1−σ(v(w)Tθj−1u)]−djuσ(v(w)Tθj−1u)}v(w)=[1−dju−σ(v(w)Tθj−1u)]v(w)
所以 θ j − 1 w \theta_{j-1}^w θj−1w更新公式为:
θ j − 1 u : = θ j − 1 u + η [ 1 − d j u − σ ( v ( w ) T θ j − 1 u ) ] 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) θj−1u:=θj−1u+η[1−dju−σ(v(w)Tθj−1u)]v(w)
其中 η \eta η为学习率。
(2)更新 v ( w ) \mathbf v(w) v(w)
因为 L ( w , u , j ) \mathcal L(w,u,j) L(w,u,j) 关于变量 v ( w ) \mathbf v(w) v(w)和 θ j − 1 w \theta_{j-1}^w θj−1w是对称的。所以:
∂ L ( w , u , j ) ∂ v ( w ) = [ 1 − d j u − σ ( v ( w ) T θ j − 1 u ) ] θ j − 1 u \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)∂L(w,u,j)=[1−dju−σ(v(w)Tθj−1u)]θj−1u
所以, v ( w ) \mathbf v(w) v(w)更新公式为:
v ( w ) : = v ( w ) + η ∑ u ∈ c o n t e x t ( w ) ∑ j = 2 l w ∂ L ( w , u , j ) ∂ v ( w ) , w ∈ c o n t e x t ( 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) v(w):=v(w)+ηu∈context(w)∑j=2∑lw∂v(w)∂L(w,u,j),w∈context(w)
具体伪代码如下:
与 CBOW 相比,最大的区别是多个了外层循环。
使用霍夫曼树来代替传统的神经网络,避免了从隐藏层到输出的softmax层这里的计算,也避免计算所有词的softmax概率。
但是如果我们的训练样本里的中心词 w w w是一个很生僻的词,那么就得在霍夫曼树中辛苦的向下走很久了。解决这个问题则是采用基于Negative Sampling的模型。
参考文章:
word2vec 中的数学原理详解
基于Hierarchical Softmax的word2vec模型