理解 word2vec

本文是个人对 word2vec 的理解,绝大部分翻译自 Xin Rong 博士的 paper,同时参考了网上很多blogs,都列在References中了。
注:文中数学公式,不加粗小写代表标量值,加粗小写代表向量,加粗大写代表矩阵。

1. word2vec 简介

Word2Vec是Google在2013 年开源的一个词向量(Word Embedding)计算工具,其用来解决单词的分布编码问题。它通过从大量文本预料中以无监督方式学习语义知识型,被广泛地应用于自然语言处理中。

2. 什么是 word embedding(词嵌入)

我们知道,文本是一种非结构化的数据信息,如汉字是一种方块字,是不可以直接被计算的。因此需要将这种非结构化的信息转换为结构化的信息,从而实现针对文本信息进行计算。简单来说,就是把文字转换成数学向量。

这种表示方法很多,常见的有如下三种:

  • 独热编码 | one-hot representation
  • 整数编码
  • 词嵌入 | word embedding

所谓独热码就是开一个和词汇表大小相同的向量,向量的一个位置就代表了一个单词,例如,假设单词表中只有四个单词,我、爱、中、国,那么一个可能的编码为:

我:[1 0 0 0]
爱:[0 1 0 0]
中:[0 0 1 0]
国:[0 0 0 1]

但是在实际情况中,文本中很可能出现成千上万个不同的词,这时候向量就会非常长。其中99%以上都是 0,导致所谓的维度灾难。

整数编码更简单,就是用一个整数代表一个词,如1代表我,2代表爱,等等。

整数编码的缺点如下:

  • 无法表达词语之间的关系
  • 对于模型解释而言,整数编码可能具有挑战性。

word embedding 则是文本表示的一类方法。他可以将文本通过一个低维向量来表达,不像 one-hot 那么长。并且语意相似的词在向量空间上也会比较相近。而Word2vec则是一种基于统计方法来获得词嵌入的方法,2013年由谷歌的 Mikolov 提出。

Word2vec 算法有2种训练模式(2 种网络结构,CBOW和Skip-Gram):

  1. CBOW(Continuous Bag-of-Word Model):用单词的上下文预测当前单词
  2. Skip-gram:当前词预测其上下文

首先要说明,word2vec 本质上是一个神经网络,其输入是 单词的 one-hot 向量,输出是待预测单词的 one-hot 向量(并不是所谓的word embedding),而单词的真正的词嵌入表示是蕴含在在网络的参数中的。

下面分别写一下自己的理解,其中大部分都是来自 Xin Rong 博士在论文 word2vec Parameter Learning Explained 中所解释的。

3. CBOW

CBOW 是用上下文预测当前的单词,也就是输入是多个上下文的单词,输出为待预测的一个单词。首先,为了简便,我们将输入的上下文单词设置为一个。

3. 1 One-word context

此时模型输入一个单词,预测一个单词。下图显示了网络的结构:
在这里插入图片描述
其实网络结构很简单,图中就只有一个隐藏层,且隐藏层没有激活函数输出层有Softmax函数,即输出预测单词的概率分布,概率大的就被预测出来了。我们假设,单词表的长度为 V V V,即一共有 V V V 个单词。隐藏层的节点数为 N N N,输出层的节点数和输入层一样也是 V V V,因为就是要输出每个单词出现的概率,而真值就是该被预测的单词的one-hot,那么整个网络就是要训练成,输出尽可能接近待预测单词的one-hot。

输入层和隐藏层之间为全连接网络,由于没有激活函数,其输入输出关系很简单:
h = W T x = v I T \mathbf{h}=\mathbf{W}^{T} \mathbf{x}=\mathbf{v}_I^T h=WTx=vIT
其中, x \mathbf{x} x 是一个 V × 1 V \times 1 V×1 的列向量。 W \mathbf{W} W 是一个 V × N V \times N V×N 矩阵,那么 h \mathbf{h} h 就是一个 N × 1 N \times 1 N×1 的列向量。由于 x \mathbf{x} x 只有一个元素为 1 1 1 ,假设是第 k k k 维为1,其他都为 0 0 0,那么这个操作的本质是把 W \mathbf{W} W 的第 k k k 行转置之后复制给 h \mathbf{h} h,即 v I T \mathbf{ v}_I^T vIT,下标 I I I 代表 input。

