word2vec 的 Negative Sampling(负采样)技巧

Skip-gram 模型的负采样

在 Skip-gram 模型 中,softmax 的计算成本很大,因为它需要扫描整个词嵌入矩阵()来计算词汇表中所有词的分布概率,而词汇表的大小可能上百万甚至更多。

word2vec 的 Negative Sampling(负采样)技巧_第1张图片

假设训练的语料库有 V 个不同的词汇,隐藏层是 N 维,这意味着每训练一次样本(采用随机梯度下降),  中有  个神经元要更新, 中有 N 个神经元要更新,导致如果语料库非常庞大,计算会非常低效。

采用负采样:

从噪声分布中随机抽样 K 个负例(K是超参数),对于每次训练样本(已知正例对: w 和 ), 就只用更新  个神经元。

无负采样的  更新:

word2vec 的 Negative Sampling(负采样)技巧_第2张图片

有负采样的  更新:

word2vec 的 Negative Sampling(负采样)技巧_第3张图片

负采样工作原理

使用负采样的 Skip-gram 模型不再使用 softmax 去计算概率分布,而是使用 Sigmoid 函数(\sigma(x))去学习将正例(在中心词的上下文窗口内的词)从随机抽取的负例(不在中心词的上下文窗口内的词)中区分出来。也就是说训练一个 sigmoid 二分类器,只要模型能够从中找出正例就认为完成任务。

word2vec 的 Negative Sampling(负采样)技巧_第4张图片

假设中心词是 “regression”,那么比起 "regression" + {"zebra", "pimples", "Gangnam-Style", "toothpaste", "idiot"}成对出现,"regression" + {"logistic", "machine", "sigmoid", "supervised", "neural"}成对出现的可能性更高。模型最大化正例对出现的概率,最小化负例对出现的概率。词向量不再是通过给定一个中心词来预测上下文词学习得到,而是认为如果模型能区分正例对和负例对,那么就学习到了好的词向量表示。

负采样将多分类任务转化为了二分类任务,而新的目标是给定任意一对中心词和词,去预测词 c 是否在中心词 w 的上下文窗口内。

词 c 在中心词 w 的上下文窗口内/词 c 是正例的概率:

 是  中的词向量,是由一个正例() 和 K 个反例()组成的集合中的一个元素(),也就是词汇表里的每个词都只需要被应用  次而不是 V 次。

负采样的损失函数

最大化正例对出现的概率同时最小化负例对出现的概率:

(2) 等价于:

\quad \underset{\theta}{\operatorname{argmax}} p\left(D=1 \mid w, c_{\text {pos}} ; \theta\right) \prod_{c_{\text {neg}} \in W_{n e g}}\left(1-p\left(D=1 \mid w, c_{\text {neg}} ; \theta\right)\right) \qquad (3)

对 (3) 取对数简化求导:

运算(4)

(1)式代入(5)式:

\underset{\theta}{\operatorname{argmax}} \log \frac{1}{1+\exp \left(-\bar{c}_{p o s} \cdot \bar{w}\right)}+\sum_{c_{n e g} \in W_{n e g}} \log \left(1-\frac{1}{1+\exp \left(-\bar{c}_{n e g} \cdot \bar{w}\right)}\right) \qquad (6)

(6) 代入 sigmoid 函数定义:

对于机器学习,习惯最小化损失函数,即随机梯度下降的损失函数为:

J\left(\theta ; w, c_{p o s}\right)=-\log \sigma\left(\bar{c}_{p o s} \cdot \bar{w}\right)-\sum_{c_{n e g} \in W_{n e g}} \log \left(1-\sigma\left(\bar{c}_{n e g} \cdot \bar{w}\right)\right)\\= -\log \sigma\left(\bar{c}_{p o s} \cdot h\right)-\sum_{c_{n e g} \in W_{n e g}} \log \left(1-\sigma\left(\bar{c}_{n e g} \cdot h\right)\right)\qquad (8)

梯度

sigmoid 函数的导数:

对  通过链式求导:

\frac{\partial J}{\partial \theta}=\left(\sigma\left(\bar{c}_{p o s} \cdot h\right)-1\right) \frac{\partial \bar{c}_{p o s} \cdot h}{\partial \theta}+\sum_{c_{n e g} \in W_{n e g}} \sigma\left(\bar{c}_{n e g} \cdot h\right) \frac{\partial \bar{c}_{n e g} \cdot h}{\partial \theta} \qquad (10)

\theta 是由两个词嵌入矩阵 , 拼接起来的,分别进行求导。

输出矩阵求导

负采样中,每次训练只更新输出矩阵中的  个词向量(),分别对正例和负例求导:

词向量更新:

,可以合并表达为:

当 ,;当 ,

输入矩阵求导

每次训练,只更新输入矩阵中,中心词对应的词向量。

\frac{\partial J}{\partial h} =\left(\sigma\left(\bar{c}_{p o s} \cdot h\right)-1\right) \cdot \bar{c}_{p o s}+\sum_{c_{e n g} \in W_{n e g}} \sigma\left(\bar{c}_{n e g} \cdot h\right) \cdot \bar{c}_{n e g} \\=\sum_{c_{j} \in\left\{c_{p o s}\right\} \cup W_{n e g}}\left(\sigma\left(\bar{c}_{j} \cdot h\right)-t_{j}\right) \cdot \bar{c}_{j} \qquad (16)

词向量更新:

实例演示

训练语料库为一本书《A Song of Ice and Fire》,含中心词的句子为 “Ned Stark is the most honorable man”,设置 “Ned” 为中心词,window=2,即“Stark”和“is”是其上下文词,从噪声分布中为每个正例对随机抽样 K 个负例(令K=3):pimples, zebra, idiot

正例对(Ned,Stack)

word2vec 的 Negative Sampling(负采样)技巧_第5张图片

sigmoid 输出层是给定一个中心词,正例和负例的概率分布。

word2vec 的 Negative Sampling(负采样)技巧_第6张图片

计算预测错误(prediction error):

word2vec 的 Negative Sampling(负采样)技巧_第7张图片

计算 :

word2vec 的 Negative Sampling(负采样)技巧_第8张图片

计算 :

word2vec 的 Negative Sampling(负采样)技巧_第9张图片

更新 :

word2vec 的 Negative Sampling(负采样)技巧_第10张图片

更新 :

word2vec 的 Negative Sampling(负采样)技巧_第11张图片

正例对(Ned,is)

word2vec 的 Negative Sampling(负采样)技巧_第12张图片

sigmoid 输出层:

word2vec 的 Negative Sampling(负采样)技巧_第13张图片

计算预测错误(prediction error):

word2vec 的 Negative Sampling(负采样)技巧_第14张图片

计算 :

word2vec 的 Negative Sampling(负采样)技巧_第15张图片

计算 :

word2vec 的 Negative Sampling(负采样)技巧_第16张图片

更新 :

word2vec 的 Negative Sampling(负采样)技巧_第17张图片

更新 :

word2vec 的 Negative Sampling(负采样)技巧_第18张图片

Reference

https://aegis4048.github.io/optimize_computational_efficiency_of_skip-gram_with_negative_sampling

你可能感兴趣的:(深度学习,自然语言处理,神经网络,nlp)