Word2vec skip-gram模型

Skip-gram使用了一个机器学习的trick。我们训练一个简单的只有一个隐藏层的模型来完成某个任务,但我们的最终目的并不是完成这个任务,而是学习隐藏层中的参数。后面你会看到这些参数就是我们要找的word vectors

我们先来说说用这个网络要完成的“假任务”,然后再说这如何间接的使我们得到想要的word vector

基本模型


训练数据与模型输出


http://mccormickml.com/assets/word2vec/training_data.png
对于原文本中的每个词(作为input),我们看这个词的前w和后w个词(w为窗口大小),这个词和它周围的2w个词分别组成2w个词对作为模型的训练数据。向模型输入input单词,模型输出一个长度为词库大小的向量,向量中每个元素对应一个单词,表示在这个单词的窗口中随机选一个词且这个词恰好是input单词的概率。注意到skip-gram是一个对称的模型,如果wt为中心词时,wk在其窗口内,那么当wk为中心词时,wt也在窗口内。

图中是窗口大小为2的示例

模型细节


我们不能将文本字符串直接输入进模型,要先将输入词做one-hot encoding。同理,output同样也是one-hot encoding

模型只有一层隐藏层,且没有激活函数,但输出层需要softmax,这样输出向量是一个概率分布
http://mccormickml.com/assets/word2vec/skip_gram_net_arch.png

隐藏层

比如我们想学习每个单词的300个特征,即最后得到的word vector长度为300。假设词库大小为10000,这样隐藏层的节点个数为300,且这一层的参数为10000*300的矩阵。

特征数在word2vec中是超参数

如果你仔细看看参数矩阵,会发现每一行就是单词的word vector。所以我们最终的目标就是学习这个参数矩阵,模型训练好后输出层就没用了
http://mccormickml.com/assets/word2vec/word2vec_weight_matrix_lookup_table.png

如图所示,隐藏层的输出就是输入词的word vector
这里写图片描述

输出层

http://mccormickml.com/assets/word2vec/output_weights_function.png
输出层为softmax regression classifier,是logistic regression classfier 对于多类问题的扩展,loss使用交叉熵损失

沿用上面的假设,隐藏层 有300个节点,输出层有10000个节点,所以需要300*10000矩阵的参数,但这个矩阵是上一个矩阵的transpose。也就是说每一列都是一个word vector。

Negative Sampling


从之前简单的skip-gram模型中不难发现,如按照先前的假设,需要300*10000,共三百万个参数,这还仅仅是在词库大小只有一万的情况下。如此之多的参数不但需要很长的训练时间,还需有很大的训练数据,于是,模型的原作者提出了一下改进方案:

  1. 将常见的词组看成一个单词
  2. 对于出现频率高的单词进行随机抽取以减少训练样本
  3. negative sampling

原文链接(https://arxiv.org/pdf/1310.4546.pdf

词组法


比如“boston globe”(一个报纸的名字)与其中的单个字“boston”,“globe”,有着截然不同的意思,所以将“boston globe”看成一个单词是合理的

随机抽取单词


http://mccormickml.com/assets/word2vec/training_data.png
之前我们说过如何从源文本中产生训练样本,还以之前的例子为例,我们可以发现两个问题

  1. (‘fox’, ‘the’)这个词对并没有告诉我们关于fox语境的有价值的信息,‘the’几乎可以出现在所有词的语境中
  2. 我们会获得很多包含‘the’的词对,然而我们得到‘the’的一个好的word vector可能并不需要这么多词对作为训练样本

Word2vec用subsampling方法来解决这个问题,文本中的每个词都有一个被删除的概率,这个词出现的越频繁,被删除的概率越高。词wi被保留下来的几率是
这里写图片描述

z(wi)是wi在文本中出现的频率(出现次数/文本单词总数)。0.001是名为sample的参数(默认值为0.001),sample越小,单词被保留的几率越小

此函数的图像如图所示(sample为0.001不变)
http://mccormickml.com/assets/word2vec/subsample_func_plot.png

negative sampling


Negative sampling使得每个训练样本只更新一小部分的模型参数

在正常情况下,用交叉熵得到损失函数如下:
这里写图片描述

这里的K是总类别数,也就是词库大小。可见这样的话,每一次向后传播都会更新所有的参数。而在nagative sampling中,K不再是词库大小,而是我们抽取几个negative words(期望网络输出为零的单词)再加上positive word(期望网络输出为1的单词)组成的“小词库”的大小。假设我们抽取5个negative words,这样就相当于输出层节点个数从原来的10000个减少到6个(K=6),只有1800个参数得到更新,而不再是三百万个!

抽取negative sample的概率遵从unigram distribution,出现频率越高的词,越容易被选上
f(w)是w出现的次数(word count),3/4次方是由经验得来的,原论文中提到这么做更好
这里写图片描述

参考资料

http://mccormickml.com/2016/04/19/word2vec-tutorial-the-skip-gram-model/
http://mccormickml.com/2017/01/11/word2vec-tutorial-part-2-negative-sampling/

猜你喜欢

转载自blog.csdn.net/libbyandhelen/article/details/79331583