本文共分为三节,由若干文章拼接而成。第一节具体推导word2vec参数的更新规则,第二节介绍在词表比较大时对softmax做近似的方法,第三部分介绍如何生成好的词向量
本节内容完全来自于[Rong2014]
上下文只有一个单词时,网络做的事情其实类似于二元语法模型。假设词表大小为 V V V,隐藏层大小为 N N N,输入层到隐藏层及隐藏层到输出层都是全连接,输入为独热编码向量,那么网络的示意图如下图所示
从图中可知,输入层和隐藏层之间的权重可以使用 V × N V \times N V×N的矩阵 W \boldsymbol{W} W表示。假设输入的语境单词为词表中的第 k k k个单词,则输入向量 x \boldsymbol{x} x满足 x k = 1 x_k = 1 xk=1且 ∀ k ′ ̸ = k → x k ′ = 0 \forall k' \not= k \rightarrow x_{k'} = 0 ∀k′̸=k→xk′=0,因此有
h = W T x = w ( k , ⋅ ) T : = v w I T \boldsymbol{h} = \boldsymbol{W}^\mathsf{T}\boldsymbol{x} = \boldsymbol{w}_{(k, \cdot)}^\mathsf{T} := \boldsymbol{v}_{w_I}^\mathsf{T} h=WTx=w(k,⋅)T:=vwIT
即 W \boldsymbol{W} W的第k行行向量实际上就是词表中第k个单词词向量的转置,记输入单词词向量为 v w I \boldsymbol{v}_{w_I} vwI
假设最后得到的得分向量为 u \boldsymbol{u} u,则从隐藏层到输出层有
(1) u = W ′ T h \boldsymbol{u} = \boldsymbol{W}'^\mathsf{T}\boldsymbol{h} \tag{1} u=W′Th(1)
其中 u \boldsymbol{u} u的第 j j j行元素 u j u_j uj为
(2) u j = w ( ⋅ , j ) ′ T h u_j = \boldsymbol{w}_{(\cdot, j)}'^\mathsf{T}\boldsymbol{h} \tag{2} uj=w(⋅,j)′Th(2)
这里 w ( ⋅ , j ) ′ \boldsymbol{w}_{(\cdot, j)}' w(⋅,j)′是 W ′ \boldsymbol{W}' W′的第 j j j列。记 w ( ⋅ , j ) ′ \boldsymbol{w}_{(\cdot, j)}' w(⋅,j)′为 v w O ′ \boldsymbol{v}'_{w_O} vwO′
得到 u \boldsymbol{u} u以后,可以使用softmax来得到单词的后验分布:给定上文单词为 w I w_I wI的情况下,出现单词 w O w_O wO的概率为
(3) P ( w O ∣ w I ) = y j = exp ( u j ) ∑ j ′ = 1 V exp ( u j ′ ) P(w_O|w_I) = y_j = \frac{\exp(u_j)}{\sum_{j'=1}^V \exp(u_{j'})} \tag{3} P(wO∣wI)=yj=∑j′=1Vexp(uj′)exp(uj)(3)
将式(1)和(2)代入(3)可得
(4) P ( w O ∣ w I ) = exp ( v w O ′ T v w I ) ∑ j ′ = 1 V exp ( v w j ′ ′ T v w I ) P(w_O|w_I) = \frac{\exp\left(\boldsymbol{v}_{w_O}'^\mathsf{T}\boldsymbol{v}_{w_I}\right)}{\sum_{j'=1}^V \exp\left(\boldsymbol{v}_{w_j'}'^\mathsf{T}\boldsymbol{v}_{w_I}\right)} \tag{4} P(wO∣wI)=∑j′=1Vexp(vwj′′TvwI)exp(vwO′TvwI)(4)
可见对同一个单词 w w w来说,会有两个嵌入表示 v w \boldsymbol{v}_{w} vw和 v w ′ \boldsymbol{v}_{w}' vw′,前者是 W \boldsymbol{W} W的第 i i i行行向量,后者是 W ′ \boldsymbol{W}' W′的第 i i i列列向量。在后续的分析中,称前者为单词 w w w的输入向量,后者为单词 w w w的输出向量
假设给定单词 w k w_k wk,期望输出是单词 w j ∗ w_{j^\ast} wj∗,那么模型优化的目标是要最大化正确单词对应的概率 y j ∗ y_{j^\ast} yj∗,有
arg max W ′ p ( w O ∣ w I ) = arg max W ′ y j ∗ = arg max W ′ log y j ∗ = arg max W ′ ( u j ∗ − log ∑ j ′ = 1 V exp ( u j ′ ) ) \begin{aligned} \mathop{ {\rm \arg}\max}_{\boldsymbol{W}'} p(w_O|w_I) &= \mathop{ {\rm \arg}\max}_{\boldsymbol{W}'} y_{j^\ast} \\ &= \mathop{ {\rm \arg}\max}_{\boldsymbol{W}'} \log y_{j^\ast} \\ &= \mathop{ {\rm \arg}\max}_{\boldsymbol{W}'} \left(u_{j^\ast} - \log \sum_{j'=1}^V \exp(u_{j'})\right) \end{aligned} argmaxW′p(wO∣wI)=argmaxW′yj∗=argmaxW′logyj∗=argmaxW′⎝⎛uj∗−logj′=1∑Vexp(uj′)⎠⎞
记 E = − log p ( w O ∣ w I ) E = -\log p(w_O|w_I) E=−logp(wO∣wI) 为学习的目标函数,那么学习的目的就是最小化 E E E。可知
∂ E ∂ u j = y j − t j : = e j \frac{\partial E}{\partial u_j} = y_j - t_j := e_j ∂uj∂E=yj−tj:=ej
其中 t j = 1 ( j = j ∗ ) t_j = \mathbb{1}(j = j^\ast) tj=1(j=j∗)。或者可以写为
∂ E ∂ u j = { y j − 1 j = j ∗ y j e l s e w h e r e \frac{\partial E}{\partial u_j} = \begin{cases}y_j - 1 & j = j^\ast \\ y_j & {\rm elsewhere}\end{cases} ∂uj∂E={yj−1yjj=j∗elsewhere
接着可以求出 E E E对 W ′ \boldsymbol{W}' W′中每个元素 w i j ′ w_{ij}' wij′的偏导数
∂ E ∂ w i j ′ = ∂ E ∂ u j ⋅ ∂ u j ∂ w i j ′ = e j ⋅ h i \frac{\partial E}{\partial w_{ij}'} = \frac{\partial E}{\partial u_j}\cdot \frac{\partial u_j}{\partial w_{ij}'} = e_j \cdot h_i ∂wij′∂E=∂uj∂E⋅∂wij′∂uj=ej⋅hi
因此梯度下降的更新方法为
w i j ′ ( n e w ) = w i j ′ ( o l d ) − η ⋅ e j ⋅ h i w_{ij}'^{(\rm new)} = w_{ij}'^{(\rm old)} - \eta \cdot e_j\cdot h_i wij′(new)=wij′(old)−η⋅ej⋅hi
向量化的形式为
v w j ′ ( n e w ) = v w j ′ ( o l d ) − η ⋅ e j ⋅ h \boldsymbol{v}_{w_j}'^{(\rm new)} = \boldsymbol{v}_{w_j}'^{(\rm old)} - \eta \cdot e_j \cdot \boldsymbol{h} vwj′(new)=vwj′(old)−η⋅ej⋅h
这意味着,当 y j > t j y_j > t_j yj>tj时, e j e_j ej为正值, v w j ′ \boldsymbol{v}_{w_j}' vwj′会变小。由于 t j t_j tj只能为0或1,因此这说明给定输入单词为 w I w_I wI时,对不是期望单词序号 j ∗ j^\ast j∗的 j j j, w j w_j wj的输出向量会变小,反之相反
首先计算目标函数 E E E对隐藏层每个输出元素 h i h_i hi的偏导数。由于隐藏层到输出层是全连接的,因此 h i h_i hi对每个 u j u_j uj都有贡献,使用全微分公式有
∂ E ∂ h i = ∑ j = 1 V ∂ E ∂ u j ⋅ ∂ u j ∂ h i = ∑ j = 1 V e j ⋅ w i j ′ : = e i ′ \frac{\partial E}{\partial h_i} = \sum_{j=1}^V \frac{\partial E}{\partial u_j} \cdot \frac{\partial u_j}{\partial h_i} = \sum_{j=1}^V e_j \cdot w_{ij}' := e'_i ∂hi∂E=j=1∑V∂uj∂E⋅∂hi∂uj=j=1∑Vej⋅wij′:=ei′
其中 e i ′ e'_i ei′是 N N N维向量 e ′ \boldsymbol{e}' e′的第 i i i个元素。由于输入层到隐藏层也是一个全连接,因此有
h i = ∑ k = 1 V x k ⋅ w k i h_i = \sum_{k=1}^V x_k \cdot w_{ki} hi=k=1∑Vxk⋅wki
所以对 W \boldsymbol{W} W的每个元素 w k i w_{ki} wki,有
∂ E ∂ w k i = ∂ E ∂ h i ⋅ ∂ h i ∂ w k i = e i ′ ⋅ x k \frac{\partial E}{\partial w_{ki}} = \frac{\partial E}{\partial h_i}\cdot \frac{\partial h_i}{\partial w_{ki}} = e'_i \cdot x_k ∂wki∂E=∂hi∂E⋅∂wki∂hi=ei′⋅xk
写成向量(矩阵)形式,为
∂ E ∂ W = x ⊗ e ′ = x e ′ T \frac{\partial E}{\partial \boldsymbol{W}} = \boldsymbol{x} \otimes \boldsymbol{e}' = \boldsymbol{x}\boldsymbol{e}'^\mathsf{T} ∂W∂E=x⊗e′=xe′T
由于 x \boldsymbol{x} x是独热向量,因此 ∂ E / ∂ W = e ′ T \partial E/\partial \boldsymbol{W} = \boldsymbol{e}'^\mathsf{T} ∂E/∂W=e′T,即
v w I ( n e w ) = v w I ( o l d ) − η e ′ T \boldsymbol{v}_{w_I}^{(\rm new)} = \boldsymbol{v}_{w_I}^{(\rm old)} - \eta \boldsymbol{e}'^\mathsf{T} vwI(new)=vwI(old)−ηe′T
这意味着本次更新只有输入单词对应的那一行参数会受到影响
从前面的推导中可以看出, e ′ \boldsymbol{e}' e′实际上是 V V V个输出向量 v j ′ \boldsymbol{v}_j' vj′的加权求和,权重是每个单词 j j j的损失值 e j = y j − t j e_j = y_j - t_j ej=yj−tj。因此如果在输出层中,单词 w j w_j wj成为输出单词的概率被高估了,梯度下降会把输入向量 w I w_I wI拉得离 w j w_j wj的输出向量远一些,反之相反
综上所述,整个参数更新的过程实际上就是输出词的输出向量被输入词(邻居)的输入向量来回拉扯的过程,对输入词的输入向量也是如此。两个词的共现次数越多,对应向量之间的拉力就越强,最后整个系统在经历足够多的迭代以后,会稳定下来
当上下文有多个单词时(假设有 C C C个),隐藏层会对输入向量做平均
h = 1 C W T ( x 1 + x 2 + ⋯ + x C ) = 1 C ( v w 1 + v w 2 + ⋯ + v w C ) T \begin{aligned} \boldsymbol{h} &= \frac{1}{C}\boldsymbol{W}^\mathsf{T}(\boldsymbol{x}_1 + \boldsymbol{x}_2 + \cdots + \boldsymbol{x}_C) \\ &= \frac{1}{C}(\boldsymbol{v}_{w_1} + \boldsymbol{v}_{w_2} + \cdots + \boldsymbol{v}_{w_C})^\mathsf{T} \end{aligned} h=C1WT(x1+x2+⋯+xC)=C1(vw1+vw2+⋯+vwC)T
模型的损失函数并没有变化,结构变为如下形式
输出向量的更新方法也没有变化,唯一变化是输入向量的更新量是之前的 C C C分之一
v w I , c ( n e w ) = v w I , c ( o l d ) − 1 C ⋅ η e ′ T \boldsymbol{v}_{w_{I, c}}^{(\rm new)} = \boldsymbol{v}_{w_{I, c}}^{(\rm old)} - \frac{1}{C}\cdot\eta \boldsymbol{e}'^\mathsf{T} vwI,c(new)=vwI,c(old)−C1⋅ηe′T
CBOW模型是用多个词做上下文,预测的是中心词;而跳表模型是用一个词做上下文,预测的是周围词。因此,对跳表模型,隐藏层输入向量与单个单词做上下文的CBOW模型没有区别
h = w ( k , ⋅ ) T : = v w I T \boldsymbol{h} = \boldsymbol{w}_{(k, \cdot)}^\mathsf{T} := \boldsymbol{v}_{w_I}^\mathsf{T} h=w(k,⋅)T:=vwIT
由于是预测周围 C C C个词,因此输出层要输出 C C C个多项分布,输出之间共享隐藏层到输出层的矩阵 W ′ \boldsymbol{W'} W′。有
p ( w c , j = w O , c ∣ w I ) = y c , j = exp ( u c , j ) ∑ j ′ = 1 V exp ( u j ′ ) p(w_{c,j} = w_{O, c}|w_I) = y_{c,j} = \frac{\exp(u_{c, j})}{\sum_{j'=1}^V \exp(u_{j'})} p(wc,j=wO,c∣wI)=yc,j=∑j′=1Vexp(uj′)exp(uc,j)
其中 w c , j w_{c,j} wc,j是输出层中第 c c c个位置上的第 j j j个单词, w O , c w_{O, c} wO,c是输出单词序列中的第 c c c个单词(第 c c c个位置上的实际单词), w I w_I wI是唯一的那个输入单词, y c , j y_{c,j} yc,j是模型算出第 c c c个位置上是第 j j j个单词的概率。由于输出层各个位置共享权重,因此
u c , j = u j = v w j ′ T ⋅ h , f o r c = 1 , 2 , ⋯   , C u_{c,j} = u_j = \boldsymbol{v}_{w_j}'^\mathsf{T} \cdot \boldsymbol{h},\ \ {\rm for\ }c =1,2,\cdots, C uc,j=uj=vwj′T⋅h, for c=1,2,⋯,C
其中 v w j ′ \boldsymbol{v}_{w_j}' vwj′仍然是第 j j j个单词的输出向量,也是 W j ′ \boldsymbol{W}_j' Wj′的第 j j j列。跳表模型的示意图如下
由于是预测多个输出单词,因此需要对 C C C个输出概率连乘。损失函数变为
E = − log p ( w O , 1 , w O , 2 , ⋯   , w O , C ∣ w I ) = − log ∏ c = 1 C exp ( u c , j c ∗ ) ∑ j ′ = 1 V exp ( u j ′ ) = − ∑ c = 1 C u j c ∗ + C ⋅ log ∑ j ′ = 1 V exp ( u j ′ ) \begin{aligned} E &= -\log p(w_{O,1}, w_{O, 2}, \cdots, w_{O, C}|w_I) \\ &= -\log \prod_{c=1}^C \frac{\exp (u_{c, j_c^\ast})}{\sum_{j'=1}^V \exp(u_{j'})} \\ &= -\sum_{c=1}^C u_{j_{c}^\ast} + C \cdot \log\sum_{j'=1}^V \exp(u_{j'}) \end{aligned} E=−logp(wO,1,wO,2,⋯,wO,C∣wI)=−logc=1∏C∑j′=1Vexp(uj′)exp(uc,jc∗)=−c=1∑Cujc∗+C⋅logj′=1∑Vexp(uj′)
对输出的每个位置 c c c, ∂ E / ∂ u c , j \partial E / \partial u_{c,j} ∂E/∂uc,j的计算方法与之前差别不大
∂ E ∂ u c , j = y c , j − t c , j : = e c , j \frac{\partial E}{\partial u_{c,j}} = y_{c,j} - t_{c,j} := e_{c,j} ∂uc,j∂E=yc,j−tc,j:=ec,j
定义 e j e_j ej为每个位置 c c c上模型都预测为 w j w_j wj时,模型的损失值总和
e j = ∑ c = 1 C e c , j e_j = \sum_{c=1}^C e_{c,j} ej=c=1∑Cec,j
这样,跳表模型的 ∂ E / ∂ w i j ′ \partial E /\partial w_{ij}' ∂E/∂wij′、 e i ′ e_i' ei′和权重更新公式就和前面单个上下文CBOW模型的公式形式一样了
前面提到无论是CBOW还是SkipGram算法,对每个单词都会计算出一个输入向量 v w \boldsymbol{v}_w vw和一个输出向量 v w ′ \boldsymbol{v}_w' vw′。为了计算输出向量,对每条训练数据都要迭代词表中的每个单词 w j w_j wj,计算原始得分 u j u_j uj、概率 p j p_j pj(对SkipGram是 p c , j p_{c, j} pc,j)、误差 e j e_j ej然后才能更新 v j ′ \boldsymbol{v}_j' vj′。这些计算代价太高,因此对大型训练语料或者大词表使用原始做法比较难,因此人们想出了分层softmax和负采样两种做法
分层softmax的做法是建立一棵二叉树(更确切地说,为了快速训练,是一颗Huffman树)表达此表中的所有单词,其中所有单词对应的节点都是叶子节点,因此树一共有 V V V个叶子节点,相应地有 V − 1 V-1 V−1个内部节点。而且由树的性质,从树根到每个单词的路径是唯一的,这条路径也就可以用来估计叶子节点对应单词的概率。对单词 w w w,记从根节点到其对应叶子节点路径上的第 j j j个节点为 n ( w , j ) n(w,j) n(w,j)
在该模型中,单词不再有对应的输出向量表示,而是每个内部节点都有一个输出向量 v n ( w , j ) ′ \boldsymbol{v}'_{n(w,j)} vn(w,j)′。令 L ( w ) L(w) L(w)是路径的长度(即路径上有几个节点,因此 n ( w , 1 ) = r o o t n(w, 1) = {\rm root} n(w,1)=root, n ( w , L ( w ) ) = w n(w, L(w)) = w n(w,L(w))=w)。对所有内部节点 n n n,令 c h ( n ) {\rm ch}(n) ch(n)为其左孩子(Mikolov的原始论文里其实无此限制),并令 [ ​ [ x ] ​ ] [\![x]\!] [[x]]在 x x x为真时为1否则为-1, σ ( x ) \sigma(x) σ(x)是sigmoid函数,则一个单词是输出单词的概率是
p ( w = w O ) = ∏ j = 1 L ( w ) − 1 σ ( [ ​ [ n ( w , j + 1 ) = c h ( n ( w , j ) ) ] ​ ] ⋅ v n ( w , j ) ′ T h ) p(w=w_O) = \prod_{j=1}^{L(w)-1}\sigma\left([\![n(w, j+1) = {\rm ch}(n(w, j))]\!] \cdot {\boldsymbol{v}_{n(w,j)}'}^\mathsf{T}\boldsymbol{h}\right) p(w=wO)=j=1∏L(w)−1σ([[n(w,j+1)=ch(n(w,j))]]⋅vn(w,j)′Th)
上图给出了分层softmax的一个示例。假设要计算输出单词为 w 2 w_2 w2的概率,这实际上是计算从根开始随机游走,有多大概率会走到 w 2 w_2 w2对应的叶子节点。我们先定义在每个内部节点向左走的概率为
p ( n , l e f t ) = σ ( v n ′ T ⋅ h ) p(n, {\rm left}) = \sigma\left(\boldsymbol{v}_n'^\mathsf{T}\cdot \boldsymbol{h}\right) p(n,left)=σ(vn′T⋅h)
由于二叉树是Huffman树,每个内部节点有且仅有两个分支,因此显然 p ( n , r i g h t ) = 1 − p ( n , l e f t ) p(n, {\rm right}) = 1 - p(n, {\rm left}) p(n,right)=1−p(n,left)。由sigmoid函数的性质,有
p ( n , r i g h t ) = σ ( − v n ′ T ⋅ h ) p(n, {\rm right}) = \sigma\left(-\boldsymbol{v}_n'^\mathsf{T}\cdot \boldsymbol{h}\right) p(n,right)=σ(−vn′T⋅h)
所以有
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), {\rm left}) \cdot p(n(w_2, 2), {\rm left}) \cdot p(n(w_2, 3), {\rm right})\\ &= \sigma\left(\boldsymbol{v}_{n(w_2,1)}'^\mathsf{T}\cdot \boldsymbol{h}\right) \cdot \sigma\left(\boldsymbol{v}_{n(w_2,2)}'^\mathsf{T}\cdot \boldsymbol{h}\right) \cdot \sigma\left(-\boldsymbol{v}_{n(w_2,3)}'^\mathsf{T}\cdot \boldsymbol{h}\right) \end{aligned} p(w2=wO)=p(n(w2,1),left)⋅p(n(w2,2),left)⋅p(n(w2,3),right)=σ(vn(w2,1)′T⋅h)⋅σ(vn(w2,2)′T⋅h)⋅σ(−vn(w2,3)′T⋅h)
显然有
∑ i = 1 V p ( w i = w O ) = 1 \sum_{i=1}^V p(w_i = w_O) = 1 i=1∑Vp(wi=wO)=1
接下来来看一下分层softmax算法如何更新权重。为了简单起见,不失准确性地,可以记
[ ​ [ ⋅ ] ​ ] : = [ ​ [ n ( w , j + 1 ) = c h ( n ( w , j ) ) ] ​ ] v j ′ : = v n ( w , j ) ′ \begin{aligned} [\![\cdot]\!] &:= [\![n(w, j+1) = {\rm ch}(n(w, j))]\!] \\ \boldsymbol{v}'_j &:= \boldsymbol{v}'_{n_{(w, j)}} \end{aligned} [[⋅]]vj′:=[[n(w,j+1)=ch(n(w,j))]]:=vn(w,j)′
因此损失函数为
E = − log p ( w = w O ∣ w I ) = − ∑ j = 1 L ( w ) − 1 log σ ( [ ​ [ ⋅ ] ​ ] v j ′ T h ) E = -\log p(w=w_O|w_I) = -\sum_{j=1}^{L(w)-1}\log \sigma\left([\![\cdot]\!]\boldsymbol{v}_j'^\mathsf{T}\boldsymbol{h}\right) E=−logp(w=wO∣wI)=−j=1∑L(w)−1logσ([[⋅]]vj′Th)
先计算 ∂ E / ∂ v j ′ T h \partial E/\partial \boldsymbol{v}_j'^\mathsf{T}\boldsymbol{h} ∂E/∂vj′Th。考虑到 σ ′ ( x ) = σ ( x ) ( 1 − σ ( x ) ) \sigma'(x) = \sigma(x)(1-\sigma(x)) σ′(x)=σ(x)(1−σ(x))和 σ ( − x ) = 1 − σ ( x ) \sigma(-x) = 1-\sigma(x) σ(−x)=1−σ(x),有
∂ E ∂ v j ′ T h = ( σ ( [ ​ [ ⋅ ] ​ ] v j ′ T h ) − 1 ) [ ​ [ ⋅ ] ​ ] = { σ ( v j ′ T h ) − 1 ( [ ​ [ ⋅ ] ​ ] = 1 ) σ ( v j ′ T h ) ( [ ​ [ ⋅ ] ​ ] = − 1 ) = σ ( v j ′ T h ) − t j \begin{aligned} \frac{\partial E}{\partial \boldsymbol{v}_j'^\mathsf{T}\boldsymbol{h}} &= \left(\sigma\left( [\![\cdot]\!] \boldsymbol{v}_j'^\mathsf{T}\boldsymbol{h}\right)-1\right)[\![\cdot]\!] \\ &= \begin{cases}\sigma\left(\boldsymbol{v}_j'^\mathsf{T}\boldsymbol{h}\right) - 1 & ([\![\cdot]\!] = 1)\\ \sigma\left(\boldsymbol{v}_j'^\mathsf{T}\boldsymbol{h}\right) & ([\![\cdot]\!] = -1) \end{cases} \\ &= \sigma\left(\boldsymbol{v}_j'^\mathsf{T}\boldsymbol{h}\right) - t_j \end{aligned} ∂vj′Th∂E=(σ([[⋅]]vj′Th)−1)[[⋅]]={σ(vj′Th)−1σ(vj′Th)([[⋅]]=1)([[⋅]]=−1)=σ(vj′Th)−tj
其中
t j = { 1 i f [ ​ [ ⋅ ] ​ ] = 1 0 e l s e w h e r e \begin{aligned} t_j = \begin{cases}1 & {\rm if\ }[\![\cdot]\!]=1 \\ 0 & {\rm elsewhere}\end{cases} \end{aligned} tj={10if [[⋅]]=1elsewhere
有了 ∂ E / ∂ v j ′ T h \partial E/\partial \boldsymbol{v}_j'^\mathsf{T}\boldsymbol{h} ∂E/∂vj′Th以后,计算 ∂ E / ∂ v ′ \partial E / \partial \boldsymbol{v}' ∂E/∂v′就容易许多:
∂ E ∂ v j ′ = ∂ E ∂ v j ′ T h ⋅ ∂ v j ′ T h ∂ v j ′ = ( σ ( v j ′ T h ) − t j ) ⋅ h \frac{\partial E}{\partial \boldsymbol{v}_j'} = \frac{\partial E}{\partial \boldsymbol{v}_j'^\mathsf{T}\boldsymbol{h}} \cdot \frac{\partial \boldsymbol{v}_j'^\mathsf{T}\boldsymbol{h}}{\partial \boldsymbol{v}_j'} = \left(\sigma(\boldsymbol{v}_j'^\mathsf{T}\boldsymbol{h})-t_j\right) \cdot \boldsymbol{h} ∂vj′∂E=∂vj′Th∂E⋅∂vj′∂vj′Th=(σ(vj′Th)−tj)⋅h
所以对 j = 1 , 2 , ⋯   , L ( w ) − 1 j = 1, 2, \cdots, L(w)-1 j=1,2,⋯,L(w)−1,有内部节点输出向量的更新公式
v j ′ ( n e w ) = v j ′ ( o l d ) − η ( σ ( v j ′ T h ) − t j ) ⋅ h \boldsymbol{v}_j'^{(\rm new)} = \boldsymbol{v}_j'^{\rm (old)} - \eta \left(\sigma(\boldsymbol{v}_j'^\mathsf{T}\boldsymbol{h})-t_j\right) \cdot \boldsymbol{h} vj′(new)=vj′(old)−η(σ(vj′Th)−tj)⋅h
该公式对CBOW和skip-gram模型都适用。对于后者,需要对 C C C个输出单词重复走一遍这个过程
为了学习输入层到隐藏层的权重,需要计算 ∂ E / ∂ h \partial E/\partial \boldsymbol{h} ∂E/∂h:
∂ 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 ′ : = e ′ \begin{aligned} \frac{\partial E}{\partial \boldsymbol{h}} &= \sum_{j=1}^{L(w)-1}\frac{\partial E}{\partial \boldsymbol{v}_j'^\mathsf{T}\boldsymbol{h}} \cdot \frac{\partial \boldsymbol{v}_j'^\mathsf{T}\boldsymbol{h}}{\partial \boldsymbol{h}} \\ &= \sum_{j=1}^{L(w)-1} \left(\sigma(\boldsymbol{v}_j'^\mathsf{T}\boldsymbol{h})-t_j\right) \cdot \boldsymbol{v}_j' \\ &:= \boldsymbol{e}' \end{aligned} ∂h∂E=j=1∑L(w)−1∂vj′Th∂E⋅∂h∂vj′Th=j=1∑L(w)−1(σ(vj′Th)−tj)⋅vj′:=e′
就可以继续用之前推导过的公式来更新权重
可以看出,使用分层softmax以后,参数数量没有变化( V − 1 V-1 V−1个输出向量, V V V个输入向量),但是每个训练单词的计算复杂度从 O ( V ) O(V) O(V)削减到了 O ( log ( V ) ) O(\log(V)) O(log(V))
负采样的思想是,由于每次迭代要花时间更新太多输出向量,不如采样少量几个单词,把它们当做负样本。采样负样本只需要设计一个合理的概率分布就可以,这里称其为“噪声分布”,记为 P n ( w ) P_n(w) Pn(w)。原文的噪声分布参见词向量的介绍。目标函数为
E = − log σ ( v w O ′ T h ) − ∑ w j ∈ W n e g log σ ( − v w j ′ T h ) E = -\log \sigma(\boldsymbol{v}_{w_O}'^\mathsf{T}\boldsymbol{h}) - \sum_{w_j \in \mathcal{W}_{\rm neg}} \log \sigma(-\boldsymbol{v}_{w_j}'^\mathsf{T}\boldsymbol{h}) E=−logσ(vwO′Th)−wj∈Wneg∑logσ(−vwj′Th)
其中
类似地,可以先计算出损失函数对原始得分的偏导数
∂ E ∂ v w j ′ T h = { σ ( v w j ′ T h ) − 1 i f w j = w O σ ( v w j ′ T h ) i f w j ∈ W n e g = σ ( v w j ′ T h ) − t j \begin{aligned} \frac{\partial E}{\partial \boldsymbol{v}_{w_j}'^\mathsf{T}\boldsymbol{h}} &= \begin{cases}\sigma\left(\boldsymbol{v}_{w_j}'^\mathsf{T}\boldsymbol{h}\right) - 1 & {\rm if\ } w_j = w_O \\ \sigma\left(\boldsymbol{v}_{w_j}'^\mathsf{T}\boldsymbol{h}\right) & {\rm if\ }w_j\in \mathcal{W}_{\rm neg}\end{cases} \\ &= \sigma\left(\boldsymbol{v}_{w_j}'^\mathsf{T}\boldsymbol{h}\right)-t_j \end{aligned} ∂vwj′Th∂E=⎩⎨⎧σ(vwj′Th)−1σ(vwj′Th)if wj=wOif wj∈Wneg=σ(vwj′Th)−tj
其中 t j t_j tj意义明显,不再进一步解释。接下来的参数更新方式和 ∂ E / ∂ h \partial E/\partial \boldsymbol{h} ∂E/∂h的计算也与前面分层softmax部分的推导类似,不再赘述
本节主要来自于Ruder的博客文章[Ruder2016]
如本文和前面若干文章所讨论过的,softmax的最大问题是要对每个词都计算得分,因此当词表非常大时,算法的时间复杂度非常高。为了不让这个步骤成为影响效率的主要瓶颈,人们提出了很多种方法。其中softmax扩展法仍然保留了softmax的基本思想,不过对体系结构做出了修改;而采样法则是去掉了softmax层,通过修改损失函数做softmax的近似。word2vec的两个改进方案里,分层Softmax(以下简称HSM)属于第一种方法,而负采样属于第二种
(本节写作的初衷是,直觉上感觉TensorFlow不太好实现HSM,想看看有没有写得比较漂亮的代码,然后发现好像真的没有。接着,在OpenNMT-py,也就是OpenNMT的PyTorch版,的一个issue里,看到他们没有实现HSM的原因是PyTorch实现了一个更高效的方法,称为适应softmax(adaptive softmax,简称ASM)。因此勾起了我的好奇心,想看看有没有其它类似比较高效的,适用于大规模词表的softmax方法,于是就找到了Ruder的这篇文章。但是此文成文之时并没有介绍ASM,因此本节会同时覆盖两者,并把ASM作为重点。其它方法基本都会简略带过)
除去HSM和ASM,[Ruder2016]还介绍了两种扩展方法
本小节主要介绍的工作是FAIR在2016年发表的工作ASM[Grave2017](2016年首发于arxiv),这项工作的最大特点是其目的是要有效利用GPU,比起普通softmax有2倍到10倍性能提升。其核心思想是将单词聚类,然后做分层softmax
假设训练时每批量数据大小为 B B B,隐藏单元数量为 d d d,词表大小为 k k k,大小为 B × d B\times d B×d的隐层矩阵与大小为 d × k d \times k d×k的输出层矩阵相乘的计算时间为 g ( k , B ) g(k, B) g(k,B)。实验表明,当固定 B B B大小不变时,存在一个阈值 k 0 k_0 k0,使得 k ≤ k 0 k \le k_0 k≤k0时 g ( k ) g(k) g(k)的时间为常量, k > k 0 k > k_0 k>k0时 g ( k ) g(k) g(k)与 k k k呈线性关系,对 B B B也存在一个类似的 B 0 B_0 B0。因此有
g ( k , B ) = max ( c + λ k 0 B 0 , c + λ k B ) g(k,B) = \max(c+\lambda k_0B_0, c+\lambda kB) g(k,B)=max(c+λk0B0,c+λkB)
即当矩阵相乘时,如果某个维度比较小,则相乘效率会降低。所以使用Huffman编码的效率不是最优的,原因是会导致每个内部结点下面只有两个叶子节点,节点数太少;或者如果某个内部节点下面的叶子节点都是罕见词,概率 p p p都很小,也会导致 p B pB pB变小,不划算
由于自然语言中存在Zipf现象(直观例子是87%的文档由20%单词覆盖),因此直观地说可以把词典 V \mathcal{V} V划分成两个簇 V h \mathcal{V}_{\rm h} Vh和 V t \mathcal{V}_{\rm t} Vt,其中 V h \mathcal{V}_{\rm h} Vh是分布的头部(头簇),只包含最常见的单词; V t \mathcal{V}_{\rm t} Vt是分布的尾部(尾簇),包含大量罕见词。划分应该满足 ∣ V h ∣ ≪ ∣ V t ∣ |\mathcal{V}_{\rm h}| \ll |\mathcal{V}_{\rm t}| ∣Vh∣≪∣Vt∣且 p h : = ∑ w ∈ V h p i ≫ p t : = ∑ w ∈ V t p i p_{\rm h} := \sum_{w \in \mathcal{V_{\rm h}}}p_i \gg p_{\rm t} := \sum_{w \in \mathcal{V_{\rm t}}}p_i ph:=∑w∈Vhpi≫pt:=∑w∈Vtpi。如果使用short-list实现方式(根节点里包含一个列表,列表中存储头簇),且记 k h = ∣ V h ∣ k_{\rm h} = |\mathcal{V}_{\rm h}| kh=∣Vh∣,则总的计算时间为
C = g ( k h + 1 , B ) + g ( k t , p t B ) C = g(k_{\rm h}+1, B) + g(k_{\rm t}, p_{\rm t}B) C=g(kh+1,B)+g(kt,ptB)
文章使用了一个投影矩阵来把尾簇的维度降低到 d / 4 d/4 d/4,因为罕见词不太容易被学习,使用高维空间比较浪费
类似的思想可以很容易扩展到多维划分的情况,此时词典 V \mathcal{V} V被分为 V = V h ∪ V 1 ∪ … ∪ V J \mathcal{V}= \mathcal{V}_{\rm h} \cup \mathcal{V}_1 \cup \ldots \cup \mathcal{V}_J V=Vh∪V1∪…∪VJ, V i ∩ V j = ∅ \mathcal{V}_i \cap \mathcal{V}_j = \varnothing Vi∩Vj=∅。此时比较好的策略是将所有词按出现频率降序排列,词频高的词分到比较小的簇,簇的大小依次增大(小簇里是词频高的词,大簇里是罕见词)。实验指出簇数在10到15达到最优,但是超过5以后模型ppl(perplexity,困惑度)变化不是很大,因此常用2到5个簇。确定簇数后,每个簇分配多少个单词就可以用动态规划求解
自适应softmax的TF实现可以参考这里
Softmax可以看做是将各个得分归一化的手段,采样法实际上是对归一化时的分母做近似,使用一些其它更容易计算的损失函数。采样法只在训练时可用,推断时仍然需要计算完整的softmax
为了说明上面加粗部分的结论,来看一下损失函数 J θ J_\theta Jθ对参数 θ \theta θ的梯度。通常来讲,多元分类使用交叉熵作为损失函数,即
H ( p , q ) = − ∑ x p ( x ) log q ( x ) H(p, q) = -\sum_x p(x)\log q(x) H(p,q)=−x∑p(x)logq(x)
这里 p ( x ) p(x) p(x)为真实概率分布, q ( x ) q(x) q(x)为近似的概率分布。对于使用softmax获得各单词概率的模型来说, p ( x ) p(x) p(x)就是一个独热向量,该向量中对应应该出现的单词的ID那一行元素为1,其余元素为0; q ( x ) q(x) q(x)是一个概率分布,由softmax得出。因此假设目标单词为 w w w,则损失函数为
J θ = − log exp ( v w ′ T h ) ∑ w i ∈ V exp ( v w i ′ T h ) = − v w ′ T h + log ∑ w i ∈ V exp ( v w i ′ T h ) \begin{aligned} J_\theta &= -\log \frac{\exp(\boldsymbol{v}_w'^\mathsf{T}\boldsymbol{h})}{\sum_{w_i \in V}\exp(\boldsymbol{v}_{w_i}'^\mathsf{T}\boldsymbol{h})}\\ &= -\boldsymbol{v}_w'^\mathsf{T}\boldsymbol{h} + \log \sum_{w_i\in V} \exp(\boldsymbol{v}_{w_i}'^\mathsf{T}\boldsymbol{h}) \end{aligned} Jθ=−log∑wi∈Vexp(vwi′Th)exp(vw′Th)=−vw′Th+logwi∈V∑exp(vwi′Th)
记 − v w ′ T h -\boldsymbol{v}_w'^\mathsf{T}\boldsymbol{h} −vw′Th为 E ( w ) \mathcal{E}(w) E(w),则上式可以重写为
J θ = E ( w ) + log ∑ w i ∈ V exp ( − E ( w i ) ) J_\theta = \mathcal{E}(w) + \log \sum_{w_i \in V}\exp(-\mathcal{E}(w_i)) Jθ=E(w)+logwi∈V∑exp(−E(wi))
求 J θ J_\theta Jθ对 θ \theta θ的偏导,有
∇ θ J θ = ∇ θ E ( w ) + ∇ θ log ∑ w i ∈ V exp ( − E ( w i ) ) = ∇ θ E ( w ) + 1 ∑ w i ∈ V exp ( − E ( w i ) ) ∑ w i ∈ V exp ( − E ( w i ) ) ∇ θ ( − E ( w i ) ) = ∇ θ E ( w ) + ∑ w i ∈ V exp ( − E ( w i ) ) ∑ w j ∈ V exp ( − E ( w j ) ) ∇ θ ( − E ( w i ) ) \begin{aligned} \nabla_\theta J_\theta &= \nabla_\theta\mathcal{E}(w) + \nabla_\theta\log\sum_{w_i \in V}\exp(-\mathcal{E}(w_i))\\ &= \nabla_\theta\mathcal{E}(w) + \frac{1}{\sum_{w_i \in V}\exp(-\mathcal{E}(w_i))}\sum_{w_i\in V}\exp(-\mathcal{E}(w_i))\nabla_\theta(-\mathcal{E}(w_i)) \\ &= \nabla_\theta\mathcal{E}(w) + \sum_{w_i \in V}\frac{\exp(-\mathcal{E}(w_i))}{\sum_{w_j \in V}\exp(-\mathcal{E}(w_j))}\nabla_\theta(-\mathcal{E}(w_i)) \end{aligned} ∇θJθ=∇θE(w)+∇θlogwi∈V∑exp(−E(wi))=∇θE(w)+∑wi∈Vexp(−E(wi))1wi∈V∑exp(−E(wi))∇θ(−E(wi))=∇θE(w)+wi∈V∑∑wj∈Vexp(−E(wj))exp(−E(wi))∇θ(−E(wi))
注意到求和项内部梯度的系数其实就是 w i w_i wi的softmax概率,因此将其写作 P ( w i ) P(w_i) P(wi),有
∇ θ J θ = ∇ θ E ( w ) + ∑ w i ∈ V P ( w i ) ∇ θ ( − E ( w i ) ) = ∇ θ E ( w ) − ∑ w i ∈ V P ( w i ) ∇ θ E ( w i ) \begin{aligned} \nabla_\theta J_\theta &= \nabla_\theta \mathcal{E}(w) + \sum_{w_i \in V}P(w_i)\nabla_\theta (-\mathcal{E}(w_i)) \\ &= \nabla_\theta \mathcal{E}(w) - \sum_{w_i \in V}P(w_i)\nabla_\theta \mathcal{E}(w_i) \end{aligned} ∇θJθ=∇θE(w)+wi∈V∑P(wi)∇θ(−E(wi))=∇θE(w)−wi∈V∑P(wi)∇θE(wi)
因此梯度可以分为两部分,第一部分是增强目标单词 w w w,第二部分是削弱非目标单词 w i w_i wi。后者又可以写作
∑ w i ∈ V P ( w i ) ∇ θ E ( w i ) = E w i ∼ P [ ∇ θ E ( w i ) ] \sum_{w_i \in V}P(w_i)\nabla_\theta\mathcal{E}(w_i) = \mathbb{E}_{w_i \sim P}[\nabla_\theta\mathcal{E}(w_i)] wi∈V∑P(wi)∇θE(wi)=Ewi∼P[∇θE(wi)]
因此所有的抽样法实际上都是在求上项的近似值,以避免算 V V V中所有单词 w i w_i wi的概率
[Ruder2016]调研了若干种基于采样法的工作,本文主要介绍两项:重要性采样法(Importance Sampling,简称IS)和噪声对比估计(Noice Contrastive Estimation,简称NCE)。另一个重要的方法是负采样,在本系列博客中已经提到很多次,这里就不赘述了。不过需要注意的是,负采样可以看作是NCE的一个简化版本
如果知道前面提到的单词分布 P P P,那么就可以从该分布中抽样 m m m个单词,计算近似期望(蒙特卡罗法)
E w i ∼ P [ ∇ θ E ( w i ) ] ≈ 1 m ∑ i = 1 m ∇ θ E ( w i ) \mathbb{E}_{w_i \sim P}[\nabla_\theta\mathcal{E}(w_i)] \approx \frac{1}{m}\sum_{i=1}^m\nabla_\theta\mathcal{E}(w_i) Ewi∼P[∇θE(wi)]≈m1i=1∑m∇θE(wi)
但是根据前面的分析,要避免计算每个单词的softmax分布,所以退而求其次,需要找到一个替代的分布 Q Q Q,使得该分布容易获得,而且最好接近 P P P。常用的分布 Q Q Q是训练集中的单词词频。进一步,还可以用另一个近似来避免对抽样到的 w w w计算 P ( w ) P(w) P(w)。此时,计算 1 / R ⋅ r ( w i ) 1/R \cdot r(w_i) 1/R⋅r(wi)来避免计算 P ( w i ) P(w_i) P(wi),其中
r ( w ) = exp ( − E ( w ) ) Q ( w ) ; R = ∑ j = 1 m r ( w j ) \begin{aligned} r(w) &= \frac{\exp(-\mathcal{E}(w))}{Q(w)};\ \ \ R = \sum_{j=1}^m r(w_j) \end{aligned} r(w)=Q(w)exp(−E(w)); R=j=1∑mr(wj)
综上,有
E w i ∼ P [ ∇ θ E ( w i ) ] ≈ 1 R ∑ r = 1 m r ( w i ) ∇ θ E ( w i ) \mathbb{E}_{w_i \sim P}[\nabla_\theta\mathcal{E}(w_i)] \approx \frac{1}{R}\sum_{r=1}^mr(w_i)\nabla_\theta\mathcal{E}(w_i) Ewi∼P[∇θE(wi)]≈R1r=1∑mr(wi)∇θE(wi)
需要注意的是,样本数越少,近似效果越差
关于IS法的详细内容,可以参考[Bengio2003a]
IS法的一个潜在风险是近似分布 Q Q Q有可能偏离真实分布 P P P,而NCE[Gutmann2010] [Mnih2012]则不再直接估计某个词的概率,而是使用了另一种损失函数做辅助。其核心思想是将目标单词从噪声中区分开,因此模型训练过程变成了求解一个二元分类问题。假设每个目标单词 w i w_i wi的语境 c i c_i ci由 n n n个上文单词 w t − 1 , … , w t − n + 1 w_{t-1}, \ldots, w_{t-n+1} wt−1,…,wt−n+1组成(注意原始NCE论文没有考虑单词下文), k k k个噪声单词 w ~ i k \tilde{w}_{ik} w~ik来自于噪声分布 Q Q Q(这里也使用一元词频),则类别 y = 1 y=1 y=1说明给定 c i c_i ci得到 w i w_i wi,类别 y = 0 y=0 y=0说明给定 c i c_i ci得到 w ~ i k \tilde{w}_{ik} w~ik。损失函数为
J θ = − ∑ w i ∈ V ( log P ( y = 1 ∣ w i , c i ) + k E w ~ i k ∼ Q [ log P ( y = 0 ∣ w ~ i j , c j ) ] ) J_\theta = -\sum_{w_i \in V}\left(\log P(y=1|w_i, c_i) + k\mathbb{E}_{\tilde{w}_{ik}\sim Q}[\log P(y=0|\tilde{w}_{ij}, c_j)]\right) Jθ=−wi∈V∑(logP(y=1∣wi,ci)+kEw~ik∼Q[logP(y=0∣w~ij,cj)])
使用蒙特卡洛模拟来计算期望,上式可化为
J θ = − ∑ w i ∈ V ( log P ( y = 1 ∣ w i , c i ) + k ∑ j = 1 k 1 k log P ( y = 0 ∣ w ~ i j , c j ) ) = − ∑ w i ∈ V ( log P ( y = 1 ∣ w i , c i ) + ∑ j = 1 k log P ( y = 0 ∣ w ~ i j , c j ) ) \begin{aligned} J_\theta &= -\sum_{w_i \in V}\left(\log P(y=1|w_i, c_i) + k\sum_{j=1}^k\frac{1}{k}\log P(y=0|\tilde{w}_{ij}, c_j)\right) \\ &= -\sum_{w_i \in V}\left(\log P(y=1|w_i, c_i) + \sum_{j=1}^k\log P(y=0|\tilde{w}_{ij}, c_j)\right) \end{aligned} Jθ=−wi∈V∑(logP(y=1∣wi,ci)+kj=1∑kk1logP(y=0∣w~ij,cj))=−wi∈V∑(logP(y=1∣wi,ci)+j=1∑klogP(y=0∣w~ij,cj))
由于正确单词是从训练集的经验分布 P t r a i n P_{\rm train} Ptrain中取得且依赖于语境 c c c,噪声来自于分布 Q Q Q,因此给定语境 c c c,取样到一个单词的概率为
P ( y , w ∣ c ) = 1 k + 1 P t r a i n ( w ∣ c ) + k k + 1 Q ( w ) P(y,w|c) = \frac{1}{k+1}P_{\rm train}(w|c) + \frac{k}{k+1}Q(w) P(y,w∣c)=k+11Ptrain(w∣c)+k+1kQ(w)
若某个单词被抽中,则其为正确样本的条件概率为
P ( y = 1 ∣ w , c ) = 1 k + 1 P t r a i n ( w ∣ c ) 1 k + 1 P t r a i n ( w ∣ c ) + k k + 1 Q ( w ) = P t r a i n ( w ∣ c ) P t r a i n ( w ∣ c ) + k Q ( w ) \begin{aligned} P(y=1|w, c) &= \frac{\frac{1}{k+1}P_{\rm train}(w|c) }{\frac{1}{k+1}P_{\rm train}(w|c) + \frac{k}{k+1}Q(w)} \\ &= \frac{P_{\rm train}(w|c)}{P_{\rm train}(w|c) + kQ(w)} \end{aligned} P(y=1∣w,c)=k+11Ptrain(w∣c)+k+1kQ(w)k+11Ptrain(w∣c)=Ptrain(w∣c)+kQ(w)Ptrain(w∣c)
由于 P t r a i n ( w ∣ c ) P_{\rm train}(w|c) Ptrain(w∣c)为未知量,可以将其替为模型概率 P ( w ∣ c ) P(w|c) P(w∣c),而显然
P ( w ∣ c ) = exp ( v w ′ T h ) ∑ w i ∈ V exp ( v w i ′ T h ) P(w|c) = \frac{\exp(\boldsymbol{v}_w'^\mathsf{T}\boldsymbol{h})}{\sum_{w_i \in V}\exp(\boldsymbol{v}_{w_i}'^\mathsf{T}\boldsymbol{h})} P(w∣c)=∑wi∈Vexp(vwi′Th)exp(vw′Th)
似乎又回到了原来的老问题,但是NCE直接将分母置为1!(更保守的做法是将分母设为一个可学习的参数,但是有研究发现学到的分母通常也都接近于1,而且方差不大)。这样,就可以直接说 P ( w ∣ c ) = exp ( v w ′ T h ) P(w|c) = \exp(\boldsymbol{v}_w'^\mathsf{T}\boldsymbol{h}) P(w∣c)=exp(vw′Th),所以
P ( y = 1 ∣ w , c ) = exp ( v w ′ T h ) exp ( v w ′ T h ) + k Q ( w ) P(y=1|w,c) = \frac{\exp(\boldsymbol{v}_w'^\mathsf{T}\boldsymbol{h})}{\exp(\boldsymbol{v}_w'^\mathsf{T}\boldsymbol{h}) + kQ(w)} P(y=1∣w,c)=exp(vw′Th)+kQ(w)exp(vw′Th)
由于要求解的是一个二分类问题,因此 P ( y = 0 ∣ w , c ) = 1 − P ( y = 1 ∣ w , c ) P(y=0|w, c) = 1-P(y=1|w,c) P(y=0∣w,c)=1−P(y=1∣w,c)。将上述结论代入 J θ J_\theta Jθ,可得到最终的NCE损失函数
J θ = − ∑ w i ∈ V [ log exp ( v w i ′ T h ) exp ( v w i ′ T h ) + k Q ( w i ) + ∑ j = 1 k log ( 1 − exp ( v w ~ i j ′ T h ) exp ( v w ~ i j ′ T h ) + k Q ( w ~ i j ) ) ] J_\theta= -\sum_{w_i \in V}\left[\log \frac{\exp(\boldsymbol{v}_{w_i}'^\mathsf{T}\boldsymbol{h})}{\exp(\boldsymbol{v}_{w_i}'^\mathsf{T}\boldsymbol{h})+kQ(w_i)} + \sum_{j=1}^k\log\left(1-\frac{\exp\left(\boldsymbol{v}_{\tilde{w}_{ij}}'^\mathsf{T}\boldsymbol{h}\right)}{\exp\left(\boldsymbol{v}_{\tilde{w}_{ij}}'^\mathsf{T}\boldsymbol{h}\right) + kQ(\tilde{w}_{ij})}\right)\right] Jθ=−wi∈V∑⎣⎡logexp(vwi′Th)+kQ(wi)exp(vwi′Th)+j=1∑klog⎝⎛1−exp(vw~ij′Th)+kQ(w~ij)exp(vw~ij′Th)⎠⎞⎦⎤
有理论证明,当NCE中噪声样本数量 k k k变大时,NCE损失函数的梯度会逼近于softmax函数的梯度
[Jozefowicz2016]论证了IS实际上是优化一个多类别分类问题(NCE是二分类),因此更适合于语言建模。当NCE使用的 k = ∣ V ∣ k=|V| k=∣V∣且 Q Q Q为均匀分布时(此时 k Q ( w ) = 1 kQ(w) = 1 kQ(w)=1),NCE退化成负采样
(原计划在本文里还跟进Ruder词向量系列博客的第三部:On word embeddings - Part 3: The secret ingredients of word2vec,该文章讨论了一些词向量的理论解释,但是比较抽象,数学内容更多,因此暂时就不介绍了。有兴趣的可以移步上面的链接阅读原文,或者参考[Levy2015] [Levy2014])
[Lai2016]讨论了一些训练词向量的细节,包括模型搭建、训练语料、参数设计等方面。文章调查的工作包括
所有训练词向量的方法基本都依赖于一条分布式假设:出现在相似上下文的单词有相同意思。因此,文章调研的建模方法实际上都是在对目标单词 w w w和上下文 c c c之间的关系建模,不同模型的区别主要体现在 (1) 如何建模目标单词和上下文之间的关系 (2) 如何表示上下文。对于前者,大部分模型都是用给定上下文预测中心词(注意,从这个角度看,skipgram也可以看作是用上下文预测中心词,只不过此时“中心词”是滑动的),而C&W是建模 ( c , w ) (c, w) (c,w)的分数。对于后者,word2vec没有考虑上下文的词序,而其它工作均将上下文单词词向量按序拼接,有的还加入了隐藏层来获取更强的建模能力
文章使用了三类共八项任务来评估词向量模型,包括
最后得到如下结论
对于模型来说,从目标单词与上下文之间关系的角度看,训练时只建模 ( c , w ) (c, w) (c,w)分数的C&W不太容易捕捉词义相加和相减的关系,因此使用上下文预测目标单词的模型效果更好。从上下文表示的角度看,数据量小时,简单的模型效果更好(例如CBOW在训练语料单词量级为千万或亿时效果很好),但是语料量更大时,复杂的模型更好
如果要用词向量初始化其他任务需要的网络,或者作为特征,结论是不同词向量模型影响不是很大,此时简单的模型就足够了
对于训练语料来说,同领域下,语料量越大,得到的词向量效果越好。不同领域下语料训练出的词向量变化会非常大,例如IMDB语料训出的词向量里,与"movie"相近的词包括了"this"、"it"等,说明在这个语料里movie这个词相当于是一个停用词
文章做了一个比较有趣的实验:对于avg任务,使用纯IMDB语料训练词向量,加权作为特征,然后向训练词向量用的语料里逐渐加入wiki与纽约时报的语料,重新训练词向量,观察新特征对模型的影响。实验表明,混杂的语料总是不如纯净的IMDB语料,因此语料领域比语料数量影响大得多
训练词向量应该训练多少轮?实验表明使用训练词向量时对应的验证集意义不大,最好的选择是用一个简单的任务(例如前面介绍的tfl任务)来做验证。如果训练词向量是为了一个特定的任务,那么应该使用该任务对应的验证集来验证词向量效果,不过这个过程可能比较费时间。此外,对于NLP任务,50维的词向量就可以达到不错的效果
[Rong2014] Rong, X. (2014). word2vec parameter learning explained. arXiv preprint arXiv:1411.2738.
[Ruder2016] Ruder, S. (2016). On Word Embeddinngs - Part 2: Approximating the Softmax
[Chen2016] Chen, W., Grangier, D., & Auli, M. (2016). Strategies for Training Large Vocabulary Neural Language Models. In Proceedings of the 54th Annual Meeting of the Association for Computational Linguistics (Volume 1: Long Papers) (ACL2016) (Vol. 1, pp. 1975-1985).
[Jozefowicz2016] Jozefowicz, R., Vinyals, O., Schuster, M., Shazeer, N., & Wu, Y. (2016). Exploring the limits of language modeling. arXiv preprint arXiv:1602.02410.
[Grave2017] Grave, E., Joulin, A., Cissé, M., & Jégou, H. (2017, August). Efficient softmax approximation for GPUs. In Proceedings of the 34th International Conference on Machine Learning-Volume 70 (ICML 2017) (pp. 1302-1310).
[Bengio2003a] Bengio, Y., & Senécal, J. S. (2003, January). Quick Training of Probabilistic Neural Nets by Importance Sampling. In AISTATS (pp. 1-9).
[Gutmann2010] Gutmann, M., & Hyvärinen, A. (2010, March). Noise-contrastive estimation: A new estimation principle for unnormalized statistical models. In Proceedings of the Thirteenth International Conference on Artificial Intelligence and Statistics (pp. 297-304).
[Mnih2012] Mnih, A., & Teh, Y. W. (2012). A fast and simple algorithm for training neural probabilistic language models. In Proceedings of the 29th International Conference on Machine Learning, ICML 2012 (Vol. 2, pp. 1751-1758).
[Levy2015] Levy, O., Goldberg, Y., & Dagan, I. (2015). Improving distributional similarity with lessons learned from word embeddings. Transactions of the Association for Computational Linguistics, 3, 211-225.
[Levy2014] Levy, O., & Goldberg, Y. (2014). Neural word embedding as implicit matrix factorization. In Advances in neural information processing systems, NeurIPS 2014 (pp. 2177-2185).
[Lai2016] Lai, S., Liu, K., He, S., & Zhao, J. (2016). How to generate a good word embedding. IEEE Intelligent Systems, 31(6), 5-14.
[Bengio2003b] Bengio, Y., Ducharme, R., Vincent, P., & Jauvin, C. (2003). A neural probabilistic language model. Journal of machine learning research, 3(Feb), (JMLR) (pp. 1137-1155).
[Mnih2007] Mnih, A., & Hinton, G. (2007, June). Three new graphical models for statistical language modelling. In Proceedings of the 24th international conference on Machine learning, ICML 2007 (pp. 641-648). ACM.
[Collobert2008] Collobert, R., & Weston, J. (2008, July). A unified architecture for natural language processing: Deep neural networks with multitask learning. In Proceedings of the 25th international conference on Machine learning, ICML 2008 (pp. 160-167). ACM.
[Mikolov2013] Mikolov, T., Chen, K., Corrado, G., & Dean, J. (2013). Efficient estimation of word representations in vector space. arXiv preprint arXiv:1301.3781.
[Pennington2014] Pennington, J., Socher, R., & Manning, C. (2014). Glove: Global vectors for word representation. In Proceedings of the 2014 conference on empirical methods in natural language processing ,EMNLP 2014 (pp. 1532-1543).