word2vec 参数详解

1. 背景知识

在NLP任务中,很多时候我们处理文本的细粒度的是词语,所以我们需要将词语转换成向量的形式以进行各式各样的计算。

最初也是最简单的一种词向量表达方式是 One-hot 编码词语,例如:

text: I love you
Vocab: { I: 0, love: 1, you: 2}

Wordvector: {I:[1,0,0], love: [0,1,0], you: [0,0,1]}

可以看到这种表达方式很直观,但是有缺陷:

  1. 词向量的维度 = vocab中词语数量。后者在实际中往往是几万甚至几十几百万,因此会有维度爆炸
  2. 只能单纯的表示词语在vocab的索引,无法表示词语之间的内在联系

有许多研究者就词向量的获取方式作了改进,我们今天讲的word2vec便是其中一种。wordvec是google团队在2013年发布的一个训练获取词向量的工具包,包含了两种训练训练词向量的模型(skip-gram, COBW)和训练优化工具(negative samping, hierarchy softmax)

2. CBOW, Skip-Gram介绍

2.1 以单个词语为输入的情况

image-20200817124222016

​ 从最简单的情况开始讲起,假设输入的文本只有一个单词。我们设 V = vocab size,N = hidden size。Input layer是一个 (V*1) 大小的embedding layer : { x 1 , x 2 , . . . , x V x_1,x_2,...,x_V x1,x2,...,xV}。 x i x_i xi为1代表该词语在输入文本中出现。以单个词语为输入时,意味着{ x 1 , x 2 , . . . , x V x_1,x_2,...,x_V x1,x2,...,xV}只有一个1值。

W V × N W_{V\times N} WV×N是input 和 hidden之间的权重矩阵,每一行代表一个与input word相关的N维向量,我们用 v w v_w vw表示。对于单个词语的输入,假设 x k = 1 x_k=1 xk=1,我们有:

h = W T x = W ( k , . ) T : = v w I T h = W^Tx = W^T_{(k,.)}:= v^T_{w_I} h=WTx=W(k,.)T:=vwIT

注意到 x k = 1 x_k=1 xk=1,所以h其实就是W的第k行, v w I v_{w_I} vwI便是输入词 w I w_I wI的向量表示。

​ 通过hidden layer到output layer中的权重矩阵 W ′ = w i j ′ W'={w'_{ij}} W=wij,我们可以计算出词汇表中每个词语的得分:

u j = v w j ′ T h u_j = {v'_{w_j}}^Th uj=vwjTh

v w j ′ v'_{w_j} vwj W ’ W’ W的第j列,然后我们用softmax得到所有词语的后验概率:

image-20200816203609634

y j y_j yj便是对应output layer的第j个词。

​ 我们注意到,对于输入词 w I w_I wI,他在W和W’中有两种向量形式: v w I , v w I ′ v_{w_I}, v'_{w_I} vwI,vwI,接下来我们把分别称为词语 w I w_I wI输入向量(input vector)和输出向量(output vector)。

更新输出向量:

​ 我们要最大化 P ( w o ∣ w i ) P(w_o|w_i) P(wowi)


E = − l o g   p ( w O ∣ w I ) E = -log\ p(w_O|w_I) E=log p(wOwI)便是我们的损失函数, j ∗ j^* j是实际输出词语的index。然后反向传播更新输出向量

image-20200816205145777

从式子中可以看出,更新一次,我们要检查vocab中所有词的概率。

更新输入向量:

image-20200816205935077

E对输入向量W求导,得到一个V*N的矩阵,因为只有一个输入词,所以该矩阵只有一行是非0的,值为 E H T EH^T EHT,然后便可以对W进行更新:

image-20200816210145738

注意,只有 v w I v_{w_I} vwI那一行得到了更新。

讲过多次训练,最终,输入词的词向量维 w j = h = W T x j w_j=h = W^Tx_j wj=h=WTxj

2.2 CBOW

image-20200816214432341

直观来看,CBOW实际上是以上下文的方式来预测输出的词,我们需要设置一个上下文词语数量skip_window来决定窗口值C, 比如

Text: I love you three thousands.

Window size: skip_window = 2,C=2*skip_window+1=5

假设我们的输入词是 {I, love, three, thousands}, 我们的预测就应该是{you}。参数与2.1中的参数设置基本相同,hidden layer的值为:

image-20200816215024604

C为窗口值5,损失函数也随即成了:

image-20200816215352048

输出输入向量更新为:

image-20200816215450715 image-20200816215500364

注意,对于所有的输入词,输入向量 W W W都是同一个矩阵。

2.3 Skip-Gram

image-20200816215913465

直观来看,skip-gram实际上利用单个词预测上下文。我们设置skip_window和num_skip两个参数,前者代表上文或者下文的个数,后者代表从窗口中选取输出词的数量。同样对于文本"I love you three thousand":

设 skip_window = 1, num_skip=3, 意味着我们的窗口值(包括输入词)为span = 2*1+1 = 5, 输出词个数为3,即:

Input: “you” output=[“I love you”, “love you three”, “you three thousand”)]

