Appearance
词嵌入近似训练
一、为什么需要近似训练
之前我们学的跳元模型(用中心词预测周围词)和连续词袋模型(用周围词预测中心词),在计算梯度的时候,都需要对整个词表的所有词进行求和计算。但实际里词表往往有几十万甚至上百万个词,这样的计算量太大了,根本没法高效训练。所以就需要用近似训练的方法,来降低计算复杂度.
主要有两种方法:负采样和分层 softmax。
二、负采样:把多分类变成二分类
1. 基本思路
原来的跳元模型是一个多分类问题:给定中心词,要预测它的上下文词是词表里的哪一个,需要计算每个词的概率。负采样把这个问题改成了二分类问题:
- 正样本:中心词和它上下文里的词,这个组合是 “真的上下文对”,用 sigmoid 函数计算这个事件的概率,sigmoid 函数可以把两个词向量的点积转换成 0 到 1 之间的概率值,点积越大,概率越接近 1,说明这两个词越可能是上下文对。
- 负样本:从词表里随机选 K 个不是上下文里的词(叫噪声词),这些组合是 “假的上下文对”,同样用 sigmoid 函数计算这些组合是假的概率。
2. 损失函数
我们的目标是让正样本的概率尽可能大,负样本的概率尽可能小。对应的损失函数就是:对于每个正样本,我们要最大化它是真的概率;对于每个负样本,我们要最大化它是假的概率。把这些概率取对数加起来,再取负数,就得到了损失函数,这样我们就可以用梯度下降来最小化这个损失。
3. 计算量的优势
原来的计算量和词表大小成正比,现在负采样的计算量只和我们选的噪声词数量 K 成正比,K 一般选很小的数(比如 5-20),这样计算量就大大减少了。
三、分层 softmax:用二叉树简化计算
1. 基本思路
分层 softmax 把词表里的每个词都作为二叉树的叶子节点,每个非叶子节点都有一个向量。这样,计算给定中心词生成某个上下文词的概率,就变成了从二叉树的根节点走到这个词对应的叶子节点的过程,每一步走左子树或者右子树的概率用 sigmoid 函数计算,最后把路径上的所有概率乘起来,就是这个词的条件概率。
2. 举个例子
比如我们有一个二叉树,根节点是 N1,左子节点是 N2,右子节点是 w1;N2 的左子节点是 w2,右子节点是 w3。要计算中心词生成 w3 的概率,就是从根节点 N1 走到 w3 的路径:先从 N1 走到 N2(计算这个步骤的概率),再从 N2 走到 w3(计算这个步骤的概率),把这两个概率乘起来,就是 w3 的条件概率。
3. 计算量的优势
二叉树里,从根到叶子的路径长度大概是词表大小的对数(比如词表有 100 万个词,对数大概是 20),所以计算量就从原来的和词表大小成正比,变成了和词表大小的对数成正比,大大减少了计算量。
四、小结
负采样把多分类问题转成二分类,通过正样本和随机选的负样本计算损失,计算量和噪声词数量 K 成正比,K 很小的时候计算很快。
分层 softmax 用二叉树来表示词表,把条件概率变成路径上的概率乘积,计算量和词表大小的对数成正比,适合词表很大的场景。
这两种方法都是为了降低词嵌入训练的计算量,让大词表的词嵌入训练变得可行。
五、练习
- 负采样里的噪声词怎么选?
一般是按照词的出现频率来采样,出现频率高的词被选中的概率更大。
- 验证分层 softmax 的所有词的条件概率加起来是 1
因为二叉树的每个路径都是互斥的,所有叶子节点的路径概率加起来就是 1,所以所有词的条件概率总和是 1。
- 怎么用负采样和分层 softmax 训练连续词袋模型?
思路和跳元模型类似,连续词袋模型是用周围词预测中心词,负采样就是把周围词和中心词作为正样本,选噪声词作为负样本;分层 softmax 就是把中心词作为目标,用二叉树的路径来计算概率。
(注:文档部分内容可能由 AI 生成) 源地址