细读词向量W2v理论

参考论文:“word2vec Parameter Learning Explained Xin Rong ronxin@umich.edu

随着2014W2v模型被提出并应用,基于W2V模型的向量表示已经被证明具有语义,并且在各种自然语言处理任务中性能表现良好。但是Mikolov的两篇文章对于模型训练和优化技术方面介绍比较少,主要是在讲为什么采用这些思路来改进模型,估计这就是大佬。

连续词袋模型CBOW:

首先从只有一个词的文本开始讨论,在这种情况下模型就是根据输入的一个上下文词来预测目标词,这就很像二元模型,这个一个隐藏层的神经网络模型的输入输出层之间的权重可以被表示为一个矩阵,VxN


矩阵中的每一行都是可以表示为一个N维向量,在公式里面被表示为Vt,也就是输入层所有单元向隐藏层的全连接权重论文细读: - 图1W^T是N行V列,与X的积是N行1列,也就是原本W矩阵的某一行,这个简单示例模型的隐藏层就是简单的线性激活函数,直接将输入的加权和传递给输出层,在隐藏层和输出层之间的权重矩阵w‘是NxV的结构。
这个部分是对词表中你的每个单词加权计算之后使用非线性函数,注意h是N行1列的向量,其中V‘wj是W‘的j列

这里就是对隐藏层的结果再次进行加权计算之后得到的线性加权和
后边会对这个加权和进行sigmoid计算,在后面的分析里面我们称论文细读: - 图2v{wI}作输入向量,论文细读: - 图3v{wj}^{‘}作输出向量
原来的式子更新就是:
论文细读: - 图4u
{j*} - log\sum{j’=1}^V exp(u{j’}) 作为损失函数计算的最大问题就是要在整个词表上计算论文细读: - 图5-log\sum{j’=1}^V exp(u{j’})
在语言任务上词表一般是千万级别的,也就是说这项计算一个批量最少得做千万次
可以注意到这个损失函数可以被看作是两个概率分布之间的交叉熵计算
如果评估结果大于t,这种情况只会处在在t=0,p>0的情况下,这个时候要使得隐藏层结果也要减小,尽量拉开输入和输出向量的距离,两个词向量(输入和输出词向量)是词的两种不同向量表示,同理只有在t=1,p<1的情况下要增大h,同时拉近输入和输出向量的距离

因为更新是对输入向量做输出向量总和的系数更新,也即是e = y-t
我们可以理解成是根据输出向量跟真实情况的差异来更新输入向量
然后回顾一下这个只有一个上下文词的简单模型,可以简单的看一下模型的主要部分
也就是在两层线性加权和基础上使用一个softmax激活函数来获得最大概率的分布
这里有一个形象的描述,词的意思是由其上下文一起出现的词和中心词的关联来调整中心词在向量空间各个维度上的位置,调整的这个过程是根据预测的上下文的词和真实的词的分布之间的差异来进行评估的。
也就是在中心词和上下文词的分布之间可以看作存在一条线,权重就是这些线之间的拉力,这些线的拉力会随着权重的更新产生变化,使得中心词和上下文分布之间的关系能够接近于真实分布状况。


这里开始讨论多词模型,细讲一下在上下文分布在连续词袋模型之间,和上文的单个上下文向量的词模型隐藏层计算是不一样的,这里使用的是上下文平均词向量和权重W的计算结果作为隐藏层的隐藏层的计算结果。

这里就是上下文多词模型的第一部分的变动,计算得来的输入向量也是C的规模,但是隐藏层得到的词表示W应该只能是一个,

这里对输入输出向量的更新其实旨在对隐藏层前后两个权重矩阵进行更新,

第二层我认为是对降维后的词表方式进行复原,如果这层运作正常的话架构就是W2V2W的形式,正常的隐层的向量就是我们要的词的分布表示。


Skip-gram模型在Mikolov在2013年发表的两篇论文里面都进行了一些思路上的介绍,它的思路是和CBOW理念的模型,这个目标词现在是作为模型的输入,而上下文词是模型输出,也即是通过中心词来预测它周围的词的分布形式
可以看出来隐藏层是第一部分权重矩阵的一行的复制和转置,然后在第二层架构的跳词模型中通过第二个权重矩阵对隐藏层输出的V个多项式映射,也就是要把原本的一个中心词向量中对上下文分布词的关系重新映射出来,后边在对预测的这个结果计算得出分数,然后计算损失,但是这是一个假想任务,是通过这个任务来确保隐藏层学习到的向量有着良好的实际效果。

这个多个上下文分布表示的跳词模型是的预测误差是输出层的V个词的损失的和,因为是利用损失和的偏导和隐藏层结果来对第二部分的权重矩阵进行更新,所以这在更新第一部分,也就是权重矩阵更新的时候要同时计算

这里的EI是上下文预测和真实分布之间的损失和,这个就是一个标量,但是论文细读: - 图6w_{ij}^{‘}这第二层的权重矩阵的元素。所以论文细读: - 图7EH_i这里就是第二层权重矩阵的一行元素的和,所以论文细读: - 图8EH是N行元素。但是因为是共现第二个权重矩阵,所以会对原本的第一层权重矩阵的对应的中心词表示向量进行更新。


这里可以看见两种词向量表示模型的一些细节,第一层一般是用来学习一个词向量的表示方式,第二层用来由这个学习来的词向量预测上下文词分布或者中心词,在两个模型中因为模型的输入就是独热码,所以每个词的维度上只有一列是1,其他position都是0,也就是说