损失函数为:
image-20200817131804545

其中image-20200817131857410为输出层所有词的错误和。

输出向量更新公式:

image-20200817132108255

输入向量更新公式:
image-20200817132147209image-20200817132212039

3. 优化计算效率的两种方法

我们注意到,输入向量的学习是很轻松的,但是输出向量的更新却很繁重。对于每个训练示例(training instance),我们都需要遍历一遍vocab中的所有词语,计算每个词语的概率,损失,然后更新相对应输出向量,这对于动辄几万几十万的vocab来说计算成本巨大,所以有一个优化的思路是减少每次训练是需要更新的输出向量。

3.1 Hierarchical Softmax

Hierarchical Softmax是一个利用霍夫曼树来表示vocab中所有词来达到优化softmax计算的方法。首先,将原先模型的输出向量 W ′ W' W矩阵替代成如下的霍夫曼树:

image-20200817140405631

白色的叶结点代表输出层的词,共V个; 黑色结点为内部节点,共V-1个。图中显示从隐藏层到输出层 w 2 w_2 w2的路径 P 2 P_2 P2,路径长度 L ( w 2 ) = 4 L(w_2)=4 L(w2)=4 n ( w 2 , j ) : j = 1 , 2 , 3 n(w_2,j):j=1,2,3 n(w2,j)j=1,2,3代表该路径上的第i个内部节点。

原先用输出向量表示输出词 w 2 w_2 w2,现在变成了用 P 2 P_2 P2路径上每个节点表示。树中每一个内部节点都有一个输出向量 v n ( w , j ) ′ v'_{n(w,j)} vn(w,j),所以相应的,输出词的概率也变成了:

image-20200817141715608

c h ( n ( w , j ) ) ch(n(w,j)) ch(n(w,j))表示节点 n ( w , j ) n(w,j) n(w,j)的左节点,image-20200817141925153

直观的理解就是预测值 w w w为实际值 w O w_O wO的概率是在 P 2 P_2 P2的每一个节点都取左节点的概率。

更新的式子为:image-20200817142548050

其中
image-20200817142626748
就是路径上每个词语的内部节点的预测error。我们根据词频构建霍夫曼树,出现频率越高的词拥有越短的路径(内部节点越少),所需要更新的 v j ′ v'_j vj也越少。因此,我们的更新参数时的计算复杂度从原来的O(V)减少到了O(logV)。当然,我们的总参数量并没有显著减少( N × V → ( V − 1 ) × N N \times V \to (V-1)\times N N×V(V1)×N)。

3.2 Negative Sampling

Negative Sampling的优化思路简单暴力,我们称输出词为正样本,非输出词为负样本,我们基于经验选择特定的概率分布作为样本的噪音分布 P n ( w ) P_n(w) Pn(w),基于 P n ( w ) P_n(w) Pn(w)选择K个负样本:image-20200817144414440

image-20200817144514745

更新方程:

image-20200817144540220

所以,每次更新,我们只需要更新正样本和K个负样本就好了,显著地减少了计算时间。

参考资料:
Rong, Xin. “word2vec parameter learning explained.” arXiv preprint arXiv:1411.2738 (2014).

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值