Word2Vec之Skip-Gram

一.什么是word2vec

word2vec是Google开源的一款用于(分布式)词向量计算的工具。word2vec不仅可以在百万数量级的词典和上亿的数据集上进行高效地训练,还可以得到训练结果——词向量(word embedding),可以很好地度量词与词之间的相似性。其实word2vec算法的背后是一个浅层神经网络,而且还是一个计算word vector的开源工具。当我们在说word2vec算法或模型的时候,其实指的是其背后用于计算word vector的CBoW模型Skip-gram模型。而Negative SamplingHierachical Softmax则是优化提升前面这两种模型的训练算法。

二、Skip-Gram

2.1 Skip-Gram 模型

Skip-Gram在传统的NNLM语言模型基础上进行了改进简化,使用了下面这种全连接的网络结构:
Word2Vec之Skip-Gram_第1张图片
这样训练得到的权重矩阵W和W’就是词向量,最后可以把两个词向量相加或者拼接从而得到最终的词向量。

我们把训练词向量的问题转换为端到端的文本分类问题。如下图所示,对于语料库中的一个句子,假设临近窗口为前后两个词,则可以抽取出如下图右边所示的训练样本,每个训练样本是一个(中心词,临近词)的pair
Word2Vec之Skip-Gram_第2张图片
比如对于(the, quick)训练样本,我们希望神经网络在输入the这个中心词时,能以较高的概率预测出quick这个词。

  • 表示输入是the的one-hot编码,输出是quick的one-hot编码。
  • 假设词典里有10000个不同的词,则one-hot编码长度为10000。
  • 有一个隐藏层的全连接网络,对应权重构成两个权重矩阵,和输入层连接的矩阵为W,其每一列表示词作为中心词时的词向量 v c v_c vc。输入的one-hot行向量乘以 W W W正好得到输入词的词向量。
  • 隐层和输出层连接的权重矩阵为W',其每一行表示输出层的词的临近词词向量 u o u_o uo
  • v c v_c vc乘以矩阵W’,得到中心词的临近词 u o u_o uo的概率分布,再经过softmax激活,进行归一化。

其实反过来看,从输出往隐层看,相当于输出层的行向量乘以的转置,得到隐层词向量。这其实就是另一种训练词向量的方法CBOW,即英语完形填空,用临近词来预测中心词。

详细的看一下:
Word2Vec之Skip-Gram_第3张图片
对照上面这张图,总结一下使用神经网络训练SG模型求解词向量的具体步骤如下:
(1)对于某一个训练样本(单词对),初始化中心词的one-hot向量 w t : ( V , 1 ) w_t : (V,1) wt:(V,1),然后作为神经网络的输入;
(2)将权重矩阵 W : ( d , V ) W : (d,V) W:(d,V) 乘以one-hot向量 w t : ( V , 1 ) w_t : (V,1) wt:(V,1) ,得到中心词的word2vec词向量 v c : ( d , 1 ) v_c : (d,1) vc:(d,1)
(3)然后将词向量中心词向量 v c : ( d , 1 ) v_c : (d,1) vc:(d,1)乘以权重矩阵 W ′ : ( V , d ) W' : (V,d) W:(V,d) ,得到邻近词的一个概率分布 w v c ′ : ( V , 1 ) w'_{v_c} : (V,1) wvc:(V,1)
(4)再经过softmax操作得到一个(V,1)维度的概率分布,概率值最大的那个单词就是该位置预测的单词 w t − j w_{t-j} wtj,也就是通过中心词预测的某一个邻近词,然后再进行梯度下降算法优化权重值。
(5)再将这个中心词的其他邻近词进行1-4步的操作,从而得到这个中心词的所有邻近词的预测。

可以按照上面这几个步骤对语料中的所有句子进行训练。最终得到了所有单词的词向量。

