美文网首页
关于skip-gram和负采样

关于skip-gram和负采样

作者: 全村希望gone | 来源:发表于2020-04-05 16:50 被阅读0次

前言

skip-gram和CBOW都是生成词向量的神经网络,而负采样(negative sampling)则是skip-gram中为了优化训练过程而采用的技术,CBOW中也有相应的技术,叫hierarchical softmax。这篇文章主要讲解skip-gram和negative sampling。

skip-gram

  • 结构图[1]
  • 过程
    理解skip-gram需要几个关键词:海量文本,input word,窗口,训练数据,词汇表,one-hot。

    简而言之,给定训练文本,skip-gram模型会根据input word和窗口,生成训练数据,如下图[2]所示。给定“The quick brown fox jumps over the lazy dog.”,窗口为2,表示取input word左右各两个词与input word组成(input word, output word)形式的训练数据。第一个input word是“The”,所以只能取后两个词,组成(the, quick)和(the brown),然后input word滑动到下一个词,以此类推,形成训练数据对。有了训练数据对后,需要将数据表示为计算机可以处理的形式,这时候one-hot就派上用场了,根据训练数据可以生成一个词汇表,将每个词汇表示为one-hot向量,就可以训练skip-gram模型了。

网络结构

有了大概印象后,下面开始详细讲解模型细节[2]
  • 训练数据
    训练数据就是根据文本生成的(input word, output word)数据对
  • 输入层
    输入层的维度是词汇表中词语的数量,具体值是某一个词汇的one-hot向量。
  • 隐藏层
    隐藏层的值是由输入层和权重矩阵A相乘得来,其实就是这个单词对应的词向量,而A事实上就是所有单词对应的词向量,这个A一开始是随机初始化的,然后经过不断地反向传播,最终训练得到。
  • 输出层
    输出层的维度是词汇表中词语的数量,每个神经元的值表示当前位置的词语和input word共同出现的概率。
    有了训练数据对后,就可以通过反向传播来训练模型了,更详细的看参考资料[2]。但我有些困惑的地方在于一个input word可能对应不同的output word,例如上面的句子中fox有多个数据对(fox, quick)、(fox, brown)、(fox, jumps)、(fox, over),我有点不确定的是训练方式到底是下面哪种(如果有大佬知道是哪种方式,请告诉我,谢谢)
  • 单个(input word, output word)训练,一次只接收(fox, quick)
  • 多个(input word, output word)训练,一次接收(fox, quick)、(fox, brown)、(fox, jumps)、(fox, over),也就是说输入还是单个单词,但是输出对应多个单词(有这种想法是因为看到了一张图),我忘了这张图是哪儿来的了。 skipgram示例.jpg

    但是无论采用何种方式,第二个权重矩阵都会被更新,而第一个权重矩阵只有input word对应的词向量部分会被更新。

负采样

以下摘抄自参考资料[3]
“skip-gram是一个很大的神经网络,在如此庞大的神经网络中进行梯度下降是相当慢的,而且需要大量的训练数据来调整这些权重并且避免过拟合。
负采样(negative sampling)解决了这个问题,它是用来提高训练速度并且改善所得到词向量的质量的一种方法。不同于原本每个训练样本更新所有的权重,负采样每次让一个训练样本仅仅更新一小部分的权重,这样就会降低梯度下降过程中的计算量。
例如当我们用训练样本 ( input word: "fox",output word: "quick") 来训练我们的神经网络时,“ fox”和“quick”都是经过one-hot编码的。如果我们的vocabulary大小为10000时,在输出层,我们期望对应“quick”单词的那个神经元结点输出1,其余9999个都应该输出0。在这里,这9999个我们期望输出为0的神经元结点所对应的单词我们称为“negative” word。(这里解释了我上面的困惑,skip-gram应该是用单个数据对来训练的)
当使用负采样时,我们将随机选择一小部分的negative words(比如选5个negative words)来更新对应的权重。我们也会对我们的“positive” word进行权重更新(在我们上面的例子中,这个单词指的是”quick“)。
回忆一下我们的隐层-输出层拥有300 x 10000的权重矩阵。如果使用了负采样的方法我们仅仅去更新我们的positive word-“quick”的和我们选择的其他5个negative words的结点对应的权重,共计6个输出神经元,相当于每次只更新300 x 6 = 1800个权重。对于3百万的权重来说,相当于只计算了0.06%的权重,这样计算效率就大幅度提高。”
所以负采样实际上就是对negative word进行采样,当然采样也是有策略的,出现频次越高的词,被采样的概率就越大,详见[2]或[3]。

为什么负采样能减少计算量

根据上面的的描述,假设输出层维度为10000,所以真实向量A是[0, 0..., 1..., 0, 0],假设预测向量B为[0.001, 0.002..., 0.009..., 0.01, 0.06],对negative word进行采样,就是先拷贝一个向量B作为向量C,然后将C中某些negative word对应的概率改为0,output word对应的概率改为1,除此之外,其余word对应的概率不变,然后将C作为真实向量,对B求误差后再反向传播,这样的话就可以做到只更新和input word还有采样的negative word相关的权重了。

参考资料

[1] 提出skip-gram模型的论文
[2] 讲解skip-gram的博客
[3] [2]的中文版

相关文章

网友评论

      本文标题:关于skip-gram和负采样

      本文链接:https://www.haomeiwen.com/subject/uzhuphtx.html