同理,隐藏层和输出层之间通过一个大小为 N × V N \times V N×V 的矩阵 W ′ \mathbf{W}^\prime W 全连接( W ′ \mathbf{W}^\prime W W \mathbf{W} W 没有任何关系!),设其输出为 u \mathbf{u} u,那么输出的第 j j j 个元素为:
u j = v j ′ T h u_{j}={\mathbf{v}_{j}^{\prime}}^T \mathbf{h} uj=vjTh
其中, v j ′ T {\mathbf{v}_{j}^{\prime}}^T vjT 代表矩阵 W ′ T {\mathbf{W}^\prime}^T WT 的第 j j j 行(或者说,矩阵 W ′ {\mathbf{W}^\prime} W 的第 j j j 列 )。最后使用 Softmax 获得单词的后验概率(这里所有的概率之和加起来就等于 1 1 1 了):
p ( w j ∣ w I ) = y j = exp ⁡ ( u j ) ∑ j ′ = 1 V exp ⁡ ( u j ′ ) p\left(w_{j} \mid w_{I}\right)=y_{j}=\frac{\exp \left(u_{j}\right)}{\sum_{j^{\prime}=1}^{V} \exp \left(u_{j^{\prime}}\right)} p(wjwI)=yj=j=1Vexp(uj)exp(uj)
p ( w j ∣ w I ) p\left(w_{j} \mid w_{I}\right) p(wjwI) 代表给定输入单词,预测输出第 j j j 个单词的概率。代入 u j u_j uj,有,
p ( w j ∣ w I ) = exp ⁡ ( v j ′ v I ) ∑ j ′ = 1 V exp ⁡ ( v j ′ ′ T v I ) p\left(w_{j} \mid w_{I}\right)=\frac{\exp \left(\mathbf{v}_{ {j}}^{\prime} \mathbf{v}_{ {I}}\right)}{\sum_{j^{\prime}=1}^{V} \exp \left(\mathbf{v}_{ {j^{\prime}}}^{\prime}{ }^{T} \mathbf{v}_{ {I}}\right)} p(wjwI)=j=1Vexp(vjTvI)exp(vjvI)
我们假设预测真值出现在第 j ∗ j^* j 个位置,则预测输出应该是 t j ∗ \mathbf{t}_{j^*} tj 是一个 one-hot向量,并且只在第 j ∗ j^* j 个位置有一个 1 1 1,其他位置都是 0 0 0,那么,我们目的是想让 输出 y \mathbf{y} y 的第 j ∗ j^* j 个位置的值越大越好(尽可能接近 t j ∗ \mathbf{t}_{j^*} tj ),其他位置的值越小越好,
max ⁡ p ( w O ∣ w I ) = max ⁡ y j ∗ = max ⁡ log ⁡ y j ∗ = u j ∗ − log ⁡ ∑ j ′ = 1 V exp ⁡ ( u j ′ ) : = − E , \begin{aligned} \max p\left(w_{O} \mid w_{I}\right) &=\max y_{j^{*}} \\ &=\max \log y_{j^{*}} \\ &=u_{j^{*}}-\log \sum_{j^{\prime}=1}^{V} \exp \left(u_{j^{\prime}}\right):=-E, \end{aligned} maxp(wOwI)=maxyj=maxlogyj=ujlogj=1Vexp(uj):=E,
其中, E = − log ⁡ p ( w O ∣ w I ) E=-\log p\left(w_{O} \mid w_{I}\right) E=logp(wOwI) 是损失函数,要使得上述的概率最大,那就是最小化 E E E
因此,对上式进行反向传播即可更新参数如下,
∂ E ∂ w i j ′ = ∂ E ∂ u j ⋅ ∂ u j ∂ w i j ′ = ( y j − t j ) ⋅ h i v j ′ (new) = v j ′  (old) − η ⋅ ( y j − t j ) ⋅ h  for  j = 1 , 2 , ⋯   , V \frac{\partial E}{\partial w_{i j}^{\prime}}=\frac{\partial E}{\partial u_{j}} \cdot \frac{\partial u_{j}}{\partial w_{i j}^{\prime}} =(y_{j}-t_{j})\cdot h_{i} \\ {\mathbf{v}_{ {j}}^{\prime}}^\text {(new)}={\mathbf{v}_{ {j}}^{\prime}} ^\text { (old)}-\eta \cdot (y_{j}-t_{j}) \cdot \mathbf{h} \quad \text { for } j=1,2, \cdots, V wijE=ujEwijuj=(yjtj)hivj(new)=vj (old)η(yjtj)h for j=1,2,,V

