两种自监督的词嵌入模型
跳元模型(Skip-Gram)
跳元模型假设一个词可以用于在文本序列中生成周围的词。
假设考虑上下文的长度为 l,用 xi 表示文本序列中第 i 个词,那么考虑用 xi 生成它周围 2l 个词的条件概率:P(xi−l⋯,xi−1,xi+1,⋯,xi+l∣xi)
跳元模型中假定生成每个上下文词的概率是独立的,即有:
P(xi−l⋯,xi−1,xi+1,⋯,xi+l∣xi)=0<∣j−i∣⩽l∏P(xj∣xi)
在预训练阶段,我们尝试用两个向量来表示一个词:它的中心词向量 vi 以及上下文词向量 ui,用 uj⋅vi 的大小来衡量 P(xj∣xi)。再对这些点积进行一个 softmax 操作来估计条件概率:
P(xj∣xi)∼∑kexp(uk⋅vi)exp(uj⋅vi)
对于一个长度为 T 的文本序列,假定每个长度为 2l+1 的上下文窗口由中心词生成上下文词的概率独立,在跳元模型中需要最大化这些概率的乘积,即最小化它的负对数:
−t=1∑T0<∣j−t∣≤l∑logP(xj∣xi)
一般在自然语言处理应用中,用中心词向量作为词表示。
连续词袋模型(CBOW)
连续词袋模型与跳元模型相反,假设中心词可以由上下文词生成。在连续词袋模型中用所有上下文词的上下文词向量的平均值 uo=2m1∑0<∣j−c∣⩽luj 作为上下文向量和中心词向量做点积来建模,其中 c 表示中心词的位置:
P(xc∣xc−l,⋯,xc−1,xc+1,⋯,xc+l)∼∑kexp(vk⋅uo)exp(vc⋅uo)
剩下的过程和跳元模型类似,这里不再赘述。
近似训练
上面的两种词嵌入模型前向计算和反向传播的时候复杂度包含 ∣V∣,其中 V 为词表。在实际应用中,词表大小可能非常大,这样会导致训练的过程非常缓慢。为了降低计算的复杂度,接下来会介绍两种近似计算的方法:负采样和分层 softmax。
负采样
这里以跳元模型为例,其中的 softmax 由于综合考虑了上下文词可能是词表中的任意一个,这里削弱一下这个条件,改为判定一个二分类问题:“预测某一词 x 出现在中心词 xc 的上下文中的概率”。这里仍然利用点积进行建模:
P(D=1∣xc,x)≈σ(vc⋅u)
其中 σ 是 sigmoid 函数,它将 R 映为 (0,1),它的定义式 σ(x)=1+e−x1
对于反面的情况有:
P(D=0∣xc,x)=1−P(D=1∣xc,x)
对于每一个上下文词 xo,生成 K 个不属于这个上下文窗口的噪声词 y1,⋯,yK。用预测 xo 属于 xc 的上下文,yi 不属于 xc 的上下文的概率的乘积近似地作为 xo 属于 xc 的上下文的概率:
P(xo∣xc)≈P(D=1∣xc,xo)i=1∏KP(D=0∣xc,yi)
计算的时候取负对数,然后和普通的训练类似。但是将梯度计算的成本从词表大小降为超参数 K 的大小。
层序 softmax
对词表建一棵二叉树,叶节点表示原词表中的每个词,对于非叶节点 p,额外维护一个上下文向量 up。考虑这样的一个过程:从根节点开始进行一个随机游走,每到一个点 p,根据 p 的上下文向量计算接下来向左走和向右走的概率。对于给定的一个上下文词 xo,以及中心词向量 vc,考虑用从根节点进行这样一个随机游走走到 xo 的概率作为 P(xo∣xc) 的估计值。
这里在点 p 向左走的概率用 σ(up⋅vc) 来估计,向右走的概率用 1−σ(up⋅vc)=σ(−up⋅vc) 来估计。
这里建二叉树的时候似乎用些特殊的方法可以由更好的效果,虽然感觉直接建完全二叉树应该也能用(?),由于是鸽子,没写代码,没去看原论文,所以咕咕咕。