word2vec背后的数学原理+从零开始纯Python实现(下)

引言

在上篇文章中我们了解到了word2vec中CBOW和Skip-Gram的原理,有一个主要的问题是计算量太大了。想象一下百万级别的词汇量,那个softmax需要计算百万次。

本文就来介绍两种优化方法,分别是层次Softmax(Hierarchical softmax)和负采样(Negative Sampling)。

Hierarchical softmax

在介绍这种方法之前,我们来回顾一下数据结构中的哈弗曼树。

给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

word2vec背后的数学原理+从零开始纯Python实现(下)_第1张图片

下面来看一下哈夫曼树的构造,假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w 1 w_1 w1 w 2 w_2 w2、…、 w n w_n wn,则哈夫曼树的构造规则为:

  1. w 1 , w 2 , ⋯   , w n w_1,w_2,\cdots,w_n w1,w2,,wn看成是有n颗树的森林(每颗树仅有一个结点)
  2. 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;
  3. 从森林中删除选取的两棵树,并将新树加入森林
  4. 重复(2)、(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。

哈弗曼树有什么好处呢,一般可用于哈夫曼编码。比如约定左子树编码为0,右子树编码为1。由于权重高的叶子节点越靠近根节点,权重低的叶子节点则远离根节点,这样权重高的节点编码值较短,权重低的节点编码值较长,这可以保证树的带权路径最短。

用到word2vec中就是出现频次高的单词计算其分布概率可以更快。

Hierarchical softmax使用二叉树(哈夫曼树)来表示词典中的单词。这颗树的叶子节点表示词典中的每个单词,所以总共有 V V V个叶子节点。并且有 V − 1 V-1 V1个内部节点。对于每个叶子节点,都能通过一条唯一的从根节点开始的路径到达,这条路径就用来计算叶子节点所表示单词的概率。并且这个概率是已经标准化了的,也就是这颗哈夫曼树的所有叶子节点概率之和为1。

word2vec背后的数学原理+从零开始纯Python实现(下)_第2张图片

如上图所示,白色节点代表单词,黑色节点是非叶子节点。比如要计算单词 w 2 w_2 w2的概率,上图给出了唯一的一条路径,该条路径的长度 L ( w 2 ) = 4 L(w_2)=4 L(w2)=4 n ( w , j ) n(w,j) n(w,j)表示从根节点到单词 w w w所在节点的第 j j j个节点。

在Hierarchical softmax模型中,每个(共有 V − 1 V-1 V1个)内部节点有一个输出向量 v n ′ ( w , j ) v^\prime_n(w,j) vn(w,j)。然后单词作为输出单词的概率被定义为:

p ( w = w O ) = ∏ j = 1 L ( W ) − 1 σ ( I ( n ( w , j + 1 ) = c h ( n ( w , j ) ) ⋅ v n ( w , j ) ′ T h ) (1) p(w=w_O) = \prod_{j=1}^{L(W)-1} \sigma \left(I(n(w,j+1) = ch(n(w,j)) \cdot {v^\prime_{n(w,j)}}^T h \right) \tag{1} p(w=wO)=j=1L(W)1σ(I(n(w,j+1)=ch(n(w,j))vn(w,j)Th)(1)

其中 c h ( n ) ch(n) ch(n)是节点 n n n 左 孩 子 \color{red}{左孩子} v n ( w , j ) ′ v^\prime_{n(w,j)} vn(w,j)是内部节点 n ( w , j ) n(w,j) n(w,j)的输出向量; h h h是隐藏层的输出值; I ( x ) I(x) I(x)是指数函数,当 x x xTrue的时候,输出为1,输入为False的时候,输出为0。

看起来很复杂,其实很简单。我们看上图,假设我们想要计算单词 w 2 w_2 w2作为输出词的概率,我们把这个概率定义为从根节点到叶子节点 w 2 w_2 w2的概率。在每个内部节点上(包括根节点),我们需要设定向左或向右走的概率。定义在内部节点 n n n处向左走的概率为:

p ( n , l e f t ) = σ ( v n ′ T ⋅ h ) (2) p(n,left) = \sigma \left({v^\prime_n}^T \cdot h \right) \tag{2} p(n,left)=σ(vnTh)(2)

我们知道,sigmoid函数的取值是 [ 0 , 1 ] [0,1] [0,1],因此作为概率是再合适不过了。而它的函数值是由内部节点( v n ′ v^\prime_n vn)和隐藏层的输出值决定的。那么向右走的概率就为:

p ( n , r i g h t ) = 1 − σ ( v n ′ T ⋅ h ) = σ ( − v n ′ T ⋅ h ) (3) p(n,right) =1 - \sigma \left({v^\prime_n}^T \cdot h \right) = \sigma(-v{^\prime_n}^T \cdot h)\tag{3} p(n,right)=1σ(vnTh)=σ(vnTh)(3)

1 − σ ( x ) = 1 − 1 1 + e − x = e − x 1 + e − x = 1 1 + e x = σ ( − x ) 1 - \sigma(x) = 1 - \frac{1}{1+e^{-x}} = \frac{e^{-x}}{1 + e^{-x}} = \frac{1}{1+e^x} = \sigma(-x) 1σ(x)=11+ex1=1+exex=1+ex1=σ(x)

那么如何验证从根节点到 w 2 w_2 w2的路径计算 w 2 w_2 w2作为输出词的概率呢?请看下面的公式:

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 ) 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^\prime_n(w_2,1)}^T h) \cdot \sigma({v^\prime_n(w_2,2)}^T h) \cdot \sigma(- {v^\prime_n(w_2,3)}^T h) 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) (1)得到的。

