NLP《词汇表示方法(四)负采样》

一:负采样
在CBOW和Skip-Gram模型中,最后输出的都是词汇的one-hot向量,假如我们的词汇表的数量是10000,嵌入空间的维度是300,再假设此时是以Skip-Gram模型只预测context内的单独一个word的模型为例,那么从隐藏层到输出层的参数数量是300 x 10000的。

每次的输出之前都要做softmax操作,对于如此庞大的词汇数量,计算softmax是很耗费时间的,不仅仅是前向计算,在反向传播的时候求偏导数也是很耗费计算的。

负采样就是一个简化计算的办法,考虑到我们最终样本输出的one-hot向量只有一个点是等于1(称之为正样本),其他9999个点都是0(称之为负样本)。思想就是,保留这个正样本,另外从所有的词典中随机选取采样一个其他的词语的点作为负样本,总共选取K个,K个负样本,这样一来,我们最后只用管这(K+1)个样本的计算,反向传播进行采纳数更新也是只更新这(K+1)个样本对应的参数。每个训练样本只会更新一小部分模型权重,而不是所有的词汇点对应的模型参数,从而降低计算负担。

有点类似于dropout,保留一些样本不失活,前向/反向传播只考虑这存活的节点。
注意,选取节点的时候必须包含一个正样本,其他K个都是负样本。

这样的话,我们的隐藏层到输出层的参数就只有300 x (1+K)个了,大大减少了softmax层计算量,也值更新这选中的节点对应的参数。提升了计算效率。

二:采样方式
任何采样算法都应该保证频次越高的样本越容易被采样出来。

方法就是对预料库的所有词语做一个词频统计,求出每个词语所占的多少概率。
在这里插入图片描述
分子是每个词语的个数,分母是所有词语的总数。且占比之和是等于1。

由于出现频率高的词语理应该被较大概率选中。就把所有词语对应的频率密切衔接对应到一条直线上,直线长度是1,每个词语占一定的长度。接下来我们只要生成一个0-1之间的随机数,看看落到哪个区间,就能采样到该区间对应的单词了,很公平,如下图。
在这里插入图片描述

实现上需要记录每个词语所处的刻度位置和长度,产生的随机数才能去匹配。

Word2vec中,对比有点不一样的做法就是,小数操作太麻烦了,直接将上述直线划分成等距离份的M个小线段,接着我们就不生成0-1之间的随机数了,我们生成0-M之间的整数,去这个刻度尺上一查就能抽中一个单词了,如下图。
在这里插入图片描述

Word2vec中的频率计算有些不同,不是直接使用上述的式子,而是使用了一个更加“平滑”的式子。
在这里插入图片描述
这样做能提小概率的词汇提高一些选择的概率,对大概率的词汇降低一些选择的概率。

例如:词汇表只有A和B两个词语,A是16个,B是81个。A的数量少于B。 用原始式子是:P(A)=16/97 用“平滑”式子是:P(A)=8/(8+27),很明显A的概率值提高了。