当然这种全连接网络虽然能很方便的计算词向量,但还是存在一个问题:当词向量个数巨大时,网络过于庞大,参数量太多。对于这个问题,可以采用 subsampling 技巧,每个词都有一个保留概率p,以p的概率保留在训练数据中,以1-p的概率删除这个词。对于某个词 w i w_i wi,其保留概率p如下,其中 z ( w i ) z(w_i) z(wi)是词频:
p ( w i ) = ( z ( w i ) 0.001 + 1 ) 0.001 z ( w i ) p(w_i)=(\sqrt{\frac{z(w_i)}{0.001}}+1)\frac{0.001}{z(w_i)} p(wi)=(0.001z(wi) +1)z(wi)0.001
也就是说词频越大,被删得概率越大。

2.2 目标函数

Skip-Gram的中心思想就是对于每个选定的中心词,尽量准确预测其周围可能出现的词的概率分布。

具体来说,SG算法首先随机初始化每个词的词向量(或者one-hot),然后预测不同邻近词出现的概率,最后最大化实际邻近词出现的概率。形式化来说,就是利用极大似然估计的方法,求解每个词的词向量,其目标函数如下:
L i k e l i h o o d = L ( θ ) = Π t = 1 T Π − m ≤ j ≤ m   p ( w t + j ∣ w t , θ ) Likelihood=L(\theta)=\mathop{\Pi}\limits_{t=1}^{T}\mathop{\Pi}\limits_{-m\leq j \leq m} \ p(w_{t+j}|w_t,\theta) Likelihood=L(θ)=t=1ΠTmjmΠ p(wt+jwt,θ)

其中, θ \theta θ是待求解的参数,这两个矩阵其实都是词向量组成的矩阵,我们最后求出来之后可以直接相加也可以拼接成一个更大的词向量。t是选定的中心词的位置, w t w_t wt就表示选定的中心词, w t + j w_{t+j} wt+j就表示距离 t 位置 j 距离的词。最终目标是要最小化这个 L 函数。

求解极大似然估计一般就是转化为取负数对数似然,然后利用梯度下降求解最小化之后的 L。上式转化之后等价于:
J ( θ ) = − 1 T l o g L ( θ ) = − 1 T ∑ t = 1 T ∑ − m ≤ j ≤ m   l o g p ( w t + j ∣ w t , θ ) J(\theta)=-\frac{1}{T}logL(\theta)=-\frac{1}{T} \mathop{\sum}\limits_{t=1}^{T}\mathop{\sum}\limits_{-m\leq j \leq m} \ logp(w_{t+j}|w_t,\theta) J(θ)=T1logL(θ)=T1t=1Tmjm logp(wt+jwt,θ)

2.3 梯度下降算法

那我们再看看预测到的某个上下文条件概率 p ( w t + j ∣ w t ) p(w_{t+j}|w_t) p(wt+jwt)是如何得到的,可以通过naive-softmax
p ( o ∣ c ) = e x p ( u o T v c ) ∑ w ∈ V e x p ( u w T v c ) (2.3.1) p(o|c)=\frac{exp(u_o^Tv_c)}{\sum\limits_{w \in V}exp(u^T_wv_c)} \tag{2.3.1} p(oc)=wVexp(uwTvc)exp(uoTvc)(2.3.1)
这里o是输出的上下文词语中的确切某一个,c是中间词。u是c对应的(某一个)上下文词语o的词向量v是(某一个)中心词c的词向量。指数函数可以把实数映射成正数。分子上点积也有点像衡量两个向量相似度的方法,两个向量越相似,其点积越大,而分母则是起到归一化得到概率的作用。

【重点】:有了 u 和 v 这两个词向量的定义之后,我们可以把原来目标函数中的 θ \theta θ 表示为下面这种形式
Word2Vec之Skip-Gram_第4张图片
由于上述两个矩阵的原因,所以θ的维度中有个2。