y j , t j , h i y_{j}, t_{j},h_{i} yj,tj,hi 分别代表向量 y , t , h \mathbf{y,t,h} y,t,h 的第 j , j , i j,j,i j,j,i 个元素, w i j w_{i j} wij 代表矩阵 W ′ {\mathbf{W}^\prime} W i i i 行第 j j j 列元素, η \eta η 是学习率。
同理,更新 W \mathbf{W} W 过程如下,我们首先求 E E E h i h_i hi 的导数如下:
∂ E ∂ h i = ∑ j = 1 V ∂ E ∂ u j ⋅ ∂ u j ∂ h i = ∑ j = 1 V ( y j − t j ) ⋅ w i j ′ : = E H 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} (y_{j}-t_{j}) \cdot w_{i j}^{\prime} :=\mathrm{EH}_{i} hiE=j=1VujEhiuj=j=1V(yjtj)wij:=EHi

: = := := 表示记为。

参数定义同上。下一步就可以算出 E E E W W W 的偏导数,这里要注意,因为input layer的操作是, W \mathbf{W} W 的第 k k k 行转置之后复制给 h \mathbf{h} h,也就是说, h i = w k i h_i = w_{ki} hi=wki,其中的 k k k 代表输入 one-hot 向量的第 k k k 个元素是 1 1 1,其他都是 0 0 0,因此我们更新 W \mathbf{W} W 的时候只要更新第 k k k 行,其他的值由于梯度是 0 0 0,保持不变:
∂ E ∂ w k i = ∂ E ∂ h i ⋅ ∂ h i ∂ w k i = ∑ j = 1 V ( y j − t j ) ⋅ w i j ′ = E H i ⋅ x k for  w  is a constant,  i = 1 , 2 , ⋯   , N \frac{\partial E}{\partial w_{k i}}=\frac{\partial E}{\partial h_{i}} \cdot \frac{\partial h_{i}}{\partial w_{k i}} = \sum_{j=1}^{V} (y_{j}-t_{j}) \cdot w_{i j}^{\prime}=\mathrm{EH}_{i} \cdot x_{k} \quad \text{for } w \text{ is a constant, } i=1,2, \cdots,N wkiE=hiEwkihi=j=1V(yjtj)wij=EHixkfor w is a constant, i=1,2,,N
向量形式表示更新如下:
v I ( new  ) = v I (old)  − η E H T \mathbf{v}_{ {I}}^{(\text {new })}=\mathbf{v}_{ {I}}^{\text {(old) }}-\eta \mathrm{EH}^{T} vI(new )=vI(old) ηEHT
同样也是只更新 W \mathbf{W} W 的第 k k k 行,其他行保持不变。

3.2 Multi-word context