在内部节点处, 向左向右的概率和为1, 一直分裂下去,最后的和还是1. 因此可以很容易得到:

∑ i = 1 V p ( w i = w O ) = 1 \sum_{i=1}^V p(w_i=w_O) = 1 i=1Vp(wi=wO)=1

这样使得Hierarchical softmax输出层也是一个所有单词的概率多项分布。

下面开始反向传播的训练过程。为了简单起见,我们先看一个上下文单词模型(one-word context model),后面扩展到CBOW和Skip-Gram是很容易的。

为了简化符号,用 [ I ] [I] [I]表示下面的指示函数式子:
[ I ] : = I ( n ( w , j + 1 ) = c h ( n ( w , j ) ) [I] := I \left(n(w,j+1) = ch(n(w,j)\right) [I]:=I(n(w,j+1)=ch(n(w,j))

v ′ v^\prime v表示 v n w , j ′ v^\prime_{n_{w,j}} vnw,j

那么,对于每个训练数据,损失函数定义为:

E = − log ⁡ p ( w = w O ∣ w I ) = − ∑ j = 1 L ( w ) − 1 log ⁡ σ ( [ I ] v j ′ T h ) (4) E = - \log p(w = w_O|w_I) = - \sum_{j=1}^{L(w) - 1} \log \sigma([I] {v^\prime_j}^T h) \tag{4} E=logp(w=wOwI)=j=1L(w)1logσ([I]vjTh)(4)

下面先求 E E E v j ′ h v^\prime_j h vjh的梯度

之前的文章推导过, σ ( x ) ′ = σ ( x ) ( 1 − σ ( x ) ) \sigma(x)^\prime = \sigma(x)(1 - \sigma(x)) σ(x)=σ(x)(1σ(x))

∂ E ∂ v j ′ h = − σ ( [ I ] v j ′ T h ) ( 1 − σ ( [ I ] v j ′ T h ) ) σ ( [ I ] v j ′ T h ) ( − [ I ] ) = ( σ ( [ I ] v j ′ T h ) − 1 ) [ I ] = { σ ( v j ′ T h ) − 1 if  [ I ] = 1 σ ( v j ′ T h ) if  [ I ] = − 1 = σ ( v j ′ T h ) − t j \begin{aligned} \frac{\partial E}{\partial v^\prime_j h} &= - \frac{\sigma([I] {v^\prime_j}^T h)(1 - \sigma([I] {v^\prime_j}^T h))}{\sigma([I] {v^\prime_j}^T h)}(- [I]) \\&= \left(\sigma([I] {v^\prime_j}^T h) - 1 \right) [I] \\ &= \begin{cases} \sigma({v^\prime_j}^T h) -1 & \text{if } [I] = 1 \\ \sigma({v^\prime_j}^T h) & \text{if } [I] = -1 \end{cases} \\ &= \sigma({v^\prime_j}^T h) - t_j \end{aligned} vjhE=σ([I]vjTh)σ([I]vjTh)(1σ([I]vjTh))([I])=(σ([I]vjTh)1)[I]={ σ(vjTh)1σ(vjTh)if [I]=1if [I]=1=σ(vjTh)tj

上面用到了公式 ( 3 ) (3) (3),其中当 [ I ] = 1 [I] = 1 [I]=1时, t j = 1 t_j=1 tj=1;否则 t j = 0 t_j=0 tj=0

这个公式与前面的 y j − t j y_j−t_j yjtj很像, 可以理解为预测值与真实值之差。

下面就可以求出内部节点 n ( w , j ) n(w,j) n(w,j)的向量 v j ′ v^′_j vj的梯度了。

∂ E ∂ v j ′ = ∂ E ∂ v j ′ h ⋅ ∂ v j ′ h ∂ v j ′ = ( σ ( v j ′ T h ) − t j ) ⋅ h \frac{\partial E}{\partial v^′_j} = \frac{\partial E}{\partial v^′_j h} \cdot \frac{\partial v^′_j h}{\partial v^′_j} = \left(\sigma({v^\prime_j}^T h) - t_j \right)\cdot h vjE=vjhEvjvjh=(σ(vjTh)tj)h

现在就可以得到 v j ′ v^′_j vj的更新公式:

v j ′ = v j ′ − η ( σ ( v j ′ T h ) − t j ) ⋅ h     j = 1 , 2 , ⋯   , L ( w ) − 1 (5) v^′_j = v^′_j - \eta \left(\sigma({v^\prime_j}^T h) - t_j \right)\cdot h \,\,\, j = 1,2,\cdots,L(w) -1 \tag{5} vj=vjη(σ(vjTh)tj)hj=1,2,,L(w)1(5)

这个公式既能用在CBOW模型中,又能用在Skip-Gram模型中。当用后者的时候,我们需要在C个上下文单词中重复这个过程。

为了对输入层到隐藏层的权重进行更新,我们对 h h h求梯度:

∂ E ∂ h = ∑ j = 1 L ( w ) − 1 ∂ E ∂ v j ′ h ⋅ ∂ v j ′ h ∂ h = ∑ j = 1 L ( w ) − 1 ( σ ( v j ′ T h ) − t j ) ⋅ v j ′ : = E H (6) \frac{\partial E}{\partial h} = \sum_{j=1}^{L(w) - 1} \frac{\partial E}{\partial v^\prime_j h} \cdot \frac{\partial v_j^\prime h}{\partial h} \\ = \sum_{j=1}^{L(w) - 1} \left(\sigma({v^\prime_j}^T h) - t_j \right)\cdot v_j^\prime := EH \tag{6} hE=j=1L(w)1vjhEhvjh=j=1L(w)1(σ(vjTh)tj)vj:=EH(6)

和之前的公式一样,如果是CBOW模型代入下面的式子就可以进行反向传播更新了:

v w I , c = v w I , c − 1 C ⋅ η ⋅ E H T      f o r   c = 1 , 2 , ⋯   , C (7) v_{w_I,c} = v_{w_I,c} - \frac{1}{C} \cdot \eta \cdot EH^T \,\,\,\, for\, c=1,2,\cdots,C \tag{7} vwI,c=vwI,cC1ηEHTforc=1,2,,C(7)

如果是Skip-gram模型,由于输入只有一个单词,需要计算每个上下文单词的 E H EH EH值,并求和。然后代入下式更新输入单词的向量即可:
v w I = v w I − η ⋅ E H T v_{w_I} = v_{w_I} - \eta \cdot EH^T vwI=vwIηEHT

从更新公式可以看到,隐层到输出层的计算量从 O ( V ) O(V) O(V), 利用哈夫曼树降为了 O ( log ⁡ V ) O(\log V) O(logV)

Negative Sampling

负采样的思想比层次Softmax更直接,也更简单。因为基于softmax,在使用梯度下降的时候,每个训练样本需要更新 V V V个向量。因此负采样只更新一小部分向量,而非全部 V V V个。

考虑单词-上下文词对 ( w , c ) (w,c) (w,c),然后看这个单词对是否出现在训练数据集中。用 p ( D = 1 ∣ w , c ) p(D=1|w,c) p(D=1w,c)表示 ( w , c ) (w,c) (w,c)出现语料库中的概率。相应地, p ( D = 0 ∣ w , c ) = 1 − p ( D = 1 ∣ w , c ) p(D=0|w,c)=1-p(D=1|w,c) p(D=0w,c)=1p(D=1w,c)表示没有出现在语料库中的概率。

假设存在参数 θ \theta θ决定这个分布: p ( D = 1 ∣ w , c ; θ ) p(D=1|w,c;\theta) p(D=1w,c;θ)
我们现在的目标是找到参数 θ \theta θ使得所有出现在训练集中的词对概率最大化。

arg ⁡   max ⁡ θ ∏ ( w , c ) ∈ D p ( D = 1 ∣ w , c ; θ ) \arg\,\max_\theta \prod_{(w,c) \in D} p(D=1|w,c;\theta) argθmax(w,c)Dp(D=1w,c;θ)

取对数就变成了

arg ⁡   max ⁡ θ ∑ ( w , c ) ∈ D log ⁡ p ( D = 1 ∣ w , c ; θ ) \arg\,\max_\theta \sum_{(w,c) \in D} \log p(D=1|w,c;\theta) argθmax(w,c)Dlogp(D=1w,c;θ)

p ( D = 1 ∣ w , c ; θ ) p(D=1|w,c;\theta) p(D=1w,c;θ)可通过softmax来表示:
p ( D = 1 ∣ w , c ; θ ) = 1 1 + e − v w O ′ T h p(D=1|w,c;\theta) = \frac{1}{1 + e^{ -{v^{'}_{w_O}}^T h} } p(D=1w,c;θ)=1+evwOTh1

目标就可以写成:
arg ⁡   max ⁡ θ ∑ ( w , c ) ∈ D log ⁡ 1 1 + e − v w O ′ T h (8) \arg\,\max_\theta \sum_{(w,c) \in D} \log \frac{1}{1 + e^{ -{v^{'}_{w_O}}^T h} } \tag{8} argθmax(w,c)Dlog1+evwOTh1(8)

如果光这样的话,那么只要能找到一个 θ \theta θ使得所有的单词对 ( w , c ) (w,c) (w,c)的概率 p ( D = 1 ∣ w , c ; θ ) = 1 p(D=1|w,c;\theta)=1 p(D=1w,c;θ)=1,就可以得到一个无效解。也就是只要让 v w O ′ = h v^{'}_{w_O} = h vwO=h同时 v w O ′ ⋅ h = K v^{'}_{w_O} \cdot h = K vwOh=K,当 K K K足够大时( K K K只要超过了40)就能使 p ( D = 1 ∣ w , c ; θ ) = 1 p(D=1|w,c;\theta)=1 p(D=1w,c;θ)=1

所以我们需要一个机制能防止所有的向量都学到一样的值,一种方法是抑制一些 ( w , c ′ ) (w,c^{'}) (w,c)的组合,就是碰到这些 ( w , c ′ ) (w,c^{'}) (w,c)组合时, p ( D = 1 ∣ w , c ′ ; θ ) p(D=1|w,c^{'};\theta) p(D=1w,c;θ)的概率必须要很低。 这些 ( w , c ′ ) (w,c^{'}) (w,c)组合很好找,比如可以找不存在数据集中的 ( w , c ′ ) (w,c^{'}) (w,c)。假设在我们的数据集中,中心词是 w w w,它的上下文共有 2 C 2C 2C个词。那么我们在上下文之外取某个词 w ′ w^\prime w,它没有出现在任何 w w w的上下文中。 那么 ( w , w ′ ) (w,w^\prime) (w,w)就是一个我们要的组合,这种组合就是负样本。存在数据集中的单词-上下文词对 ( w , c ) (w,c) (w,c)就是正样本。

按照这种方式,我们可以生成一个随机的负样本词对集合 D ′ D^\prime D。现在我们的目标是让正样本的概率( p ( D = 1 ∣ w , c ; θ ) p(D=1|w,c;\theta) p(D=1w,c;θ))越大越好,让负样本的概率( p ( D = 1 ∣ w , c ′ ; θ ) p(D=1|w,c^{'};\theta) p(D=1w,c;θ))越小越好,或者说让负样本的 p ( D = 0 ∣ w , c ′ ; θ ) p(D=0|w,c^{'};\theta) p(D=0w,c;θ)越大越好。

arg ⁡   max ⁡ θ ∏ ( w , c ) ∈ D p ( D = 1 ∣ w , c ; θ ) ∏ ( w , c ′ ) ∈ D ′ p ( D = 0 ∣ w , c ; θ ) = arg ⁡   max ⁡ θ ∏ ( w , c ) ∈ D p ( D = 1 ∣ w , c ; θ ) ∏ ( w , c ′ ) ∈ D ′ ( 1 − p ( D = 1 ∣ w , c ; θ ) ) = arg ⁡   max ⁡ θ ∑ ( w , c ) ∈ D log ⁡ p ( D = 1 ∣ w , c ; θ ) + ∑ ( w , c ′ ) ∈ D ′ log ⁡ ( 1 − p ( D = 1 ∣ w , c ; θ ) ) = arg ⁡   max ⁡ θ ∑ ( w , c ) ∈ D log ⁡ 1 1 + e − v w O ′ T h + ∑ ( w , c ′ ) ∈ D ′ log ⁡ ( 1 − 1 1 + e − v w i ′ T h ) = arg ⁡   max ⁡ θ ∑ ( w , c ) ∈ D log ⁡ 1 1 + e − v w O ′ T h + ∑ ( w , c ′ ) ∈ D ′ log ⁡ ( 1 1 + e v w i ′ T h ) = arg ⁡   max ⁡ θ ∑ ( w , c ) ∈ D log ⁡ σ ( v w O ′ T h ) + ∑ ( w , c ′ ) ∈ D ′ log ⁡ σ ( − v w i ′ T h ) (9) \begin{aligned} \arg\,\max_\theta \prod_{(w,c) \in D} p(D=1|w,c;\theta) \prod_{(w,c^{'}) \in D^{'}} p(D=0|w,c;\theta) &= \arg\,\max_\theta \prod_{(w,c) \in D} p(D=1|w,c;\theta) \prod_{(w,c^{'}) \in D^{'}} (1 - p(D=1|w,c;\theta)) \\ &= \arg\,\max_\theta \sum_{(w,c) \in D}\log p(D=1|w,c;\theta) + \sum_{(w,c^{'}) \in D^{'}}\log (1 - p(D=1|w,c;\theta)) \\ &= \arg\,\max_\theta \sum_{(w,c) \in D}\log \frac{1}{ 1 + e^{ -{v^{'}_{w_O}}^T h}} + \sum_{(w,c^{'}) \in D^{'}}\log (1 - \frac{1}{ 1 + e^{ -{v^{'}_{w_i}}^T h}}) \\ &= \arg\,\max_\theta \sum_{(w,c) \in D}\log \frac{1}{ 1 + e^{ -{v^{'}_{w_O}}^T h}} + \sum_{(w,c^{'}) \in D^{'}}\log (\frac{1}{ 1 + e^{ {v^{'}_{w_i}}^T h}}) \\ &= \arg\,\max_\theta \sum_{(w,c) \in D}\log \sigma({v^{'}_{w_O}}^T h) + \sum_{(w,c^{'}) \in D^{'}}\log \sigma(-{v^{'}_{w_i}}^T h) \tag{9} \\ \end{aligned} argθmax(w,c)Dp(D=1w,c;θ)(w,c)Dp(D=0w,c;θ)=argθmax(w,c)Dp(D=1w,c;θ)(w,c)D(1p(D=1w,c;θ))=argθmax(w,c)Dlogp(D=1w,c;θ)+(w,c)Dlog(1p(D=1w,c;θ))=argθmax(w,c)Dlog1+evwOTh1+(w,c)Dlog(11+evwiTh1)=argθmax(w,c)Dlog1+evwOTh1+(w,c)Dlog(1+evwiTh1)=argθmax(w,c)Dlogσ(vwOTh)+(w,c)Dlogσ(vwiTh)(9)

这里再次用到了 1 − σ ( x ) = σ ( − x ) 1 - \sigma(x) = \sigma(-x) 1σ(x)=σ(x)

最终这个式子基本上就等同于Mikolov et al在(4)中写的公式(4)了。

和Mikolov et al不同的是,这里用了所有的语料库 D ∪ D ′ D \cup D^{'} DD,而他们使用了一个正样本 ( w , c ) ∈ D (w,c) \in D (w,c)D k k k个负样本 ( w , c ′ ) ∈ D ′ (w,c^{'}) \in D^{'} (w,c)D,如下面的公式:

log ⁡ σ ( v w O ′ T h ) + ∑ w j ∈ W n e g log ⁡ σ ( − v w j ′ T h ) (10) \log \sigma({v^{'}_{w_O}}^T h) + \sum_{w_j \in \mathcal{W_{neg}}} \log \sigma(-{v^{'}_{w_j}}^T h) \tag{10} logσ(vwOTh)+wjWneglogσ(vwjTh)(10)

Mikolov et al构建 D ′ D^{'} D的时候,用了一种特殊的方法。
定义了一个noise distrubution 的 P n ( w ) P_n(w) Pn(w)

P n ( w i ) = f ( w i ) 3 / 4 ∑ j = 0 n f ( w j ) 3 / 4 (11) P_n(w_i) = \frac{ f(w_i)^{3/4} }{ \sum_{j=0}^n f(w_j)^{3/4} } \tag{11} Pn(wi)=j=0nf(wj)3/4f(wi)3/4(11)

有点类似unigram模型, f ( w ) f(w) f(w)是单词 w w w出现的频次。某个词被选中的概率与它的频次有关,取0.75幂的好处是可以减小不同频次差异过大带来的影响,使得小频次的单词被采样的概率变大。

下面给出损失函数

E = − log ⁡ σ ( v w O ′ T h ) − ∑ w j ∈ W n e g log ⁡ σ ( − v w j ′ T h ) (12) E = -\log \sigma({v^{'}_{w_O}}^T h) - \sum_{w_j \in \mathcal{W_{neg}}} \log \sigma(-{v^{'}_{w_j}}^T h) \tag{12} E=logσ(vwOTh)wjWneglogσ(vwjTh)(12)

w O w_O wO是输出单词(正样本); v w O ′ v^{'}_{w_O} vwO是输出向量; h h h是隐藏层的输出值: h = 1 C s u m c = 1 C v w c h = \frac{1}{C} sum_{c=1}^C v_{w_c} h=C1sumc=1Cvwc(CBOW模型)或 h = v w I h = v_{w_I} h=vwI(skip-gram模型); W n e g = { w j ∣ j = 1 , ⋯   , K } \mathcal{W}_{neg} = \{ w_j | j=1,\cdots,K\} Wneg={ wjj=1,,K}是基于 P n ( w ) P_n(w) Pn(w)采样的负样本。

有了损失函数,用梯度下降的方法更新 v ′ v^{'} v即可。还是先看下对 v w j ′ T h {v^{'}_{w_j}}^T h vwjTh的梯度,这里要区分正样本和负样本。

∂ E ∂ v w j ′ T h = { σ ( v w j ′ T h ) − 1 if  w j = w O σ ( v w j ′ T h ) if  w j ∈ W n e g = σ ( v w j ′ T h ) − t j (13) \begin{aligned} \frac{\partial E}{\partial {v^{'}_{w_j}}^T h} &= \begin{cases} \sigma({v^\prime_{w_j}}^T h) -1 & \text{if } w_j = w_O \\ \sigma({v^\prime_{w_j}}^T h) & \text{if } w_j \in \mathcal{W}_{neg} \end{cases} \\ &= \sigma({v^\prime_{w_j}}^T h) - t_j \tag{13} \end{aligned} vwjThE={ σ(vwjTh)1σ(vwjTh)if wj=wOif wjWneg=σ(vwjTh)tj(13)

推导过程和对公式(4)下面的推导类似。
w j w_j wj是正样本时 t j = 1 t_j=1 tj=1,否则 t j = 0 t_j=0 tj=0

下面对单词 w j w_j wj的输出向量 v w j ′ v^\prime_{w_j} vwj求梯度:

∂ E ∂ v w j ′ = ∂ E ∂ v w j ′ T h ⋅ ∂ v w j ′ T h ∂ v w j ′ = ( σ ( v w j ′ T h ) − t j ) h \frac{\partial E}{\partial v^\prime_{w_j}} = \frac{\partial E}{\partial {v^{'}_{w_j}}^T h}\cdot \frac{\partial {v^{'}_{w_j}}^T h}{\partial v^\prime_{w_j}} = \left( \sigma({v^\prime_{w_j}}^T h) - t_j \right)h vwjE=vwjThEvwjvwjTh=(σ(vwjTh)tj)h

这样就得到输出向量的更新式子:

v w j ′ = v w j ′ − η ( σ ( v w j ′ T h ) − t j ) h (14) v^\prime_{w_j} = v^\prime_{w_j} -\eta \left( \sigma({v^\prime_{w_j}}^T h) - t_j \right)h \tag{14} vwj=vwjη(σ(vwjTh)tj)h(14)

这个和非负采样的更新公式看起来有点像,对于每个训练数据,我们只要更新 w j ∈ { w O } ∪ W n e g w_j \in \{w_O\} \cup \mathcal{W_{neg}} wj{ wO}Wneg这么点向量,而非原始的 V V V个,大大降低了训练复杂度。

这个更新公式能同时应用到CBOW和skip-gram模型,在skip-gram模型中,每次只更新一个上下文单词向量。

最后求解对隐藏层的梯度:

∂ E ∂ h = ∑ w j ∈ { w O } ∪ W n e g ∂ E ∂ v w j ′ T h ⋅ ∂ v w j ′ T h ∂ h = ∑ w j ∈ { w O } ∪ W n e g ( σ ( v w j ′ T h ) − t j ) v w j ′ : = E H \begin{aligned} \frac{\partial E}{\partial h} &= \sum_{w_j \in \{w_O\} \cup \mathcal{W_{neg}}} \frac{\partial E}{\partial {v^\prime_{w_j}}^T h } \cdot \frac{\partial {v^{'}_{w_j}}^T h}{\partial h} \\ &= \sum_{w_j \in \{w_O\} \cup \mathcal{W_{neg}}} \left( \sigma({v^\prime_{w_j}}^T h) - t_j \right) v^{'}_{w_j} := EH \end{aligned} hE=wj{ wO}WnegvwjThEhvwjTh=wj{ wO}Wneg(σ(vwjTh)tj)vwj:=EH

和之前的公式一样,如果是CBOW模型代入下面的式子就可以进行反向传播更新了:

v w I , c = v w I , c − 1 C ⋅ η ⋅ E H T      f o r   c = 1 , 2 , ⋯   , C v_{w_I,c} = v_{w_I,c} - \frac{1}{C} \cdot \eta \cdot EH^T \,\,\,\, for\, c=1,2,\cdots,C vwI,c=vwI,cC1ηEHTforc=1,2,,C

如果是Skip-gram模型,由于输入只有一个单词,需要计算每个上下文单词的 E H EH EH值,并求和。然后代入下式更新输入单词的向量即可:
v w I = v w I − η ⋅ E H T v_{w_I} = v_{w_I} - \eta \cdot EH^T vwI=vwIηEHT

通过上面的过程可以看到,对于输入层到隐层的矩阵 W W W,所有的输入向量都会更新,而对于隐层到输出层的矩阵 W ′ W^{'} W,只更新了 k k k个负样本。这也是选择 W W W作为词向量原因。

参考

  1. word2vec Explained: Deriving Mikolov et al.’s Negative-Sampling Word-Embedding Method
  2. On word embeddings
  3. word2vec Parameter Learning Explained
  4. Distributed representations of words and phrases and their compositionality.

你可能感兴趣的:(人工智能,读书笔记,层次Softmax,负采样,word2vec公式推导)