论文题目:word2vec Parameter Learning Explained
发表作者:Xin Rong
发表时间:2016
参考:
《参考文章》
《参考文章》
word2vec,Google 2013年提出的用于计算词向量的工具。
word2vec 一词最初用来指程序或者工具,但是随着该词的流行,在某些语境下,也指神经网络的模型。
正确地说,CBOW 模型和 skip-gram 模型是 word2vec 中使用的两个神经网络。其中CBOW 模型(连续词袋模型)从多个单词(上下文)预测 1 个单词(目标词);skip-gram模型(跳字模型)反过来从 1 个单词(目标词)预测多个单词(上下文)。
摘要部分:word2vec模型通过学习生成的词向量表示方法,能够携带句子的语义信息(semantic meanings),因此非常适用于多种NLP任务。该论文对word2vec模型的参数更新公式的进行了详细推导和解释,包括CBOW(continuous bag-of-word)模型和SG(skip-gram)模型,以及两个优化技术,包括hierarchical softmax 和 negative sampling。并且除了数学推导,该文还提供了梯度方程的直观解释。
文章先从2013年提出的CBOW模型的最简单版本开始介绍—One-word context:
我们假定context(预测目标单词的上下文信息)只有一个单词,也就是说One-word context 模型是在只要一个上下文单词(one context word)的情况下来预测一个目标单词(one target word)的。
如图1描述的就是One-word context定义之下的神经网络模型。
这里我们假设文本词汇量的大小为V,隐藏层的大小为N,相邻层的神经元是全连接的。输入层是一个用one-hot方式编码的单词向量,其中只有一个
为1,其余均为0。从输入层到隐藏层的权重值可以用一个V x W维的矩阵来表示:
其中W矩阵的每一行代表的是一个与输入层相关的单词的N维向量表示形式。
假设我们给定了一个输入单词(a context),其单词向量的第k个元素
,其余均为0,
从(1)我们可以看出,h向量完全是从W矩阵的第k行复制过来的(同均为N维向量)。
即为输入单词
的一种向量表示(其实就是输入向量,后面会提到)
分析完输入层到隐藏层之后,我们再看隐藏层到输出层,同样连接权重用一个新的NxV矩阵来表示如下:
通过这些权重,我们可以为词表中的每一个单词都计算出一个得分:
其中是即为矩阵
的第j列向量(也是N维向量,其实就是输出单词
的输出向量,我们后面会提到)
经过以上讨论之后,我们可以使用一种对数-线性分类模型softmax函数来计算单词的后验分布(是多项式分布):
(softmax函数将多个神经元的输出,映射到(0,1)区间内,可以看成概率来理解,使得所有概率之和为1)
其中,yj表示输出层第j个神经单元的输出值。将(1)式和(2)式代入(3)式我们可以得到:
注意:正如前文所述,是单词的两种向量表现形式。其中
实际上是权重矩阵W的某一行向量,
则是权重矩阵
的某一列向量,我们将
分别成为“输入向量(input vector)”和“输出向量(output vector)”(二者均为N维向量)。
接下来让我们推导权重矩阵的更新公式,尽管在实际的计算过程中这样做是不切实际的(我们在之后再谈)
由以上描述可知,该模型训练的目标就是求公式(4)的最大值。
公式(4)代表的就是给定上下文信息(这里为一个单词)以及权重矩阵的情况下预测其实际输出单词(即上下文输出的中心词
)的条件概率。
其中,为该模型的损失函数,我们需要找到它的最小值。
为输出层实际输出单词的索引。
该损失函数可以理解为一种特殊情形下交叉熵的计算。
现在我们开始推导从隐藏层到输出层的权重矩阵在模型训练过程中的参数更新公式。
(1)首先我们对损失函数求关于得分
的偏导数:
其中,当且仅当输出层的第j个神经元为真实输出单词的时,取值为1。
(2)接下来根据链式法则求出损失函数关于矩阵
元素
的偏导数为:
因此,采用梯度下降法(SGD),我们最终得到了隐藏层到输出层权重更新公式如下:
其中大于0为参数更新的学习速率;
;
为隐藏层第i个神经元;
为单词
的输出向量。
由公式(11)我们可以看出:在更新权重参数的过程中,我们需要检查词汇表中的每一个单词,计算出它的输出概率,并与期望输出
(只能取1或0)进行比较。
1如果(“overestimating”),那就从向量
中减去隐藏向量h的一部分(例如
),这样向量
就会与
相差更远。
2如果(“underestimating”),这种情况只有在
= 1时,才会发生,此时
,则将隐藏向量的一小部分加入
,使
与
更接近。
非常接近于0,故更新参数上基本没什么变化。
(前面说过,这里的是
的第j个列向量,可以看作代表输出词
的词向量;这里
是输入词
的词向量。)
(1)我们继续对损失函数E求关于隐藏层的偏导数:
其中为隐藏层第i个神经元的输出;
在公式(2)中已经定义,表示输出层第j个神经元的输入。
为输出层第j个单词的预测误差。因此EH应该是一个N维向量,它的每一个元素代表的是词汇表中的每个单词的预测误差
与
在j=1到V上的乘积之和。
(2)因此对于权重矩阵W的每一个元素,我们求关于的偏导数,得到:
由此可以得到E对W的导数:
我们再次得到了一个V x N矩阵,由于X向量只有一个非0元素,因此只有一行是N维非0向量
,因此矩阵W的更新公式为:
(其中是矩阵W中的其中一行,是唯一的上下文单词
(context word)的“输入向量”,也是矩阵W的唯一的导数非0的行向量,除了
以外,矩阵W的其他行向量在参数更新迭代过程中都会保持不变(因为其导数为0)
与矩阵的更新过程相似,对于公式(16),我们分析如下:
1如果过高地估计了某个单词作为最终输出单词的概率(
),则上下文单词
的输入向量与单词
输出向量在更新的过程中会相差越来越大。
2如果相反,某个单词作为最终输出单词的概率被低估(
),则单词
的输入向量与单词
输出向量在更新的过程中会越来越接近。
3如果对于单词的概率预测是准确的,则对于单词的输入向量在更新过程中几乎保持不变。
因此,上下文单词的输入向量的更新取决于词汇表中所有单词的预测误差。预测误差越大,则该单词对于上下文单词的输入向量的更新过程影响越大。
当我们通过训练语料库生成的上下文目标词对迭代更新模型参数时,对向量的影响会不断累积。我们可以想象一个单词w的输出向量被w的相邻输入向量来回拖动,就好像在w的向量和它相邻的向量之间有物理字符串一样。
类似地,一个输入向量也可以看作是被许多输出向量拖动的。这种解释可以提醒我们重力或力导向的图形布局。每个虚弦的平衡长度与相关单词对之间的共现强度以及学习速率有关。
经过多次迭代,输入向量和输出向量的相对位置最终会稳定下来。
在介绍完One-word context的CBOW模型之后,我们接着介绍multi-word context下的CBOW模型。
基于multi-word context的CBOW模型就是利用多个上下文单词来推测中心单词target word的一种模型。其结构如图2所示:
其隐藏层的输出值的计算过程为:首先将输入的上下文单词(context words)的向量叠加起来并取其平均值,接着与input→hidden的权重矩阵相乘,作为最终的结果,公式如下:
其中C为上下文单词的个数,为上下文单词,
为单词的输入向量,损失函数为:
hidden→output的权重更新公式:
input→hidden 的权重矩阵更新公式与公式(16)类似,只不过现在我们需要对每一个上下文单词都执行如下更新公式:
与CBOW模型正好相反,Skip-Gram模型是根据中心单词(target word)来预测其上上下文信息(context words)。如图3所示,为Skip-Gram模型的结构示意图:
我们仍然使用来表示输入层上唯一的那个单词的输入向量,因此,我们对于隐藏层的输出值h的计算公式与公式(1)相同:
在输出层,与CBOW模型的输出为单个多项式分布不同的是,SG模型在输出层输出了C个多项式分布。每个输出都使用相同的hidden->output矩阵计算:
其中,表示输出层的第c个panel的第j个单词(何为panel?就是输出层的表示每个上下文单词的神经元的组合,图中一种有C个context words,所以总共有C个panel);
实际上表示的是输出上下文单词(output context words)的第c个单词;
是唯一的输入单词;
为输出层的第c个panel上的第j个神经单元的概率输出值;
表示的是输出层第c个panel的第j个神经元的输入值;由于输出层的所有panels共享同一权重矩阵
,因此:
其中,为词汇表第j个单词
的输出向量;同样,它也是取自于hidden→output权重矩阵
的一列。
SG模型参数更新公式的推导过程与one-word-context模型的推导过程大体上一样。这里我们将损失函数变为:
在得到损失函数E后,我们对输出层的每一个panel上的所有激活单元的输入值,均求其关于E的偏导数,得:
其中为输出层神经元的预测误差,与公式(8)类似。为了简化符号,我们定义一个V维向量
作为所有上下文单词的预测误差之和:
接下来,我们计算hidden->output权重矩阵关于E的偏导数:
这样,我们就得到了hidden→ \rightarrow→output权重矩阵的参数更新公式为:
上述参数更新公式的直观概念理解与上文公式(11)理解一样,除了一点就是:输出层的预测误差的计算是基于多个上下文单词context words,而不是单个目标单词 target word;需注意的是对于每一个训练样本,我们都要利用该参数更新公式来更新hidden→output权重矩阵的每个元素。
同样,对于input→hidden权重矩阵W的参数更新公式的推导过程,除了考虑要将预测误差替换成
外,其他也与上文公式(12)到(16)类似,这里我们直接给出更新公式:
其中,EH是一个N维向量,组成该向量的每一个元素可以用如下公式表示:
公式(36)的直观理解与公式(16)类似。
总结以上的模型介绍,我们发现所有模型的词汇表中的每个单词都存在两个向量表示形式:输入向量和输出向量
,对于输入向量的参数学习成本并不高,但对于输出向量的学习成本代价是非常昂贵的。根据更新公式(22),(23)
我们可以发现,为了更新输出向量,对于每一个训练样例,我们必须迭代遍历词汇表中所有的单词
,计算出它们的输入值
,概率预测值
,预测误差
,最终使用预测误差更新它们的输出向量
。
显然,对于每一个训练样例都要对所有单词计算上述各值,其成本是昂贵的。特别是对于大型的词汇表,这种计算方式是不切实际的。
因此为了解决这个问题,直观的方式是限制必须要更新的训练样例的输出向量的数目。一种有效的实现方式就是:hierarchical softmax(分层softmax),另一种实现通过采样的方式解决,我们在下个章节来讨论。
这两种方法都是通过只优化输出向量更新的计算过程来实现的。在我们的公式推导过程中,我们关心的有三个值:
(1) E ,新的目标函数
**Hierarchical softmax 是一种有效的计算 softmax 的方式。**该模型使用一棵二叉树来表示词汇表中的所有单词。所有的V个单词都在二叉树的叶节点上。非叶子节点一共有V-1个。对于每个叶子节点,从根节点root到该叶子节点只有一条路径;这条路径用来评估用该叶子节点代表该叶子节点上单词的概率值。二叉树的结构如图4所示:
Figure 4: An example binary tree for the hierarchical softmax model.
其中白色的树节点代表的是词汇表中的单词,灰色节点为内部节点。图中高亮显示的是一条从根节点到到的路径,该条路径的长度为
,
表示从根节点到单词
的路径上的第j个节点。
在hierarchical softmax模型中,所有的词汇单词没有输出向量表示形式。不同的是,二叉树的每一个内部节点都有一个输出向量,因此一个单词作为输出单词的概率计算公式定义如下:
其中,为节点n的左孩子节点,
是内部节点
的向量表示(输出向量),h是隐藏层的输出值(在SG模型中,h=
;而在CBOW模型中,
;
是一种特殊的函数定义如下:
接下来,我们通过一个直观地例子来理解公式(37),如图4所示,假定我们需要计算单词作为输出单词的概率。我们将这个概率定义为从根节点开始随机游走到叶节点
的概率。则在每一个内部节点(包括根节点),我们都需要确定其路径指向左孩子节点还是右孩子节点的概率。我们将经过内部节点的路径指向左孩子的概率定义为:
我们可以看出,公式(39)的值取决于内部节点的向量表示,和隐藏层的输出值h(h的值取决于输入单词的向量表示)。显然,内部节点的路径指向右孩子的概率则可以表示为(这里用到了Sigmoid 函数的性质):
顺着图4中从根节点到单词节点的路径,我们可以计算出
作为输出单词的概率为:
不难证明:
现在我们开始推导内部节点的向量表示形式的参数更新公式。为了简化步骤,我们首先考虑单个上下文单词(one-word context)的模型。
为了简化公式,我们定义子公式的简化符号如下:
则,给定一个训练样例,其误差函数我们可以定义如下:
对于误差函数E,我们取其关于的偏导数,得:
其中=1(如果
=1)或者
=0(如果
=-1)
紧接着我们计算内部节点的向量表示
关于函数E的偏导数,得:
因此,更新公式为:
我们可以将理解为内部节点
的预测误差。每一个内部节点的“任务”就是预测其随机游走路径是指向左孩子节点还是指向右孩子节点。
=1意味着节点
的路径指向左孩子节点;
=0则表示指向右孩子节点。
是预测结果。
对于一个训练实例,如果内部节点的预测值非常接近于真实值,则它的向量表示的更新变化很小;否则
量指向一个适当的方向是的该实例的预测误差逐渐减小。以上更新公式既能应用于CBOW模型,又能应用于SG模型。当在SG模型中使用该更新公式时,我们需要对C个output context words的每一个单词都重复此更新过程。
为了使用反向传播该预测误差来学习训练input→hidden的权重,我们对误差函数E求关于隐藏层输出值的偏导数,如下:
接下来我们根据公式(23)便可以获得CBOW模型输入向量的更新公式:
对于SG模型,我们需要计算上下文信息中的每个单词的EH值,并将EH值的和带入公式(35),就能够得到输入向量的更新公式。
从以上更新公式我们可以看出:**经过改进的模型Hierarchical softmax的每个训练样例的每个上下文单词的计算复杂度从降为
级别。**但是模型的参数几乎没有什么改变(内部节点对应V-1维向量,而原始模型的单词的输出向量维数为V)
Negative Sampling模型的思想比hierarchical softmax模型更直接了当。
即:在每次迭代的过程中,有大量的输出向量需要更新,为了解决这一困难,negative sampling提出了只更新其中一部分输出向量的解决方案。
显然,最终需要输出的上下文单词(正样本)在采样的过程中应该保留下来并更新,同时我们需要采集一些单词作为负样本(因此称为“negative sampling”)。
在采样的过程中,我们可以任意选择一种概率分布。我们将这种概率分布称为 “ 噪声分布 ”(the noise distribution),用来表示。我们可以根据经验选择一种较好的分布。
在 word2vec中,我们无需使用一种能够产生良好定义的后验多项式分布的负采样形式,本文作者证明了使用下面简单的训练目标函数能够产生可靠的、高质量的 word embeddings:
其中是输出单词(the positive sample),
是输出向量;
h是隐藏层的输出值:在CBOW模型中,,在SG模型中,h=
。
为了获得negative sampling模型的词向量更新公式,我们首先计算E关于输出单元的输入
的偏导数:
其中,当是一个正样本时,
=1;否则
=0。接下来我们计算E关于单词
的输出向量的偏导数:
因此输出向量的更新公式为:
negative sampling的关键就是公式(59)的更新过程只应用于词汇表的子集,而并非应用于整个词汇表。以上更新公式(59)的直观理解与公式(11)类似。公式(59)对两种应用模型CBOW和SG都适用。对于SG模型,我们每次更新一个上下文单词。
接着利用反向传播机制,计算E关于隐藏层输出h的偏导数:
我们就可以得到CBOW模型关于输入向量的更新公式;
对于SG模型,我们需要计算出每个上下文单词的EH值,将EH值的和代入公式(35)就能够得到其输入向量的更新公式。
CBOW 模型(连续词袋模型)从多个单词(上下文)预测 1 个单词(目标词);
skip-gram模型(跳字模型)反过来从 1 个单词(目标词)预测多个单词(上下文)。
层次化softmax将V分类的softmax改为logV层次二分类。(将每个样本的每次训练更新,求解所有隐藏层的权重矩阵改为求解哈弗曼节点权重矩阵)
负采样是针对每个训练样本的每次训练,只更新部分隐藏权重矩阵。