在自然语言处理(NLP,natural language processing)中,词是表义的基本单元,把词映射为实数域向量的技术叫词嵌入(word embedding),通过词嵌入我们就可以对词进行更高层次的研究。
one-hot representation 的弊端
虽然one-hot词向量构造起来很容易,但通常并不是一个好选择。最大的问题是,词汇表一般都非常大,比如达到百万级别,这样每个词都用百万维的向量来表示简直是内存的灾难。这样的向量其实除了一个位置是1,其余的位置全部都是0,表达的效率不高。另外一个问题是,one-hot词向量无法准确表达不同词之间的相似度,如我们常常使用的余弦相似度。因为任何两个不同词的one-hot向量的余弦相似度都为0,多个不同词之间的相似度难以通过one-hot向量准确地体现出来。
word2vec工具的提出正是为了解决上述的问题。值得注意的是,word2vec不是一个模型,而是一种工具,包含了两个模型,即跳字模型(skip-gram) 和连续词袋模型(continuous bag of words,CBOW)。它将每个词表示成一个定长的向量,并使得这些向量能较好地表达不同词之间的相似和类比关系。在word2vec中还提到两种高效训练的方法:负采样(negative sampling) 和层序softmax (hierarchical softmax)。
skip-gram
skip-gram是基于某个词(中心词)来生成它在文本序列周围的词(背景词)。网络结构如下:

假设文本序列是“the” “man” “loves” “his” “son”。以“loves”作为中心词,设背景窗口大小为2。给定中心词“loves”,生成与它距离不超过2个词的背景词“the”“man”“his”“son”的条件概率,即
P ( “the" , “man" , “his" , “son" ∣ “loves" ) (1) P(\textrm{``the"},\textrm{``man"},\textrm{``his"},\textrm{``son"}\mid\textrm{``loves"}) \tag{1} P(“the",“man",“his",“son"∣“loves")(1)
假设给定中心词的情况下,背景词的生成是相互独立的,那么上式可以改写成
P ( “the" ∣ “loves" ) ⋅ P ( “man" ∣ “loves" ) ⋅ P ( “his" ∣ “loves" ) ⋅ P ( “son" ∣ “loves" ) (2) P(\textrm{``the"}\mid\textrm{``loves"})\cdot P(\textrm{``man"}\mid\textrm{``loves"})\cdot P(\textrm{``his"}\mid\textrm{``loves"})\cdot P(\textrm{``son"}\mid\textrm{``loves"}) \tag{2} P(“the"∣“loves")⋅P(“man"∣“loves")⋅P(“his"∣“loves")⋅P(“son"∣“loves")(2)
设中心词 w c w_c wc在词典中索引为 c c c,对应的中心词向量表示为 v c \boldsymbol{v}_c vc,背景词 w o w_o wo在词典中索引为 o o o,对应的背景词向量表示为 u o \boldsymbol{u}_o uo,给定中心词生成背景词的条件概率可以通过对向量内积(内积表示余弦相似度)做 softmax 运算而得到:
P ( w o ∣ w c ) = exp ( u o ⊤ v c ) ∑ i ∈ V exp ( u i ⊤ v c ) , (3) P(w_o \mid w_c) = \frac{\text{exp}(\boldsymbol{u}_o^\top \boldsymbol{v}_c)}{ \sum_{i \in \mathcal{V}} \text{exp}(\boldsymbol{u}_i^\top \boldsymbol{v}_c)}, \tag{3} P(wo∣wc)=∑i∈Vexp(ui⊤vc)exp(uo⊤vc),(3)
其中词典索引集 V = { 0 , 1 , … , ∣ V ∣ − 1 } \mathcal{V} = \{0, 1, \ldots, |\mathcal{V}|-1\} V={0,1,…,∣V∣−1}。假设给定一个长度为 T T T的文本序列,设时间步 t t t的词为 w ( t ) w^{(t)} w(t)。假设给定中心词的情况下背景词的生成相互独立,当背景窗口大小为 m m m时,skip-gram模型的似然函数,即给定任一中心词生成所有背景词的概率:
∏ t = 1 T ∏ − m ≤ j ≤ m , j ≠ 0 P ( w ( t + j ) ∣ w ( t ) ) , (4) \prod_{t=1}^{T} \prod_{-m \leq j \leq m,\ j \neq 0} P(w^{(t+j)} \mid w^{(t)}), \tag{4} t=1∏T−m≤j≤m, j=0∏P(w(t+j)∣w(t)),(4)
这里小于1或大于 T T T 的时间步可以被忽略。所求参数是中心词向量和背景词向量,求最大似然函数即可学习模型的参数。这等价于最小化以下损失函数:
− 1 T ∑ t = 1 T ∑ − m ≤ j ≤ m , j ≠ 0 log P ( w ( t + j ) ∣ w ( t ) ) , (5) -\frac1T \sum_{t=1}^{T} \sum_{-m \leq j \leq m,\ j \neq 0} \text{log}\, P(w^{(t+j)} \mid w^{(t)}), \tag{5} −T1t=1∑T−m≤j≤m, j=0∑logP(w(t+j)∣w(t)),(5)
即似然函数对数化,然后除以 T T T 。
使用随机梯度下降,即每一次迭代里随机采样一个较短的子序列来计算有关该子序列的损失,然后计算梯度来更新模型参数。梯度计算的关键是条件概率的对数有关中心词向量和背景词向量的梯度。根据定义,首先:
log P ( w o ∣ w c ) = log exp ( u o ⊤ v c ) ∑ i ∈ V exp ( u i ⊤ v c ) = u o ⊤ v c − log ( ∑ i ∈ V exp ( u i ⊤ v c ) ) (6) \log P(w_o \mid w_c) = \log\frac{\text{exp}(\boldsymbol{u}_o^\top \boldsymbol{v}_c)}{ \sum_{i \in \mathcal{V}} \text{exp}(\boldsymbol{u}_i^\top \boldsymbol{v}_c)}= \boldsymbol{u}_o^\top \boldsymbol{v}_c - \log\left(\sum_{i \in \mathcal{V}} \text{exp}(\boldsymbol{u}_i^\top \boldsymbol{v}_c)\right) \tag{6} logP(wo∣wc)=log∑i∈Vexp(ui⊤vc)exp(uo⊤vc)=uo⊤vc−log(i∈V∑exp(ui⊤vc))(6)
通过微分,我们可以得到上式中 v c \boldsymbol{v}_c vc的梯度:
∂ log P ( w o ∣ w c ) ∂ v c = u o − ∑ j ∈ V exp ( u j ⊤ v c ) u j ∑ i ∈ V exp ( u i ⊤ v c ) = u o − ∑ j ∈ V ( exp ( u j ⊤ v c ) ∑ i ∈ V exp ( u i ⊤ v c ) ) u j = u o − ∑ j ∈ V P ( w j ∣ w c ) u j . (7) \begin{aligned} \frac{\partial \text{log}\, P(w_o \mid w_c)}{\partial \boldsymbol{v}_c} &= \boldsymbol{u}_o - \frac{\sum_{j \in \mathcal{V}} \exp(\boldsymbol{u}_j^\top \boldsymbol{v}_c)\boldsymbol{u}_j}{\sum_{i \in \mathcal{V}} \exp(\boldsymbol{u}_i^\top \boldsymbol{v}_c)}\\ &= \boldsymbol{u}_o - \sum_{j \in \mathcal{V}} \left(\frac{\text{exp}(\boldsymbol{u}_j^\top \boldsymbol{v}_c)}{ \sum_{i \in \mathcal{V}} \text{exp}(\boldsymbol{u}_i^\top \boldsymbol{v}_c)}\right) \boldsymbol{u}_j\\ &= \boldsymbol{u}_o - \sum_{j \in \mathcal{V}} P(w_j \mid w_c) \boldsymbol{u}_j. \end{aligned} \tag{7} ∂vc∂logP(wo∣wc)=uo−∑i∈Vexp(ui⊤vc)∑j∈Vexp(uj⊤vc)uj=uo−j∈V∑(∑i∈Vexp(ui⊤vc)exp(uj⊤vc))uj=uo−j∈V∑P(wj∣wc)uj.(7)
通过上式可以发现,skip-gram模型的计算需要词典中所有词以 w c w_c wc 为中心词的条件概率。显然,运算量是非常巨大的。接下来的CBOW模型也存在相似的问题,word2vec工具提供两种高效训练的方法:负采样(negative sampling) 和层序 softmax (hierarchical softmax),这里暂不做讨论,将在后面一起分析。
训练结束后,对于词典中的任一索引为 i i i 的词,我们均得到该词作为中心词和背景词的两组词向量 v i \boldsymbol{v}_i vi 和 u i \boldsymbol{u}_i ui 。在NLP中,一般使用skip-gram模型的中心词向量作为词的表征向量。
CBOW
CBOW和skip-gram恰好相反,它是基于某中心词在文本序列前后的背景词来生成该中心词,网络结构为:

根据skip-gram模型的例子,即:
P ( “loves" ∣ “the" , “man" , “his" , “son" ) (8) P(\textrm{``loves"}\mid\textrm{``the"},\textrm{``man"},\textrm{``his"},\textrm{``son"}) \tag{8} P(“loves"∣“the",“man",“his",“son")(8)
设中心词 w c w_c wc 在词典中索引为 c c c,对应的中心词向量表示为 u c \boldsymbol{u}_c uc ,背景词 w o 1 , … , w o 2 m w_{o_1}, \ldots, w_{o_{2m}} wo1,…,wo2m 在词典中索引为 o 1 , … , o 2 m o_1, \ldots, o_{2m} o1,…,o2m,对应的背景词向量表示为 v o 1 , … , v o 2 m \boldsymbol{v}_{o_1}, \ldots, \boldsymbol{v}_{o_{2m}} vo1,…,vo2m 。因为背景词有多个,在这里,为了计算简便,word2vec没有使用上图神经网络输入层到隐藏层的映射,而是直接求输入词向量的平均值,将这些背景词向量求平均,那么给定背景词生成中心词的条件概率:
P ( w c ∣ w o 1 , … , w o 2 m ) = exp ( 1 2 m u c ⊤ ( v o 1 + … + v o 2 m ) ) ∑ i ∈ V exp ( 1 2 m u i ⊤ ( v o 1 + … + v o 2 m ) ) (9) P(w_c \mid w_{o_1}, \ldots, w_{o_{2m}}) = \frac{\text{exp}\left(\frac{1}{2m}\boldsymbol{u}_c^\top (\boldsymbol{v}_{o_1} + \ldots + \boldsymbol{v}_{o_{2m}}) \right)}{ \sum_{i \in \mathcal{V}} \text{exp}\left(\frac{1}{2m}\boldsymbol{u}_i^\top (\boldsymbol{v}_{o_1} + \ldots + \boldsymbol{v}_{o_{2m}}) \right)} \tag{9} P(wc∣wo1,…,wo2m)=∑i∈Vexp(2m1ui⊤(vo1+…+vo2m))exp(2m1uc⊤(vo1+…+vo2m))(9)
为了让符号更加简单,我们记 W o = { w o 1 , … , w o 2 m } \mathcal{W}_o= \{w_{o_1}, \ldots, w_{o_{2m}}\} Wo={wo1,…,wo2m},且 v ˉ o = ( v o 1 + … + v o 2 m ) / ( 2 m ) \bar{\boldsymbol{v}}_o = \left(\boldsymbol{v}_{o_1} + \ldots + \boldsymbol{v}_{o_{2m}} \right)/(2m) vˉo=(vo1+…+vo2m)/(2m),那么上式可以简写成:
P ( w c ∣ W o ) = exp ( u c ⊤ v ˉ o ) ∑ i ∈ V exp ( u i ⊤ v ˉ o ) (10) P(w_c \mid \mathcal{W}_o) = \frac{\exp\left(\boldsymbol{u}_c^\top \bar{\boldsymbol{v}}_o\right)}{\sum_{i \in \mathcal{V}} \exp\left(\boldsymbol{u}_i^\top \bar{\boldsymbol{v}}_o\right)} \tag{10} P(wc∣Wo)=∑i∈Vexp(ui⊤vˉo)exp(uc⊤vˉo)(10)
给定一个长度为 T T T的文本序列,设时间步 t t t的词为 w ( t ) w^{(t)} w(t),背景窗口大小为 m m m。连续词袋模型的似然函数是由背景词生成任一中心词的概率:
∏ t = 1 T P ( w ( t ) ∣ w ( t − m ) , … , w ( t − 1 ) , w ( t + 1 ) , … , w ( t + m ) ) (11) \prod_{t=1}^{T} P(w^{(t)} \mid w^{(t-m)}, \ldots, w^{(t-1)}, w^{(t+1)}, \ldots, w^{(t+m)}) \tag{11} t=1∏TP(w(t)∣w(t−m),…,w(t−1),w(t+1),…,w(t+m))(11)
训练CBOW模型同训练skip-gram模型基本一致。CBOW模型的最大似然估计等价于最小化损失函数:
− ∑ t = 1 T log P ( w ( t ) ∣ w ( t − m ) , … , w ( t − 1 ) , w ( t + 1 ) , … , w ( t + m ) ) (12) -\sum_{t=1}^T \text{log}\, P(w^{(t)} \mid w^{(t-m)}, \ldots, w^{(t-1)}, w^{(t+1)}, \ldots, w^{(t+m)}) \tag{12} −t=1∑TlogP(w(t)∣w(t−m),…,w(t−1),w(t+1),…,w(t+m))(12)
对于每一个时刻有:
log P ( w c ∣ W o ) = log exp ( u c ⊤ v ˉ o ) ∑ i ∈ V exp ( u i ⊤ v ˉ o ) = u c ⊤ v ˉ o − log ( ∑ i ∈ V exp ( u i ⊤ v ˉ o ) ) (13) \log\,P(w_c \mid \mathcal{W}_o) =\log\frac{\exp\left(\boldsymbol{u}_c^\top \bar{\boldsymbol{v}}_o\right)}{\sum_{i \in \mathcal{V}} \exp\left(\boldsymbol{u}_i^\top \bar{\boldsymbol{v}}_o\right)}= \boldsymbol{u}_c^\top \bar{\boldsymbol{v}}_o - \log\,\left(\sum_{i \in \mathcal{V}} \exp\left(\boldsymbol{u}_i^\top \bar{\boldsymbol{v}}_o\right)\right) \tag{13} logP(wc∣Wo)=log∑i∈Vexp(ui⊤vˉo)exp(uc⊤vˉo)=uc⊤vˉo−log(i∈V∑exp(ui⊤vˉo))(13)
通过微分,可以计算出上式中条件概率的对数有关任一背景词向量 v o i \boldsymbol{v}_{o_i} voi( i = 1 , … , 2 m i = 1, \ldots, 2m i=1,…,2m)的梯度
∂ log P ( w c ∣ W o ) ∂ v o i = 1 2 m ( u c − ∑ j ∈ V exp ( u j ⊤ v ˉ o ) u j ∑ i ∈ V exp ( u i ⊤ v ˉ o ) ) = 1 2 m ( u c − ∑ j ∈ V P ( w j ∣ W o ) u j ) (14) \frac{\partial \log\, P(w_c \mid \mathcal{W}_o)}{\partial \boldsymbol{v}_{o_i}} = \frac{1}{2m} \left(\boldsymbol{u}_c - \sum_{j \in \mathcal{V}} \frac{\exp(\boldsymbol{u}_j^\top \bar{\boldsymbol{v}}_o)\boldsymbol{u}_j}{ \sum_{i \in \mathcal{V}} \text{exp}(\boldsymbol{u}_i^\top \bar{\boldsymbol{v}}_o)} \right) = \frac{1}{2m}\left(\boldsymbol{u}_c - \sum_{j \in \mathcal{V}} P(w_j \mid \mathcal{W}_o) \boldsymbol{u}_j \right) \tag{14} ∂voi∂logP(wc∣Wo)=2m1⎝⎛uc−j∈V∑∑i∈Vexp(ui⊤vˉo)exp(uj⊤vˉo)uj⎠⎞=2m1⎝⎛uc−j∈V∑P(wj∣Wo)uj⎠⎞(14)
同skip-gram模型不一样的一点在于,使用CBOW模型的背景词向量作为词的表征向量(显然是这样)。
negative sampling
上述两个模型都存在同样的问题,在 softmax 处理的过程中都使用了字典中所有的词,使得计算量非常的大。
negative sampling所做的事情就是改变目标函数,准确的说是改变 softmax 操作,给定中心词
w
c
w_c
wc 的一个背景窗口,我们把背景词
w
o
w_o
wo 出现在该背景窗口看作一个事件,并将该事件的概率计算为:
P ( D = 1 ∣ w c , w o ) = σ ( u o ⊤ v c ) , (15) P(D=1\mid w_c, w_o) = \sigma(\boldsymbol{u}_o^\top \boldsymbol{v}_c), \tag{15} P(D=1∣wc,wo)=σ(uo⊤vc),(15)
其中的 σ \sigma σ 函数与sigmoid激活函数的定义相同:
σ ( x ) = 1 1 + exp ( − x ) . (16) \sigma(x) = \frac{1}{1+\exp(-x)}. \tag{16} σ(x)=1+exp(−x)1.(16)
最大化文本序列中所有该事件的联合概率来训练词向量。具体来说,给定一个长度为 T T T的文本序列,设时间步 t t t的词为 w ( t ) w^{(t)} w(t)且背景窗口大小为 m m m,考虑最大化联合概率:
∏ t = 1 T ∏ − m ≤ j ≤ m , j ≠ 0 P ( D = 1 ∣ w ( t ) , w ( t + j ) ) . (17) \prod_{t=1}^{T} \prod_{-m \leq j \leq m,\ j \neq 0} P(D=1\mid w^{(t)}, w^{(t+j)}). \tag{17} t=1∏T−m≤j≤m, j=0∏P(D=1∣w(t),w(t+j)).(17)
对于skip-gram模型举例,模型中包含的事件仅考虑了正类样本,这导致当所有词向量相等且值为无穷大时,以上的联合概率才被最大化为1。很明显,这样的词向量毫无意义。负采样通过采样并添加负类样本使目标函数更有意义。设背景词 w o w_o wo出现在中心词 w c w_c wc的一个背景窗口为事件 P P P,我们根据分布 P ( w ) P(w) P(w)采样 K K K个未出现在该背景窗口中的词,即噪声词。设噪声词 w k w_k wk( k = 1 , … , K k=1, \ldots, K k=1,…,K)不出现在中心词 w c w_c wc的该背景窗口为事件 N k N_k Nk。假设同时含有正类样本和负类样本的事件 P , N 1 , … , N K P, N_1, \ldots, N_K P,N1,…,NK相互独立,负采样将以上需要最大化的仅考虑正类样本的联合概率改写为:
∏ t = 1 T ∏ − m ≤ j ≤ m , j ≠ 0 P ( w ( t + j ) ∣ w ( t ) ) , (18) \prod_{t=1}^{T} \prod_{-m \leq j \leq m,\ j \neq 0} P(w^{(t+j)} \mid w^{(t)}), \tag{18} t=1∏T−m≤j≤m, j=0∏P(w(t+j)∣w(t)),(18)
其中条件概率被近似表示为(省略了分母???):
P ( w ( t + j ) ∣ w ( t ) ) = P ( D = 1 ∣ w ( t ) , w ( t + j ) ) ∏ k = 1 , w k ∼ P ( w ) K P ( D = 0 ∣ w ( t ) , w k ) . (19) P(w^{(t+j)} \mid w^{(t)}) =P(D=1\mid w^{(t)}, w^{(t+j)})\prod_{k=1,\ w_k \sim P(w)}^K P(D=0\mid w^{(t)}, w_k). \tag{19} P(w(t+j)∣w(t))=P(D=1∣w(t),w(t+j))k=1, wk∼P(w)∏KP(D=0∣w(t),wk).(19)
设文本序列中时间步 t t t 的词 w ( t ) w^{(t)} w(t) 在词典中的索引为 i t i_t it,噪声词 w k w_k wk 在词典中的索引为 h k h_k hk。有关以上条件概率的对数损失为:
− log P ( w ( t + j ) ∣ w ( t ) ) = − log P ( D = 1 ∣ w ( t ) , w ( t + j ) ) − ∑ k = 1 , w k ∼ P ( w ) K log P ( D = 0 ∣ w ( t ) , w k ) = − log σ ( u i t + j ⊤ v i t ) − ∑ k = 1 , w k ∼ P ( w ) K log ( 1 − σ ( u h k ⊤ v i t ) ) = − log σ ( u i t + j ⊤ v i t ) − ∑ k = 1 , w k ∼ P ( w ) K log σ ( − u h k ⊤ v i t ) . (20) \begin{aligned} -\log P(w^{(t+j)} \mid w^{(t)}) =& -\log P(D=1\mid w^{(t)}, w^{(t+j)}) - \sum_{k=1,\ w_k \sim P(w)}^K \log P(D=0\mid w^{(t)}, w_k)\\ =&- \log\, \sigma\left(\boldsymbol{u}_{i_{t+j}}^\top \boldsymbol{v}_{i_t}\right) - \sum_{k=1,\ w_k \sim P(w)}^K \log\left(1-\sigma\left(\boldsymbol{u}_{h_k}^\top \boldsymbol{v}_{i_t}\right)\right)\\ =&- \log\, \sigma\left(\boldsymbol{u}_{i_{t+j}}^\top \boldsymbol{v}_{i_t}\right) - \sum_{k=1,\ w_k \sim P(w)}^K \log\sigma\left(-\boldsymbol{u}_{h_k}^\top \boldsymbol{v}_{i_t}\right). \end{aligned} \tag{20} −logP(w(t+j)∣w(t))===−logP(D=1∣w(t),w(t+j))−k=1, wk∼P(w)∑KlogP(D=0∣w(t),wk)−logσ(uit+j⊤vit)−k=1, wk∼P(w)∑Klog(1−σ(uhk⊤vit))−logσ(uit+j⊤vit)−k=1, wk∼P(w)∑Klogσ(−uhk⊤vit).(20)
现在,训练中每一步的梯度计算开销不再与词典大小相关,而与 K K K线性相关。当 K K K取较小的常数时,负采样在每一步的梯度计算开销较小。
hierarchical softmax
hierarchical softmax是另一种近似训练法。它使用了二叉树这一数据结构,树的每个叶结点代表词典 V \mathcal{V} V 中的每个词。

假设 L ( w ) L(w) L(w)为从二叉树的根结点到词 w w w的叶结点的路径(包括根结点和叶结点)上的结点数,这条路径用来评估该叶子节点上单词的概率值。设 n ( w , j ) n(w,j) n(w,j)为该路径上第 j j j个结点,并设该结点的背景词向量为 u n ( w , j ) \boldsymbol{u}_{n(w,j)} un(w,j)。如上图, L ( w 3 ) = 4 L(w_3) = 4 L(w3)=4。hierarchical softmax将skip-gram模型中的条件概率近似表示为:
P ( w o ∣ w c ) = ∏ j = 1 L ( w o ) − 1 σ ( [ [ n ( w o , j + 1 ) = leftChild ( n ( w o , j ) ) ] ] ⋅ u n ( w o , j ) ⊤ v c ) , (21) P(w_o \mid w_c) = \prod_{j=1}^{L(w_o)-1} \sigma\left( [\![ n(w_o, j+1) = \text{leftChild}(n(w_o,j)) ]\!] \cdot \boldsymbol{u}_{n(w_o,j)}^\top \boldsymbol{v}_c\right), \tag{21} P(wo∣wc)=j=1∏L(wo)−1σ([[n(wo,j+1)=leftChild(n(wo,j))]]⋅un(wo,j)⊤vc),(21)
其中 σ \sigma σ函数就是sigmoid激活函数, [ [ n ( w o , j + 1 ) = leftChild ( n ( w o , j ) ) ] ] [\![ n(w_o, j+1) = \text{leftChild}(n(w_o,j)) ]\!] [[n(wo,j+1)=leftChild(n(wo,j))]]表示判断结点 n ( w o , j + 1 ) n(w_o, j+1) n(wo,j+1)是否是左子节点, 即 leftChild ( n ) \text{leftChild}(n) leftChild(n)是结点 n n n的左子结点:如果判断 x x x为真, [ [ x ] ] = 1 [\![x]\!] = 1 [[x]]=1;反之 [ [ x ] ] = − 1 [\![x]\!] = -1 [[x]]=−1。
尝试计算图中给定词 w c w_c wc生成词 w 3 w_3 w3的条件概率。我们需要将 w c w_c wc的词向量 v c \boldsymbol{v}_c vc和根结点到 w 3 w_3 w3路径上的非叶结点向量一一求内积。由于在二叉树中由根结点到叶结点 w 3 w_3 w3的路径上需要向左、向右再向左地遍历(图中加粗的路径),我们得到:
P ( w 3 ∣ w c ) = σ ( u n ( w 3 , 1 ) ⊤ v c ) ⋅ σ ( − u n ( w 3 , 2 ) ⊤ v c ) ⋅ σ ( u n ( w 3 , 3 ) ⊤ v c ) . (22) P(w_3 \mid w_c) = \sigma(\boldsymbol{u}_{n(w_3,1)}^\top \boldsymbol{v}_c) \cdot \sigma(-\boldsymbol{u}_{n(w_3,2)}^\top \boldsymbol{v}_c) \cdot \sigma(\boldsymbol{u}_{n(w_3,3)}^\top \boldsymbol{v}_c). \tag{22} P(w3∣wc)=σ(un(w3,1)⊤vc)⋅σ(−un(w3,2)⊤vc)⋅σ(un(w3,3)⊤vc).(22)
由于 σ ( x ) + σ ( − x ) = 1 \sigma(x)+\sigma(-x) = 1 σ(x)+σ(−x)=1,给定中心词 w c w_c wc 生成词典 V \mathcal{V} V 中任一词的条件概率之和为1这一条件也将满足:
∑ w ∈ V P ( w ∣ w c ) = 1. (23) \sum_{w \in \mathcal{V}} P(w \mid w_c) = 1. \tag{23} w∈V∑P(w∣wc)=1.(23)
此外,由于 L ( w o ) − 1 L(w_o)-1 L(wo)−1的数量级为 O ( log 2 ∣ V ∣ ) \mathcal{O}(\text{log}_2|\mathcal{V}|) O(log2∣V∣),当词典 V \mathcal{V} V很大时,层序softmax在训练中每一步的梯度计算开销相较未使用近似训练时大幅降低。
在word2vec中,通常构建哈夫曼(Huffman)树,得到霍夫曼树后对叶子节点进行霍夫曼编码(Huffman Coding),由于权重高的叶子节点越靠近根节点,而权重低的叶子节点会远离根节点,这样我们的高权重节点编码值较短,而低权重值编码值较长。这保证的树的带权路径最短,也符合我们的信息论,即我们希望越常用的词拥有更短的编码。约定左子树编码为1,右子树编码为0,同时约定左子树的权重不小于右子树的权重。
hierarchical softmax为了避免要计算所有词的softmax概率,word2vec采样了霍夫曼树来代替从隐藏层到输出softmax层的映射。和之前的神经网络语言模型相比,霍夫曼树的所有内部节点类似之前神经网络隐藏层的神经元。其中,根节点的词向量对应投影后的词向量,而所有叶子节点就类似于之前神经网络 softmax 输出层的神经元,叶子节点的个数就是词汇表的大小。在霍夫曼树中,隐藏层到输出层的softmax映射不是一下子完成的,而是沿着霍夫曼树一步步完成的,因此这种softmax取名为"Hierarchical Softmax"。在word2vec中,采用了二元逻辑回归的方法,即规定沿着左子树走,那么就是负类(霍夫曼树编码1),沿着右子树走,那么就是正类(霍夫曼树编码0)。判别正类和负类的方法是使用sigmoid函数,即:
P ( + ) = σ ( u n ( w , j ) T θ ) = 1 1 + e − u n ( w , j ) T θ P(+) = \sigma(\boldsymbol{u}_{n(w,j)}^T\theta) = \frac{1}{1+e^{-\boldsymbol{u}_{n(w,j)}^T\theta}} P(+)=σ(un(w,j)Tθ)=1+e−un(w,j)Tθ1
其中, u n ( w , j ) \boldsymbol{u}_{n(w,j)} un(w,j)是当前内部节点的词向量,而 θ \theta θ 是我们需要从训练样本求出的逻辑回归的模型参数。
使用霍夫曼树有什么好处呢?首先,由于是二叉树,之前计算量为 V V V,现在变成了 l o g 2 V log2V log2V。第二,由于使用霍夫曼树是高频的词靠近树根,这样高频词需要更少的时间会被找到,这符合我们的贪心优化思想。
使用最大似然法来寻找所有节点的词向量和所有内部节点 θ \theta θ。先拿上面的 w 2 w_2 w2例子来看,我们期望最大化下面的似然函数:
∏ i = 1 3 P ( n ( w i ) , i ) = ( 1 − 1 1 + e − u n ( w , 1 ) T θ 1 ) ( 1 − 1 1 + e − u n ( w , 2 ) T θ 2 ) 1 1 + e − u n ( w , 3 ) T θ 3 \prod_{i=1}^3P(n(w_i),i) = (1- \frac{1}{1+e^{-\boldsymbol{u}_{n(w,1)}^T\theta_1}})(1- \frac{1}{1+e^{-\boldsymbol{u}_{n(w,2)}^T\theta_2}})\frac{1}{1+e^{-\boldsymbol{u}_{n(w,3)}^T\theta_3}} i=1∏3P(n(wi),i)=(1−1+e−un(w,1)Tθ11)(1−1+e−un(w,2)Tθ21)1+e−un(w,3)Tθ31
对于所有的训练样本,我们期望最大化所有样本的似然函数乘积。
…
总结
- hierarchical softmax 本质是把 N 分类问题变成 log(N)次二分类
- negative sampling 本质是预测总体类别的一个子集
- 实在真正应用的时候,只需要调用 Gensim (一个 Python第三方库)的接口就可以。但对理论的探究仍然有必要,能更好地知道参数的意义、模型结果受哪些因素影响,以及举一反三地应用到其他问题当中,甚至更改源码以实现自己定制化的需求
- gensim 和 google的 word2vec 里面并没有用到onehot encoder,而是初始化的时候直接为每个词随机生成一个N维的向量,并且把这个N维向量作为模型参数学习;所以word2vec结构中不存在将V维映射到N维的隐藏层。但是,本质是一样的,加上one-hot encoder 层,是为了方便理解,因为这里的 N 维随机向量,就可以理解为是 V 维 one-hot encoder输入层到 N 维隐层的权重,或者说隐层的输出(因为隐层是线性的)。每个 one-hot encoder 里值是 1 的那个位置,对应的 V个权重被激活,其实就是『从一个V*N的随机词向量矩阵里,抽取某一行』。学习 N 维向量的过程,也就是优化 one-hot encoder层到隐含层权重的过程
- 一定要用Huffman tree?未必,比如用完全二叉树也能达到O(log(N))复杂度。但 Huffman tree 被证明是更高效、更节省内存的编码形式,所以相应的权重更新寻优也更快。 举个简单例子,高频词在Huffman tree中的节点深度比完全二叉树更浅,比如在Huffman tree中深度为3,完全二叉树中深度为5,则更新权重时,Huffmantree只需更新3个w,而完全二叉树要更新5个,当高频词频率很高时,算法效率高下立判
Mikolov 两篇原论文:
『Distributed Representations of Sentences and Documents』
贡献:在前人基础上提出更精简的语言模型(language model)框架并用于生成词向量,这个框架就是 Word2vec
『Efficient estimation of word representations in vector space』
贡献:专门讲训练 Word2vec 中的两个trick:hierarchical softmax 和 negative sampling
优点:Word2vec 开山之作,两篇论文均值得一读
缺点:只见树木,不见森林和树叶,读完不得要义。
这里『森林』指 word2vec 模型的理论基础——即 以神经网络形式表示的语言模型
『树叶』指具体的神经网络形式、理论推导、hierarchical softmax 的实现细节等等北漂浪子的博客:『深度学习word2vec 笔记之基础篇』 优点:非常系统,结合源码剖析,语言平实易懂 缺点:太啰嗦,有点抓不住精髓
Yoav Goldberg 的论文:『word2vec Explained- Deriving Mikolov et al.’s Negative-Sampling Word-Embedding Method』 优点:对 negative-sampling
的公式推导非常完备 缺点:不够全面,而且都是公式,没有图示,略显干枯Xin Rong 的论文:『word2vec Parameter Learning Explained』: !重点推荐! 理论完备由浅入深非常好懂,且直击要害,既有 high-level 的 intuition 的解释,也有细节的推导过程
一定要看这篇paper!一定要看这篇paper!一定要看这篇paper!来斯惟的博士论文『基于神经网络的词和文档语义向量表示方法研究』以及他的博客(网名:licstar) 可以作为更深入全面的扩展阅读,这里不仅仅有 word2vec,而是把词嵌入的所有主流方法通通梳理了一遍
几位大牛在知乎的回答:『word2vec 相比之前的 Word Embedding 方法好在什么地方?』 刘知远、邱锡鹏、李韶华等知名学者从不同角度发表对 Word2vec 的看法,非常值得一看
Sebastian 的博客:『On word embeddings - Part 2: Approximating the Softmax』 详细讲解了 softmax 的近似方法,Word2vec 的 hierarchical softmax 只是其中一种
推荐阅读:
[NLP] 秒懂词向量Word2vec的本质
通俗理解word2vec
word2vec原理(一) CBOW与Skip-Gram模型基础
word2vec原理(二) 基于Hierarchical Softmax的模型
word2vec原理(三) 基于Negative Sampling的模型