现在我们把模型拓展到有多个上下文单词输入的情况,下图显示了一个 Multi-word context 的 CBOW 模型,
在这里插入图片描述
此时,在计算隐藏层输出时,CBOW 模型不直接复制输入上下文的输入向量,而是取输入上下文向量的平均值,并使用输入到隐藏层权值矩阵的乘积的平均向量作为输出:
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} \mathbf{h} &=\frac{1}{C} \mathbf{W}^{T}\left(\mathbf{x}_{1}+\mathbf{x}_{2}+\cdots+\mathbf{x}_{C}\right) \\ &=\frac{1}{C}\left(\mathbf{v}_{w_{1}}+\mathbf{v}_{w_{2}}+\cdots+\mathbf{v}_{w_{C}}\right)^{T} \end{aligned} h=C1WT(x1+x2++xC)=C1(vw1+vw2++vwC)T
其中, C C C 是上下文单词的数量(在 One-word context 中, C = 1 C=1 C=1), w 1 , ⋯   , w C w_{1}, \cdots, w_{C} w1,,wC 是上下文的单词向量, v 1 , ⋯   , v C \mathbf{v}_1,\cdots, \mathbf{v}_C v1,,vC 同上。损失函数定义如下:
E = − log ⁡ p ( w O ∣ w I , 1 , ⋯   , w I , C ) = − u j ∗ + log ⁡ ∑ j ′ = 1 V exp ⁡ ( u j ′ ) = − v O ′ ⋅ h + log ⁡ ∑ j ′ = 1 V exp ⁡ ( v j ′ T ⋅ h ) \begin{aligned} E &=-\log p\left(w_{O} \mid w_{I, 1}, \cdots, w_{I, C}\right) \\ &=-u_{j^{*}}+\log \sum_{j^{\prime}=1}^{V} \exp \left(u_{j^{\prime}}\right) \\ &=-\mathbf{v}_{ {O}}^{\prime} \cdot \mathbf{h}+\log \sum_{j^{\prime}=1}^{V} \exp \left(\mathbf{v}_{ {j}}^{\prime}{ }^{T} \cdot \mathbf{h}\right) \end{aligned} E=logp(wOwI,1,,wI,C)=uj+logj=1Vexp(uj)=vOh+logj=1Vexp(vjTh)
由于隐藏层到输出向量部分没有改变,因此 W ′ {\mathbf{W}}^\prime W 的更新和之前一样:
v j ′ (new) = v j ′  (old) − η ⋅ ( y j − t j ) ⋅ h  for  j = 1 , 2 , ⋯   , V {\mathbf{v}_{ {j}}^{\prime}}^\text {(new)}={\mathbf{v}_{ {j}}^{\prime}} ^\text { (old)}-\eta \cdot (y_{j}-t_{j}) \cdot \mathbf{h} \quad \text { for } j=1,2, \cdots, V vj(new)=vj (old)η(yjtj)h for j=1,2,,V
W \mathbf{W} W 的更新其实也差不多,只不过我们需要对上下文中的每个单词 w I , c w_{I,c} wI,c 应用以下等式:
v I , c ( n e w ) = v I , c ( old  ) − 1 C ⋅ η ⋅ E H T  for  c = 1 , 2 , ⋯   , C \mathbf{v}_{ {I, c}}^{(\mathrm{new})}=\mathbf{v}_{ {I, c}}^{(\text {old })}-\frac{1}{C} \cdot \eta \cdot \mathrm{EH}^{T} \quad \text { for } c=1,2, \cdots, C vI,c(new)=vI,c(old )C1ηEHT for c=1,2,,C
其中, v I , c \mathbf{v}_{ {I, c}} vI,c 是输入上下文中第 c c c 个单词的输入向量,或者说,对应矩阵 W \mathbf{W} W 的第 k c k_c kc 行,其中 k c k_c kc 为输入第 c c c 个单词在 one-hot 编码中不为 0 0 0 的那一维。

如,上下文单词中,第一个单词 c = 1 c=1 c=1 为"我", V = 4 V=4 V=4,编码为 [ 1   0   0   0 ] [1 \ 0 \ 0 \ 0] [1 0 0 0],那么, k 1 = 0 k_1 = 0 k1=0;上下文单词中,第二个单词 c = 2 c=2 c=2 为"国", V = 4 V=4 V=4,编码为 [ 0   0   0   1 ] [0 \ 0 \ 0 \ 1] [0 0 0 1],那么, k 2 = 3 k_2 = 3 k2=3

4. Skip-Gram Model

下图显示了 Skip-Gram Model 结构:
在这里插入图片描述
Skip-Gram Model 的参数更新方程的推导与one-word-context model 没有太大区别。损失函数变成了:
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\left(w_{O, 1}, w_{O, 2}, \cdots, w_{O, C} \mid w_{I}\right) \\ &=-\log \prod_{c=1}^{C} \frac{\exp \left(u_{c, j_{c}^{*}}\right)}{\sum_{j^{\prime}=1}^{V} \exp \left(u_{j^{\prime}}\right)} \\ &=-\sum_{c=1}^{C} u_{j_{c}^{*}}+C \cdot \log \sum_{j^{\prime}=1}^{V} \exp \left(u_{j^{\prime}}\right) \end{aligned} E=logp(wO,1,wO,2,,wO,CwI)=logc=1Cj=1Vexp(uj)exp(uc,jc)=c=1Cujc+Clogj=1Vexp(uj)
由于 Skip-Gram Model 是给定一个输入单词,预测其上下文多个单词的概率,所以损失函数变成 p ( w O , 1 , w O , 2 , ⋯   , w O , C ∣ w I ) p\left(w_{O, 1}, w_{O, 2}, \cdots, w_{O, C} \mid w_{I}\right) p(wO,1,wO,2,,wO,CwI) 的负对数。其中, j c ∗ j_{c}^{*} jc 是词汇表中第 c c c 个上下文输出单词在 one-hot 编码中不为 0 0 0 的那一维(解释同上)。