然后再结合等式(2.3.1)基于naive-softmax的Skig-Gram算法目标函数就变成了:
J ( u , v ) n a i v e − s o f t m a x = − 1 T ∑ t = 1 T ∑ − m ≤ j ≤ m   l o g p ( o ∣ c ) = − 1 T ∑ t = 1 T ∑ − m ≤ j ≤ m   l o g e x p ( u o T v c ) ∑ w ∈ V e x p ( u w T v c ) (2.3.2) \begin{array}{ll} J(u,v)_{naive-softmax} & =-\frac{1}{T} \mathop{\sum}\limits_{t=1}^{T}\mathop{\sum}\limits_{-m\leq j \leq m} \ log p(o|c)\\ &=-\frac{1}{T} \mathop{\sum}\limits_{t=1}^{T}\mathop{\sum}\limits_{-m\leq j \leq m} \ log \frac{exp(u_o^Tv_c)}{\sum\limits_{w \in V}exp(u^T_wv_c)} \tag{2.3.2}\\ \end{array} J(u,v)naivesoftmax=T1t=1Tmjm logp(oc)=T1t=1Tmjm logwVexp(uwTvc)exp(uoTvc)(2.3.2)

这样我们可以先对里面的 naive-softmax:log p(o|c) 分别求u和v的偏导:
(1)对 v c v_c vc求偏导:
∂ ∂ v c l o g p ( o ∣ c ) = ∂ ∂ v c l o g e x p ( u o T v c ) ∑ w ∈ V e x p ( u w T v c ) = ∂ ∂ v c ( l o g exp ⁡ ( u o T v c ) − l o g ∑ w ∈ V exp ⁡ ( u w T v c ) ) = u o − ∑ w ∈ V p ( u w ∣ v c ) u w = o b s e r v e d − e x p e c t e d \begin{array}{ll} \frac{\partial}{\partial v_c} logp(o|c) &=\frac{\partial}{\partial v_c} log \frac{exp(u_o^Tv_c)}{\sum\limits_{w \in V}exp(u^T_wv_c)}\\ &=\frac{\partial}{\partial v_c} \left(log\exp(u_o^Tv_c)-log\sum\limits_{w \in V}\exp(u^T_wv_c)\right)\\ &=u_o-\sum\limits_{w \in V}p(u_w|v_c)u_w\\ &=observed-expected\\ \end{array} vclogp(oc)=vclogwVexp(uwTvc)exp(uoTvc)=vc(logexp(uoTvc)logwVexp(uwTvc))=uowVp(uwvc)uw=observedexpected

最后算出来的梯度很有意思, u o u_o uo表示观察到的上下文词向量(o表示observed),减号后面的是这个位置的期望的词向量,期望=概率*值。差值就是真实观察词向量减去期望词向量,这就是梯度。当它们的差值很小时,说明给定能很好的预测其临近词的概率分布。

(2)对 u o u_o uo求偏导:
∂ ∂ u o l o g p ( o ∣ c ) = ( 1 − p ( o ∣ c ) ) v c \frac{\partial}{\partial u_o} logp(o|c)=(1-p(o|c))v_c uologp(oc)=(1p(oc))vc

u o u_o uo求偏导的结果可以理解为:当 p ( o ∣ c ) → 1 p(o|c) \rightarrow 1 p(oc)1时,即通过中心词c我们可以正确预测上下文词o,此时不需要调整上下文词,反之则应调整上下文词。

这样最终求得 u o , v c u_o,v_c uo,vc之后,将其组成的 θ \theta θ就是我们要求的词向量矩阵。

上面这种方法,由于使用naive-softmax放在最后一层要对所有的词语做判断,得到一个最大概率作为最终预测结果,然后使用梯度更新的方法更新所有模型参数。当训练样本太多时,每个样本都参与softmax运算并且更新所有参数,训练速度比较慢。下面来详细说一下negative sampling。

三、Negative Sampling