按照模型输入的这个特点,隐藏层的计算可以简单的说是只留权重矩阵中独热码对应位置为1的行(因为权重矩阵在和x求积的时候做了转置,也就是转置后的论文细读: - 图9W^T里面会留下对应位置的列,转置前当然留下的是行),
这点在连续词袋模型上有点特殊的是会对多个矩阵行做个取平均计算,模型的第二部分对于连续词袋模型来说是通过预测的这种词向量表示方式预测最大概率一个独热码词表示,所以还要做一个加权和计算来恢复这种映射关系,也即是这种词表示向量和独热码表示形式存在的也是普通的线性映射关系,后边的softmax函数是按照概率输出最可能的结果,这样看来权重矩阵还是挺大的,不过能够将原来论文细读: - 图10V^2大小的词矩阵,变成论文细读: - 图11NV大小的矩阵已经是很好的情况了,本来这种基于推理(预测)的方式就是为了解决共现统计方式存在的维度爆炸问题。
使用连续词袋模型是在学习语料库中单词的出现模式,如果语料不一样学习到的分布式表示也会不一样。

现在想一想这两个词向量表示模型的先后两个权重矩阵,输入权重矩阵的每一行就是一个词向量表示,在输出侧,词向量模型使用的输出权重矩阵的每一列也是每个单词的分布式表示,输出权重和隐藏层的输入计算得出的是score分数,也就是相似度,这是在V这个词表尺度上进行的计算,在W2C里面使用论文细读: - 图12W_{in}也有很好的表现,Glove里面将两个权重相加也获得良好的结果。

基于上面的一些解读,我们可以看出来CBOW模型知识只要计算一个目标词的损失,Skip-gram模型则需要对整个上下文的损失进行计算并求和,但是随着语料规模的增大,Skip-gram的性能会更加好,但是Skip-gram的计算量是在是太大。

这里讲述一下基于推理或者计数的方法在单词相似性任务上性能其实没有明显的高低之分

W2C的思想和自编码器的思路有相似的部分,通过隐层对输入向量进行编码压缩,从而在输出层部分恢复初始状态,训练完成后保留隐层就可以,另外有一点就是在输入是稀疏状态的情况下,不会做矩阵乘法,而是直接查找对应位置的权重行,这样计算效率会高很多。

这点是可以看到skip-gram的输出成其实论文细读: - 图13w_j for j=1,2,3···,c/v这样的预测词,因为跳词模型的输出矩阵权重共享,所以每一次的预测结果的上下文的结果是一样的,因为信息损失不可避免,毕竟可以将中心词视作是上下文语义的子集,它本身就不包含所有的语义信息,这样从一个中心词学到的词表示本身就很难预测上下文,还好这是一个fake task ,只是借助这个任务用来更新隐藏层的词向量表示。


目前来说,前面讨论的模型算法是为了介绍理论,在实际情况下,显然这两张种算法尤其是skip-gram算法计算量是难以接受的,softmax函数的规范因子使得模型必须计算整张词表上的socre的指数和。这里托马斯*米克罗夫采用两种策略来简化隐藏层到输出矩阵之间的计算,分层softmax和负采样,同时使用二次采样来提升模型精度。
论文细读: - 图14
按照顺序,先了解一下分层softmax,原本的softmax可以看作是n分类的n叉树寻找最大概率的叶子,现在按照2叉树生成方式,现在层高论文细读: - 图15[log_2V]的树等于对原来的顺序计算转成了二分计算,同时到达每个叶子节点的路径其实就只有一个,同时原来的输出向量的权重矩阵,现在转变为。这种策略被称作是随机游走,也就是预测一个词的概率变换为,按照一条唯一路径到达特定叶节点的概率,可以看出来这也是一个多项式分布,也就是做多层向左向右的路径选择(这部分的选择可以看作是一个逻辑回归计算),例如路径长度是3的可以看作是 论文细读: - 图16A_3^2的全排列,同时这个词典二叉树整个词表的概率和肯定是一(因为这是一个概率树),也即是说省去了计算规范因子的过程,所以说预测上下文词的过程可以看作是找一条最大概率路径,或者是log2V次的逻辑回归分类,这分层softmax可以看作是逻辑回归树,采用这种策略同时有一种好处就是它的表示向量更新其实也就是更新对应路径上的向量,同时与原来的向量数量相比,现在的V-1个向量的差别是相似的。


接下来继续讲一讲更加简化模型的思路就是负采样Negative Sampling ,因为每轮迭代之间需要对海量的输出向量进行更新,负采样的简化思路就是仅仅更新他们的一个样本。 正样本应该被采样同时得到更新,同时我们需要一些负样本来采样,通过这种来自于噪声对比学习的思路能够以简单的方式。

这里的neg也就是负样本的子集,样本来自于噪声分布论文细读: - 图17P_n(w)这是一个自由参数,使用论文细读: - 图18U(w)^{3/4}/Z是一个比较适合的,这种分布构造的负采样在更新权重的时候只用更新上下文词的向量表示,而不是对整个词表进行更新。为啥这里变成只要对输出向量部分的上下文向量进行更新而不是对整个词表进行更新呢?
因为这里从原来的softmax全概率计算变成是输出对每个上下文向量二分类的问题,也就是正负二分类来来规避了全词表的更新,

可以看到对输出矩阵的向量跟定