由于有多个输出,我们求损失 E E E 对每个输出向量的每个维度的偏导如下:
∂ 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,jE=yc,jtc,j:=ec,j

: = := := 是将 y c , j − t c , j y_{c, j}-t_{c, j} yc,jtc,j 记为 e c , j e_{c, j} ec,j

为了表示简便,我们再记:
E I j = ∑ c = 1 C e c , j \mathrm{EI}_{j}=\sum_{c=1}^{C} e_{c, j} EIj=c=1Cec,j
和前面一样, c c c 代表输出上下文的个数。下一步求 E E E W ′ {\mathbf{W}}^\prime W 中元素的偏导数,并更新:
∂ E ∂ w i j ′ = ∑ c = 1 C ∂ E ∂ u c , j ⋅ ∂ u c , j ∂ w i j ′ = E I j ⋅ h i \frac{\partial E}{\partial w_{i j}^{\prime}}=\sum_{c=1}^{C} \frac{\partial E}{\partial u_{c, j}} \cdot \frac{\partial u_{c, j}}{\partial w_{i j}^{\prime}}=\mathrm{EI}_{j} \cdot h_{i} wijE=c=1Cuc,jEwijuc,j=EIjhi
则更新如下:
w i j ′ (  new  ) = w i j ′  (old)  − η ⋅ E I j ⋅ h i w_{i j}^{\prime}(\text { new })=w_{i j}^{\prime} \text { (old) }-\eta \cdot \mathrm{EI}_{j} \cdot h_{i} wij( new )=wij (old) ηEIjhi
或者向量形式表示:
v j ′  (new)  = v j ′  (old)  − η ⋅ E I j ⋅ h  for  j = 1 , 2 , ⋯   , V \mathbf{v}_{ {j}}^{\prime} \text { (new) }=\mathbf{v}_{ {j}}^{\prime} \text { (old) }-\eta \cdot \mathrm{EI}_{j} \cdot \mathbf{h} \quad \text { for } j=1,2, \cdots, V vj (new) =vj (old) ηEIjh for j=1,2,,V
可以看出,除了损失函数,其他的和 one-word-context model 几乎没有区别。

最后求输入层到隐藏层的权值矩阵的更新方程。由于从结构上可以看出,他和 one-word-context model 完全一样,所以我们直接给出更新方程如下:
v I ( new  ) = v I ( old  ) − η ⋅ E H T \mathbf{v}_{ {I}}^{(\text {new })}=\mathbf{v}_{ {I}}^{(\text {old })}-\eta \cdot \mathrm{EH}^{T} vI(new )=vI(old )ηEHT
其中, E H EH EH 是一个 n n n 维向量,向量中的每一个元素为:
E H i = ∑ j = 1 V E I j ⋅ w i j ′ \mathrm{EH}_{i}=\sum_{j=1}^{V} \mathrm{EI}_{j} \cdot w_{i j}^{\prime} EHi=j=1VEIjwij

5. 最后

我们观察公式:
v j ′ (new) = v j ′  (old) − η ⋅ ( y j − t j ) ⋅ h  for  j = 1 , 2 , ⋯   , V {\mathbf{v}_{ {j}}^{\prime}}^\text {(new)}={\mathbf{v}_{ {j}}^{\prime}} ^\text { (old)}-\eta \cdot (y_{j}-t_{j}) \cdot \mathbf{h} \quad \text { for } j=1,2, \cdots, V vj(new)=vj (old)η(yjtj)h for j=1,2,,V
word2vec 在更新过程中需要变量一边词汇表中的所有的单词,对于每一步的更新,我们还要计算 w j , u j , y j , e j w_j,u_j, y_j, e_j wj,uj,yj,ej 最终才能更新一个 v j ′ {\mathbf{v}_{ {j}}^{\prime}} vj,计算量可想而知。所有在实际的 word2vec 中,使用了很多 tricks 优化计算效率,具体不再展开,推荐 References 中的博客和这一篇博客

References

  1. https://easyai.tech/ai-definition/word-embedding/#wordembedding
  2. word2vec Parameter Learning Explained
  3. https://mp.weixin.qq.com/s/7dsjfcOfm9uPheJrmB0Ghw

猜你喜欢

转载自blog.csdn.net/weixin_43335465/article/details/120923126
今日推荐