negative sampling技巧的核心就是只更新一小部分参数(词向量矩阵)。按照原始的方法,每次进行训练的时候权重矩阵是全量更新,实际上每次只训练了一个样本并不需要更新其他影响较小的参数。negative sampling技巧是,只更新和quick连接的权重以及随机选出的 neg 个输出神经元的连接权重进行更新。这样一下就大大减少了需要更新的权重个数。比如假设我们有10000个单词,词嵌入的长度为300,每次要更新10000x300的模型参数。如果我们采用negative sampling负采样5个负样本,加上原来的1个正样本,最终只要对这10000x6个参数做更新,减少了很多计算量。

对于一个样本,在之前的样本中,我们都是将正确的结果作为训练结果拿去训练的。对于负采样,在语言模型中,假设中心词为 w 0 w_0 w0, 他周围的上下文共有 2m个单词,记为 c o n t e x t ( w 0 ) context(w_0) context(w0),那么 w 0 w_0 w0 c o n t e x t ( w 0 ) context(w_0) context(w0) 的对应就是一个正例。而负例(可以理解为错误的例子)就是我们取 neg 个与 w 0 w_0 w0不同的单词 w i , i = 1 , 2 , … n w_i,i=1,2,…n wi,i=1,2,n 作为中心词, 这些 w i w_i wi c o n t e x t ( w 0 ) context(w_0) context(w0) 就构成了负样本。然后利用分类的思想,这就相当于一个二元分类问题,通过最优化这个分类问题求解模型的参数(词向量矩阵)。

3.1 Negative Sampling 的损失函数

把语料中的一个词串的中心词替换为别的词,构造语料 D 中不存在的词串作为负样本,本质上就是一个预测全部分类的变成预测总体类别的子集的方法。在这种策略下,优化目标变为了:最大化正样本的概率,同时最小化负样本的概率。对于一个词串 (w,c) ( c 表示 w 的上下文),用二项Logistic回归模型对其是正样本的概率建模:
p ( D = 1 ∣ w , c ) = σ ( u w T v c ) p(D=1|w,c)=\sigma(u^T_wv_c) p(D=1w,c)=σ(uwTvc)
所以全部正例样本的似然函数为:
L p o s i t i v e = ∏ w , c ∈ D p ( D = 1 ∣ w , c ) L_{positive}=\prod\limits_{w,c \in D} p(D=1|w,c) Lpositive=w,cDp(D=1w,c)
同理,全部负例样本的似然函数为:
L n e g t i v e = ∏ w , c ∉ D p ( D = 1 ∣ w , c ) L_{negtive}=\prod\limits_{w,c \notin D} p(D=1|w,c) Lnegtive=w,c/Dp(D=1w,c)

需要最大化前者同时最小化后者,也就是最大化下式:
L = ∏ w , c ∈ D p ( D = 1 ∣ w , c ) ∏ w , c ∉ D ( 1 − p ( D = 1 ∣ w , c ) ) L=\prod\limits_{w,c \in D} p(D=1|w,c)\prod\limits_{w,c \notin D} (1-p(D=1|w,c)) L=w,cDp(D=1w,c)w,c/D(1p(D=1w,c))

取负数对数似然可以得到Negative Sampling 的损失函数(目标是最小化这个函数):
L = − l o g ( ∏ w , c ∈ D p ( D = 1 ∣ w , c ) ∏ w , c ∉ D ( 1 − p ( D = 1 ∣ w , c ) ) ) = − l o g ( ∏ w , c ∈ D σ ( u w T v c ) ∏ w , c ∉ D ( σ ( − u w T v c ) ) ) ) = − ∑ w , c ∈ D l o g ( σ ( u w T v c ) ) − ∑ w , c ∉ D l o g ( σ ( − u w T v c ) ) \begin{array}{ll} L &=-log(\prod\limits_{w,c \in D} p(D=1|w,c)\prod\limits_{w,c \notin D} (1-p(D=1|w,c)))\\ & =-log(\prod\limits_{w,c \in D} \sigma(u^T_wv_c) \prod\limits_{w,c \notin D} (\sigma(-u^T_wv_c))))\\ &=-\sum\limits_{w,c \in D} log(\sigma(u^T_wv_c)) - \sum\limits_{w,c \notin D} log(\sigma(-u^T_wv_c))\\ \end{array} L=log(w,cDp(D=1w,c)w,c/D(1p(D=1w,c)))=log(w,cDσ(uwTvc)w,c/D(σ(uwTvc))))=w,cDlog(σ(uwTvc))w,c/Dlog(σ(uwTvc))

