两种自监督的词嵌入模型

跳元模型(Skip-Gram)

跳元模型假设一个词可以用于在文本序列中生成周围的词。

假设考虑上下文的长度为 ll,用 xix_i 表示文本序列中第 ii 个词,那么考虑用 xix_i 生成它周围 2l2l 个词的条件概率:P(xil,xi1,xi+1,,xi+lxi)P(x_{i-l} \cdots, x_{i - 1}, x_{i + 1}, \cdots, x_{i + l}\mid x_i)

跳元模型中假定生成每个上下文词的概率是独立的,即有:

P(xil,xi1,xi+1,,xi+lxi)=0<jilP(xjxi)P(x_{i-l} \cdots, x_{i - 1}, x_{i + 1}, \cdots, x_{i + l}\mid x_i) = \prod_{0 < |j - i|\leqslant l} P(x_j \mid x_i)

在预训练阶段,我们尝试用两个向量来表示一个词:它的中心词向量 vi\vec {v_i} 以及上下文词向量 ui\vec {u_i},用 ujvi\vec{u_{j}} \cdot \vec{v_i} 的大小来衡量 P(xjxi)P(x_j \mid x_i)。再对这些点积进行一个 softmax 操作来估计条件概率:

P(xjxi)exp(ujvi)kexp(ukvi)P(x_j \mid x_i) \sim \frac{\exp(\vec{u_j}\cdot \vec{v_i})}{\sum_k \exp(\vec{u_k} \cdot \vec{v_i})}

对于一个长度为 TT 的文本序列,假定每个长度为 2l+12l + 1 的上下文窗口由中心词生成上下文词的概率独立,在跳元模型中需要最大化这些概率的乘积,即最小化它的负对数:

t=1T0<jtllogP(xjxi)-\sum_{t=1}^T \sum_{0 <|j - t|\leq l} \log P(x_j \mid x_i)

一般在自然语言处理应用中,用中心词向量作为词表示。

连续词袋模型(CBOW)

连续词袋模型与跳元模型相反,假设中心词可以由上下文词生成。在连续词袋模型中用所有上下文词的上下文词向量的平均值 uo=12m0<jcluj\vec{u_o} = \frac{1}{2m} \sum_{0<|j-c|\leqslant l} \vec{u_{j}} 作为上下文向量和中心词向量做点积来建模,其中 cc 表示中心词的位置:

P(xcxcl,,xc1,xc+1,,xc+l)exp(vcuo)kexp(vkuo)P(x_c \mid x_{c-l},\cdots, x_{c-1}, x_{c+1}, \cdots, x_{c+l})\sim \frac{\exp(\vec {v_c}\cdot \vec{u_o})}{\sum_k \exp(\vec{v_k}\cdot \vec{u_o})}

剩下的过程和跳元模型类似,这里不再赘述。

近似训练

上面的两种词嵌入模型前向计算和反向传播的时候复杂度包含 V|\mathcal{V}|,其中 V\mathcal{V} 为词表。在实际应用中,词表大小可能非常大,这样会导致训练的过程非常缓慢。为了降低计算的复杂度,接下来会介绍两种近似计算的方法:负采样和分层 softmax。

负采样

这里以跳元模型为例,其中的 softmax 由于综合考虑了上下文词可能是词表中的任意一个,这里削弱一下这个条件,改为判定一个二分类问题:“预测某一词 xx 出现在中心词 xcx_c 的上下文中的概率”。这里仍然利用点积进行建模:

P(D=1xc,x)σ(vcu)P(D = 1\mid x_c, x) \approx \sigma(\vec{v_c}\cdot \vec{u})

其中 σ\sigma 是 sigmoid 函数,它将 R\R 映为 (0,1)(0, 1),它的定义式 σ(x)=11+ex\sigma(x) = \frac{1}{1 + e^{-x}}

对于反面的情况有:

P(D=0xc,x)=1P(D=1xc,x)P(D = 0 \mid x_c, x) = 1 - P(D = 1\mid x_c, x)

对于每一个上下文词 xox_o,生成 KK 个不属于这个上下文窗口的噪声词 y1,,yKy_1, \cdots, y_K。用预测 xox_o 属于 xcx_c 的上下文,yiy_i 不属于 xcx_c 的上下文的概率的乘积近似地作为 xox_o 属于 xcx_c 的上下文的概率:

P(xoxc)P(D=1xc,xo)i=1KP(D=0xc,yi)P(x_o\mid x_c) \approx P(D = 1\mid x_c, x_o) \prod_{i= 1}^KP(D = 0\mid x_c,y_i)

计算的时候取负对数,然后和普通的训练类似。但是将梯度计算的成本从词表大小降为超参数 KK 的大小。

层序 softmax

对词表建一棵二叉树,叶节点表示原词表中的每个词,对于非叶节点 pp,额外维护一个上下文向量 up\vec{u_p}。考虑这样的一个过程:从根节点开始进行一个随机游走,每到一个点 pp,根据 pp 的上下文向量计算接下来向左走和向右走的概率。对于给定的一个上下文词 xox_o,以及中心词向量 vc\vec{v_c},考虑用从根节点进行这样一个随机游走走到 xox_o 的概率作为 P(xoxc)P(x_o \mid x_c) 的估计值。

这里在点 pp 向左走的概率用 σ(upvc)\sigma(\vec{u_p} \cdot \vec{v_c})​ 来估计,向右走的概率用 1σ(upvc)=σ(upvc)1 - \sigma(\vec{u_p}\cdot \vec{v_c})= \sigma(-\vec{u_p}\cdot \vec{v_c}) 来估计。

这里建二叉树的时候似乎用些特殊的方法可以由更好的效果,虽然感觉直接建完全二叉树应该也能用(?),由于是鸽子,没写代码,没去看原论文,所以咕咕咕。