赞
踩
1. 两种word2vec模型的结构
之前的神经网络语言模型结构Neural Probabilistic Language Model (NNLM)
为什么采用新的结构,不使用NNLM的结构?
在NNLM的结构中,有隐藏层,就是上图中tanh那层,则当单词的窗口长度为n,映射得到的词向量C的维度为D, 隐藏层的维度为H时,从映射层(projection)到隐藏层(hidden layer)的参数量为n*D*H。在skip-gram和CBOW的结构中,没有隐藏层,直接从projection layer到softmax layer,所以减少了参数量和计算。
在skip-gram的project layer,是将中心词的one-hot向量在词表中映射到一个稠密的词向量。
在cbow的project layer,是将窗口内的词映射到的词向量直接相加,得到一个词向量。
这两种相比于有非线性函数tanh的隐藏层的计算量都明显减少。
skip-gram和CBOW两种结构的差别?
skip-gram的效果比CBOW好,训练时间比CBOW长。
skip-gram在训练的时候会根据周围窗口内的词来调整中心词,生僻字的效果会比较好。
CBOW在训练的时候是一个中心词来调整周围窗口内的所有词,所以效果相比skip-gram较差。
2. skip-gram结构
目标函数:最大化给定中间词预测周围每一个词的条件概率的对数平均。
和
是词w的输入和输出向量,W是词典的大小。c是窗口的大小,T是序列长度。
因为目标函数是给定中心词的条件下一个窗口内的非中心词的条件概率,所以skip-gram的训练集是词对的形式。
例如,“像/我/这样/迷茫/的/人/,/你/还/见过/多少/人”,以迷茫为中心词,窗口为2时,生成的训练集是(“迷茫”,“这样”),(“迷茫”,“我”),(“迷茫”,“的”),(“迷茫”,“人”)。
什么是输入和输出向量?每个词都有2个向量的话,最后选择的词向量是哪个?
输入向量是将one-hot映射到projection layer(或者也可以叫hidden layer)的权重矩阵W中对应这个词的那一行,形状为N。输出向量是由hidden layer到output layer的权重矩阵W'对应这个词的那一列,形状为N。
两个向量都可以用来作为这个词的词向量。gensim中输出的词向量是input vector。
output vector比较偏向于主题的相似性。 (参考资料:https://www.quora.com/In-word2vec-what-is-the-relation-between-input-and-output-vectors-Can-output-vectors-also-be-used-for-prediction)
但上面的损失函数在计算上是不太可行的,因为词典的大小W太大。有一些方法对softmax损失函数进行改造,减少计算。
3. 对损失函数的改造
3.1 层次softmax
层次softmax是先将词构建为一个哈夫曼树,是一颗二叉树。词典中的每个词是二叉树的叶子,树上的每个节点代表了其孩子节点的相对概率。每个词都可以在树上找到一条由根节点到叶节点的路径。
从根节点到w的第j个节点。
路径的长度
对不是根节点和叶节点的其他内部节点,表示这个节点的孩子节点
定义 当x为真时,=1,否则为-1
基于层次softmax,条件概率定义如下:
其中,
在正常的softmax中,每个词是有一个输出向量(output vector),层次softmax是树上的每个内部节点有对应一个向量。
详细的梯度推导可以参考https://www.cnblogs.com/pinard/p/7243513.html,非常详细,容易理解。
使用层次softmax计算条件概率时,当进行一次随机梯度下降时,只会更新预测词在霍夫曼树上对应路径的节点向量和输入词向量。而当使用正常的softmax计算条件概率时,每进行一次随机梯度下降会更新从projection layer到output layer的所有权重,而且在更新的计算公式中还是会保留softmax的分母,计算量太大,计算不现实。
层次softmax的缺点:
生僻词的参数更新过程较繁琐,因为路径长,需要更新的参数多。
3.2 negative sampling 负采样
negative sampling是简化的NCE,NCE的假设是使用逻辑回归可以将真实分布的数据从噪音分布中区分出来。
使用negative sampling后的对数条件概率=
其中,, f(wi)是词wi出现的次数。
(梯度更新等详细推导可以参考https://www.cnblogs.com/pinard/p/7249903.html)
注:根据 log(1-sigmoid(x)) = log(sigmoid(-x)) ,可以推导出上面那个链接中的对数似然函数和这边的对数条件概率求和是相等的。
从条件概率计算公式可以看出,一次梯度更新只会更新k个负样本和1个正样本对应的参数。
如何采样负样本?
可以生成一个长度为100M(可以根据训练集词典的大小调整,远大于词典大小就可以)的数组,将词的index值填进这个表格中,这个词在数组中的个数由 P(wi)决定。当你要生成负样本时,只需要从0~100M这些数中随机采样,采样得到这个index值对应的词。高频词更容易被采样到。
4. 对高频词subsampling
对高频词进行subsampling是说以一定概率扔掉高频词,不放进训练集。(上面3介绍的是对损失函数的改造,而这边是减少了训练集,这两种方法都可以加速训练)概率的计算公式是,其中,f(wi)是词wi出现的次数。频率越高的词被丢弃的概率越高,p(wi)与f(wi)成正比。
为什么需要对高频词进行subsampling? 因为类似于“的”“是”这类非常高频的词会和很多词都出现在一个句子或者一篇文章里,高频词和这些词生成的训练集包含的信息量比较少。同时,高频词在训练很多次之后的变化也会比较小,不需要那么多训练集来训练高频词。
subsampling的好处是啥?加速训练,且词向量的质量更好。
那3, 4这些方法的生成的词向量的效果有什么区别吗?使用衡量相近词的任务来评估
。
Syntactic是指例如“slow”“slowly”这类语法上的相似性,Semantic是指语义上的相似性。可以看出,negative sampling的效果比HS和NCE好。当使用subsampling时,训练速度提升,准确率也有提升。
5. 学习短语
为什么要学习短语?因为有些短语的意思不是可以通过组成短语的词的线性加减得到的,短语有自己的含义。
做法:将短语也当做单独一个词(token)加入训练集
如何发现短语?, 其中
是打折系数,防止把出现很少很少的词组合当做短语。当得分高于某个值的时候,就把这个词组合当做有效的短语。
将短语加入训练,negative sampling的效果还是比HS好,但HS加上subsampling之后,变成了效果最好的。
6. 使用tenosrflow进行训练
看网上一些github上tensorflow实现的项目,发现的都是使用negative sampling 来改造损失函数,没有看到使用hierarachical softmax来改造损失函数的。
具体代码可参考别人的github项目,例如https://github.com/liuhuanyong/Word2Vector
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。