3.2 基于Negative Sampling的Skip-Gram算法损失函数

在skip-gram算法中,对于每一个中心词 C 来说只有一个正例,所以只需要知道对一个正样本 (w,c) 的目标函数。下式中 NEG(w) 指 (w,c) 的负样本的中心词集合:
L = − l o g ( σ ( u w T v c ) ) − ∑ w , c ∈ N E G ( w ) l o g ( σ ( − u w T v c ) ) L=-log(\sigma(u^T_wv_c)) -\sum\limits_{w,c \in NEG(w)} log(\sigma(-u^T_wv_c)) L=log(σ(uwTvc))w,cNEG(w)log(σ(uwTvc))

于是得到了基于Negative Sampling的损失函数(针对某一个中心词)如下:
J n e g − s a m p l i n g   ( v c , u o , U ) = − l o g ( σ ( u o T v c ) ) − ∑ k = 1 K l o g ( σ ( − u k T v c ) ) (3.2.1) J_{neg-sampling} \ (v_c,u_o,U)=-log(\sigma(u_o^Tv_c))-\sum_{k=1}^Klog(\sigma(-u_k^Tv_c)) \tag{3.2.1} Jnegsampling (vc,uo,U)=log(σ(uoTvc))k=1Klog(σ(ukTvc))(3.2.1)
注:公式(2.3.2)是naive-softmax版的Skig-Gram损失函数。

对中心词向量 v c v_c vc求偏导得到梯度为:
∂ J ∂ v c = − ( 1 − σ ( u o T v c ) ) u o + ∑ k = 1 K ( 1 − σ ( − u k T v c ) ) u k (3.2.2) \frac{\partial J}{\partial v_c}=-(1-\sigma(u_o^T v_c))u_o+\sum_{k=1}^K(1-\sigma(-u_k^T v_c))u_k \tag{3.2.2} vcJ=(1σ(uoTvc))uo+k=1K(1σ(ukTvc))uk(3.2.2)

对临近词向量 u o u_o uo求偏导得到梯度为:
∂ J ∂ u o = − ( 1 − σ ( u o T v c ) ) v c (3.2.3) \frac{\partial J}{\partial u_o}=-(1-\sigma(u_o^T v_c))v_c \tag{3.2.3} uoJ=(1σ(uoTvc))vc(3.2.3)

3.3 基于Negative Sampling的Skip-Gram算法流程

