基于负采样的Skip-gram模型
题目描述:
假设我们需要训练一个词向量模型,将词汇表中的每个词映射到一个低维、稠密的实数向量(即词向量),使得语义或语法上相似的词在向量空间中的位置也相近。给定一个大型文本语料库,我们如何高效地学习这些词向量?一个著名的方法是Word2Vec中的Skip-gram模型。然而,传统的Skip-gram模型在计算上非常昂贵,因为它需要对整个庞大的词汇表进行归一化(即计算Softmax)。负采样(Negative Sampling)是一种用来解决这个计算效率问题的关键技术。本题要求详细解释:如何利用负采样技术来改进和优化Skip-gram模型的训练过程。
解题过程:
-
理解基础:Skip-gram模型的目标
Skip-gram模型的核心思想是:用一个中心词来预测它上下文窗口中的其他词(即邻居词)。例如,对于句子 "the quick brown fox jumps",如果中心词是 "brown",窗口大小为2,那么我们需要用 "brown" 来预测它左右的 "quick" 和 "fox"。- 输入:中心词(如 "brown"),用其one-hot编码表示。
- 输出:模型需要计算出词汇表中每个词作为其上下文词的概率。我们希望正确上下文词(如 "quick", "fox")的概率尽可能高。
- 挑战:词汇表(V)通常很大(数万甚至数百万词)。传统的Softmax输出层需要计算所有V个词的得分并归一化,这一步的计算成本是 O(V),非常昂贵。
-
引入负采样的核心思想
负采样通过将一个复杂的多分类问题转化为一系列简单的二分类问题,来规避昂贵的全局Softmax计算。- 二分类转换:我们不再问“哪个词是上下文词?”,而是问“这一对词(中心词,另一个词)是否是一个真实的上下文组合?”
- 正样本:从训练数据中实际观察到的(中心词,上下文词)对。例如("brown", "quick")和("brown", "fox")就是正样本。
- 负样本:我们随机从词汇表中抽取一些词(但不是当前窗口内的上下文词),与中心词组成虚假的对。例如("brown", "the")、("brown", "jumps")、("brown", "pizza")就是负样本。"pizza"甚至不在原句中,这明确是一个错误的组合。
- 目标:训练模型,使其能够很好地区分正样本对和负样本对。对于正样本,模型应输出高概率(接近1);对于负样本,模型应输出低概率(接近0)。
-
负采样的具体步骤
a. 定义目标函数:
新的目标函数基于二分类的逻辑回归(Logistic Regression)。对于任何一个词对 (w, c),我们希望模型能估计 P(D=1 | w, c),即词对 (w, c) 是正样本(D=1)的概率。通常使用sigmoid函数来建模这个概率:P(D=1 | w, c) = σ(v_c · v_w) = 1 / (1 + exp(-v_c · v_w)),其中 v_w 是中心词 w 的向量,v_c 是(可能的)上下文词 c 的向量。b. 构建训练样本:
对于一个训练实例(中心词 w,其真实上下文词 c_pos):
* 1个正样本:(w, c_pos),其目标标签 D=1。
* k个负样本:从词汇表中(按照一定的概率分布,如一元分布的3/4次方)随机抽取 k 个词 c_neg1, c_neg2, ..., c_negk。这些词通常不是 w 的上下文词。组成 k 个负样本对:(w, c_neg1), (w, c_neg2), ..., (w, c_negk),它们的目标标签 D=0。k 是一个超参数,通常取值在 5 到 20 之间,小数据集上 k 可以大一些。c. 新的损失函数:
对于这一个正样本和k个负样本,我们最大化他们的对数似然。
* 对于正样本,我们希望 P(D=1 | w, c_pos) 最大,即最大化 log(σ(v_c_pos · v_w))。
* 对于每个负样本,我们希望 P(D=1 | w, c_neg) 最小,即 P(D=0 | w, c_neg) 最大,也就是最大化 log(1 - σ(v_c_neg · v_w)) = log(σ(-v_c_neg · v_w))。
因此,对于单个中心词 w 和其一个真实上下文词 c_pos,其损失函数 J 是:
J = - [log σ(v_c_pos · v_w) + Σ_{i=1}^{k} log σ(-v_c_neg_i · v_w)]
这个损失函数只需要计算 k+1 个词(1个正上下文词 + k个负采样词)的得分,而不是整个词汇表 V,计算复杂度从 O(V) 降到了 O(k),k << V,效率得到极大提升。 -
模型训练与参数更新
- 模型结构:比原始Skip-gram更简单。输入是中心词的one-hot向量,通过一个嵌入矩阵 W_embed 得到中心词向量 v_w。然后,我们不再有一个巨大的Softmax输出层,而是为每个需要计算的词(正上下文词和k个负采样词)准备另一个嵌入矩阵 C_embed,通过查找得到这些词的向量 v_c。
- 前向传播:计算 v_w 与 v_c_pos, v_c_neg1, ..., v_c_negk 的内积,然后分别通过sigmoid函数得到概率。
- 反向传播:根据损失函数 J 计算梯度,然后只用更新三个参数:
- 中心词 w 的向量 v_w。
- 正上下文词 c_pos 的向量 v_c_pos。
- k 个负采样词 c_neg_i 的向量 v_c_neg_i。
- 关键优势:一次训练步骤中,只有 k+2 个词向量(中心词、正上下文词、k个负采样词)被更新。而原始Skip-gram会更新所有V个词的向量(虽然大部分更新幅度极小)。这大大减少了每次参数更新的计算量。
-
负采样的概率分布
负采样并不是完全均匀地随机从词汇表抽词。经验表明,对于频繁词(如"the", "a")进行降采样能提高词向量的质量。因此,常用的抽样分布是“修正的一元分布”,即 P(w_i) ∝ (count(w_i))^{3/4},其中 count(w_i) 是词 w_i 在语料中出现的次数。这种分布既给低频词一些机会,又不过度偏向它们。
总结:
基于负采样的Skip-gram模型通过将全局的多分类预测任务,巧妙地转化为局部二分类任务,显著提升了训练效率。其核心在于用“区分正负样本对”来代替“预测整个词汇表的概率分布”。这种方法使得在大规模语料上训练高质量的词向量变得可行,是Word2Vec成功的关键因素之一。最终训练完成后,我们通常使用矩阵 W_embed 中的向量作为最终的词向量表示。