按照Negative Sampling的思想,可以总结出基于Negative Sampling的Skip-Gram算法的流程如下:
输入:基于Skip-Gram的训练样本(只有正例,负例在过程中采集),上下文大小2c,步长 η \eta η,负采样个数neg
输出:词汇表中所有词的词向量
(1)随机初始化所有的模型参数 θ \theta θ 和初始词向量 w w w
(2)对于每个训练样本 ( c o n t e x t ( w 0 ) , w 0 ) (context(w_0),w_0) (context(w0),w0),负采样出 neg 个负例中心词 w i , i = 1 , 2 , . . , n e g w_i,i=1,2,..,neg wi,i=1,2,..,neg
(3)进行梯度上升迭代过程:对于训练集中的每一个样本 ( c o n t e x t ( w 0 ) , w 1 ) , ( c o n t e x t ( w 0 ) , w 1 ) , . . . , ( c o n t e x t ( w 0 ) , w n e g ) (context(w_0),w_1),(context(w_0),w_1),...,(context(w_0),w_{neg}) (context(w0),w1),(context(w0),w1),...,(context(w0),wneg),做如下处理,:
  (a) for i=1 to 2c: // i 是上下文单词的位置
    (i) e=0;
    (ii) for j=0 to neg, 计算:// j 是中心词单词的位置(0是正例,其他为负例)
       f = σ ( θ w i T w j ) f=\sigma(\theta^T_{wi} w_j) f=σ(θwiTwj); // θ w i T \theta^T_{wi} θwiT就是每个(上下文)词在权重矩阵中的词向量
       g = ( 1 − f ) η g=(1-f) \eta g=(1f)η;
       e = e + g θ w j e=e+g \theta^{w_j} e=e+gθwj; // θ w j \theta^{w_j} θwj是每个中心词在权重矩阵中的词向量
       θ w j = θ w j + g w i \theta^{w_j}=\theta^{w_j}+gw_{i} θwj=θwj+gwi; // 更新上下文单词的词向量!!!
    (iii) 对于 context(w_0) 中的每一个词向量 w i w_i wi(共2c个)进行更新 θ w i = θ w i + e \theta^{w_i}=\theta{w_i}+e θwi=θwi+e; // 更新上下文单词的词向量!!!
  (b) 如果梯度收敛,则结束,否则返回
      
这样最终学习到所有的模型参数。

四、Hierarchical Softmax

4.1 Hierarchical Softmax 简介

对于原始的模型来说,由于使用的是softmax()函数,时间复杂度为 O(|V|)(|V|表示词典的总词数) ,因此计算代价很大,对大规模的训练语料来说,非常不现实。因此Mikolov 提出的另一个技巧是Hierarchical Softmax。Hierarchical Softmax 是从隐藏层到输出的softmax层这里的计算量的改进。为了避免要计算所有词的softmax概率,word2vec采样了霍夫曼树来代替从隐藏层到输出softmax层的映射(去掉了原来的W'矩阵)。由于Hierarchical Softmax是二叉树,我们结算复杂度为 O(log|V|)。

简单来说,Hierarchical Softmax是一种对输出层进行优化的策略,输出层从原始模型的利用softmax计算概率值改为了利用Huffman树计算概率值

Huffman树是二叉树,在叶子节点及叶子节点的权给定的情况下,该树的带权路径长度最短(一个节点的带权路径长度指根节点到该节点的路径长度乘以该节点的权,树的带权路径长度指全部叶子节点的带权路径长度之和)。直观上可以看出,叶子节点的权越大,则该叶子节点就应该离根节点越近。因此对于模型来说就是,词频越高的词,距离根节点就越近

Word2Vec之Skip-Gram_第5张图片
其中图中白色的叶子节点表示词汇表中所有的|V|个词, 黑色节点表示非叶子节点, 每一个叶子节点也就是每一个单词, 都对应唯一的一条从root节点出发的路径. 而我们的目的是使的 w = w O w=w_O w=wO 这条路径的概率最大,即: P ( w = w O ∣ w I ) P(w=w_O|w_{I}) P(w=wOwI) 最大,【O表示Output,I表示input输入单词】, 此时每一个分支都代表一个选择, 向左转还是向右转. 所以如何判断向左还是向右呢? 我们用n(w,j)表示从root到叶子节点w的路径上的第j个非叶子节点, 并且每个非叶子节点都对应一个向量 v n ( w , j ) ′ v_{n(w,j)}' vn(w,j), 维度与(隐层词向量矩阵)h相同, 然后使用一个sigmod函数: σ ( x ) = 1 1 + e x p ( − x ) ∈ [ 0 , 1 ] \sigma(x)=\frac{1}{1+exp(-x)} \in [0,1] σ(x)=1+exp(x)1[0,1], 结合向量的内积, 来判断该向左还是向右, 如下, 第n个节点向左以及向右的概率定义:
P ( n , l e f t ) = σ ( v w ′ ⋅ h ) P ( n , r i g h t ) = 1 − σ ( v w ′ ⋅ h ) = σ ( − v w ′ ⋅ h ) \begin{array}{ll} P(n, left ) = \sigma({v^{'}_{w}} \cdot \mathbf{h}) \\ P(n, right) =1-\sigma(v^{'}_w \cdot \mathbf{h}) = \sigma(-v_{w}^{'} \cdot h) \\\end{array} P(n,left)=σ(vwh)P(n,right)=1σ(vwh)=σ(vwh)

有了上述的概率, 我们可以重新定义 P ( w o ∣ w i ) P(w_o|w_i) P(wowi) 了:
P ( w = w O ∣ w I ) = ∏ j = 1 L ( w ) − 1 P ( σ ( I ( n ( w , j + 1 = = l e f t ) v w ′ ⋅ h ) ) P(w=w_O|w_I)=\prod_{j=1}^{L(w)-1}P(\sigma(I(n(w,j+1==left) v^{'}_{w} \cdot \mathbf{h} )) P(w=wOwI)=j=1L(w)1P(σ(I(n(w,j+1==left)vwh))

其中I()是指示函数, 条件成立值为1, 反之为-1。而L(w)表示整条路径的长度, 这样整个概率就是从root节点到叶子节点这条路径的概率, 这样我们在训练的时候, 通过训练样本来更新非叶子节点的参数 v w ′ v_w' vw

举个例子, 比如上图中的加粗的黑色路径: n(w2,1),n(w2,2),n(w2,3),w2 , 就是说假设有一个训练样本是 ( w I , w 2 ) (w_I,w_2) (wI,w2), 我们需要使得 P ( w O = w 2 ∣ w I ) P(w_O=w_2|w_I) P(wO=w2wI) 概率最大:

P ( w 2 = w O ) = P ( n ( w 2 , 1 ) , l e f t ) ⋅ P ( n ( w 2 , 2 ) , l e f t ) ⋅ P ( n ( w 2 , 3 ) , r i g h t ) = σ ( v n ( w 2 , 1 ) ′ T h ) ⋅ σ ( v n ( w 2 , 2 ) ′ T h ) ⋅ σ ( − v n ( w 2 , 3 ) ′ T h ) \begin{aligned}P(w_2=w_O) &= P(n(w_2,1), left) \cdot P(n(w_2,2), left) \cdot P(n(w_2, 3), right) \\ &= \sigma({v^{'}_{n(w_2,1)}}^T \mathbf{h}) \cdot \sigma({v^{'}_{n(w_2,2)}}^T \mathbf{h}) \cdot \sigma(-{v^{'}_{n(w_2,3)}}^T \mathbf{h}) \end{aligned} P(w2=wO)=P(n(w2,1),left)P(n(w2,2),left)P(n(w2,3),right)=σ(vn(w2,1)Th)σ(vn(w2,2)Th)σ(vn(w2,3)Th)

并且在一个非叶子节点处, 向左向右的概率和为1, 因此一直分裂下去,最后的和肯定还是1. 因此可以很容易得到:
∑ j = 1 V P ( w j = w O ) = 1 \sum\limits_{j=1}^{V}P(w_j=w_O) =1 j=1VP(wj=wO)=1

这一点的证明是有必要的, 因为在原始的softmax本身保证了所有单词的概率和是1, 而通过上式也知道了通过HS得到的输出层仍然是一个概率多项分布, 输出所有的单词概率和为1.

4.2 Hierarchical Softmax 训练过程

首先需要明确的是训练的参数: 输入层与隐层的词向量矩阵W, 以及二叉树的非叶子节点对应的向量 v n ( w , j ) ′ , j = 1 , 2 , 3 , . . , L ( w ) − 1 {v_{n(w,j)}',j=1,2,3,..,L(w)−1} vn(w,j),j=1,2,3,..,L(w)1
对于一组训练数据, 损失函数的定义与前面相同, 最大似然(注意这里以One-Word Model为例,CBOW与Skip-Gram按照上述的思路完全一样):
E = − log ⁡ P ( w = w O ∣ w I ) = − ∑ j = 1 L ( w ) − 1 log ⁡ σ ( [ I ] v j ′ T h ) E = -\log P(w=w_O|w_I) = - \sum\limits_{j=1}^{L(w)-1}\log \sigma([I] {v^{'}_{j}}^{T} \mathbf{h}) E=logP(w=wOwI)=j=1L(w)1logσ([I]vjTh)
其中,用[I]表示前面的指示函数 I ( n ( w , j + 1 ) = = l e f t ) I(n(w,j+1)==left) I(n(w,j+1)==left), 使用 v j ′ v_j' vj 表示 v n ( w , j ) ′ v_{n(w,j)}' vn(w,j)。然后分别求对 v j ′ v_j' vj h h h的偏导:

∂ E ∂ v j ′ = ∂ E ∂ v j ′ T h ∂ v j ′ T h ∂ v j ′ T = ( σ ( v j ′ T h ) − t j ) h \frac{\partial E}{\partial v^{'}_j} = \frac{\partial E}{\partial {v^{'}_{j}}^T \mathbf{h}} \frac{\partial {v^{'}_{j}}^T \mathbf{h}}{\partial {v^{'}_{j}}^T} = (\sigma( {v^{'}_{j}}^T \mathbf{h}) - t_j) \mathbf{h} vjE=vjThEvjTvjTh=(σ(vjTh)tj)h
再通过梯度下降公式更新梯度:
v j ′ ( n e w ) = v j ′ ( o l d ) − η ( σ ( v j ′ T h ) − t j ) h ,   j = 1 , 2 , 3 , . . . , L ( w ) − 1 {v^{'}_{j}}^{(new)} = {v^{'}_{j}}^{(old)} - \eta (\sigma( {v^{'}_{j}}^T \mathbf{h}) - t_j) \mathbf{h},\ j=1,2,3,...,L(w)-1 vj(new)=vj(old)η(σ(vjTh)tj)h, j=1,2,3,...,L(w)1

同理,有:
∂ E ∂ h = ∑ j = 1 L ( w ) − 1 ∂ E ∂ v j ′ T h ∂ v j ′ T h ∂ h = ∑ j = 1 L ( w ) − 1 ( σ ( v j ′ T h ) − t j ) ⋅ v j ′ \begin{aligned} \frac{\partial E}{\partial \mathbf{h}} &= \sum\limits_{j=1}^{L(w)-1} \frac{\partial E}{\partial {v^{'}_{j}}^T \mathbf{h}} \frac{\partial {v^{'}_{j}}^T \mathbf{h}}{\partial \mathbf{h}} \\ &=\sum\limits_{j=1}^{L(w)-1}(\sigma( {v^{'}_{j}}^T \mathbf{h}) - t_j)\cdot v^{'}_{j}\end{aligned} hE=j=1L(w)1vjThEhvjTh=j=1L(w)1(σ(vjTh)tj)vj

简单来说,应用Hierarchical Softmax就是把 Naive-Softmax的N 分类问题变成 log(N)次二分类问题。


参考:
【1】CS224n笔记2 词的向量表示:word2vec
【2】CS224n学习笔记(一)
【3】CS224n-2019 学习笔记:Lecture 01 Introduction and Word Vectors
【4】CS224N(1.8)Introduction and Word Vectors
【5】基于Negative Sampling的Skip-Gram模型
【6】全面理解word2vec
【7】word2vec Parameter Learning Explained
【8】Word2vec数学原理全家桶

你可能感兴趣的:(NLP)