【自然语言处理】预训练05:全局向量的词嵌入(GloVe)

【作者主页】Francek Chen
【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上,结合当代大数据和大算力的发展而发展出来的。深度学习最重要的技术特征是具有自动提取特征的能力。神经网络算法、算力和数据是开展深度学习的三要素。深度学习在计算机视觉、自然语言处理、多模态数据分析、科学探索等领域都取得了很多成果。本专栏介绍基于PyTorch的深度学习算法实现。
【GitCode】专栏资源保存在我的GitCode仓库:https://gitcode.com/Morse_Chen/PyTorch_deep_learning。
文章目录
- 一、带全局语料统计的跳元模型
- 二、GloVe模型
- 三、从条件概率比值理解GloVe模型
- 小结
上下文窗口内的词共现可以携带丰富的语义信息。例如,在一个大型语料库中,“固体”比“气体”更有可能与“冰”共现,但“气体”一词与“蒸汽”的共现频率可能比与“冰”的共现频率更高。此外,可以预先计算此类共现的全局语料库统计数据:这可以提高训练效率。为了利用整个语料库中的统计信息进行词嵌入,让我们首先回顾词嵌入(word2vec)中的跳元模型,但是使用全局语料库统计(如共现计数)来解释它。
一、带全局语料统计的跳元模型
用 q i j q_{ij} qij表示词 w j w_j wj的条件概率 P ( w j ∣ w i ) P(w_j\mid w_i) P(wj∣wi),在跳元模型中给定词 w i w_i wi,我们有:
q i j = exp ( u j ⊤ v i ) ∑ k ∈ V exp ( u k ⊤ v i ) (1) q_{ij}=\frac{\exp(\mathbf{u}_j^\top \mathbf{v}_i)}{ \sum_{k \in \mathcal{V}} \text{exp}(\mathbf{u}_k^\top \mathbf{v}_i)} \tag{1} qij=∑k∈Vexp(uk⊤vi)exp(uj⊤vi)(1) 其中,对于任意索引 i i i,向量 v i \mathbf{v}_i vi和 u i \mathbf{u}_i ui分别表示词 w i w_i wi作为中心词和上下文词,且 V = { 0 , 1 , … , ∣ V ∣ − 1 } \mathcal{V} = \{0, 1, \ldots, |\mathcal{V}|-1\} V={0,1,…,∣V∣−1}是词表的索引集。
考虑词 w i w_i wi可能在语料库中出现多次。在整个语料库中,所有以 w i w_i wi为中心词的上下文词形成一个词索引的多重集 C i \mathcal{C}_i Ci,该索引允许同一元素的多个实例。对于任何元素,其实例数称为其重数。举例说明,假设词 w i w_i wi在语料库中出现两次,并且在两个上下文窗口中以 w i w_i wi为其中心词的上下文词索引是 k , j , m , k k, j, m, k k,j,m,k和 k , l , k , j k, l, k, j k,l,k,j。因此,多重集 C i = { j , j , k , k , k , k , l , m } \mathcal{C}_i = \{j, j, k, k, k, k, l, m\} Ci={j,j,k,k,k,k,l,m},其中元素 j , k , l , m j, k, l, m j,k,l,m的重数分别为2、4、1、1。
现在,让我们将多重集 C i \mathcal{C}_i Ci中的元素 j j j的重数表示为 x i j x_{ij} xij。这是词 w j w_j wj(作为上下文词)和词 w i w_i wi(作为中心词)在整个语料库的同一上下文窗口中的全局共现计数。使用这样的全局语料库统计,跳元模型的损失函数等价于:
− ∑ i ∈ V ∑ j ∈ V x i j log q i j (2) -\sum_{i\in\mathcal{V}}\sum_{j\in\mathcal{V}} x_{ij} \log\,q_{ij} \tag{2} −i∈V∑j∈V∑xijlogqij(2)
我们用 x i x_i xi表示上下文窗口中的所有上下文词的数量,其中 w i w_i wi作为它们的中心词出现,这相当于 ∣ C i ∣ |\mathcal{C}_i| ∣Ci∣。设 p i j p_{ij} pij为用于生成上下文词 w j w_j wj的条件概率 x i j / x i x_{ij}/x_i xij/xi。给定中心词 w i w_i wi,式(2)可以重写为:
− ∑ i ∈ V x i ∑ j ∈ V p i j log q i j (3) -\sum_{i\in\mathcal{V}} x_i \sum_{j\in\mathcal{V}} p_{ij} \log\,q_{ij} \tag{3} −i∈V∑xij∈V∑pijlogqij(3)
在式(3)中, − ∑ j ∈ V p i j log q i j -\sum_{j\in\mathcal{V}} p_{ij} \log\,q_{ij} −∑j∈Vpijlogqij计算全局语料统计的条件分布 p i j p_{ij} pij和模型预测的条件分布 q i j q_{ij} qij的交叉熵。如上所述,这一损失也按 x i x_i xi加权。在式(3)中最小化损失函数将使预测的条件分布接近全局语料库统计中的条件分布。
虽然交叉熵损失函数通常用于测量概率分布之间的距离,但在这里可能不是一个好的选择。一方面,正如我们在近似训练中提到的,规范化 q i j q_{ij} qij的代价在于整个词表的求和,这在计算上可能非常昂贵。另一方面,来自大型语料库的大量罕见事件往往被交叉熵损失建模,从而赋予过多的权重。
二、GloVe模型
有鉴于此,GloVe模型基于平方损失对跳元模型做了三个修改:
- 使用变量 p i j ′ = x i j p'_{ij}=x_{ij} pij′=xij和 q i j ′ = exp ( u j ⊤ v i ) q'_{ij}=\exp(\mathbf{u}_j^\top \mathbf{v}_i) qij′=exp(uj⊤vi)
而非概率分布,并取两者的对数。所以平方损失项是 ( log p i j ′ − log q i j ′ ) 2 = ( u j ⊤ v i − log x i j ) 2 \left(\log\,p'_{ij} - \log\,q'_{ij}\right)^2 = \left(\mathbf{u}_j^\top \mathbf{v}_i - \log\,x_{ij}\right)^2 (logpij′−logqij′)2=(uj⊤vi−logxij)2。 - 为每个词 w i w_i wi添加两个标量模型参数:中心词偏置 b i b_i bi和上下文词偏置 c i c_i ci。
- 用权重函数 h ( x i j ) h(x_{ij}) h(xij)替换每个损失项的权重,其中 h ( x ) h(x) h(x)在 [ 0 , 1 ] [0, 1] [0,1]的间隔内递增。
整合代码,训练GloVe是为了尽量降低以下损失函数:
∑ i ∈ V ∑ j ∈ V h ( x i j ) ( u j ⊤ v i + b i + c j − log x i j ) 2 (4) \sum_{i\in\mathcal{V}} \sum_{j\in\mathcal{V}} h(x_{ij}) \left(\mathbf{u}_j^\top \mathbf{v}_i + b_i + c_j - \log\,x_{ij}\right)^2 \tag{4} i∈V∑j∈V∑h(xij)(uj⊤vi+bi+cj−logxij)2(4)
对于权重函数,建议的选择是:当 x < c x < c x<c(例如, c = 100 c = 100 c=100)时, h ( x ) = ( x / c ) α h(x) = (x/c) ^\alpha h(x)=(x/c)α(例如 α = 0.75 \alpha = 0.75 α=0.75);否则 h ( x ) = 1 h(x) = 1 h(x)=1。在这种情况下,由于 h ( 0 ) = 0 h(0)=0 h(0)=0,为了提高计算效率,可以省略任意 x i j = 0 x_{ij}=0 xij=0的平方损失项。例如,当使用小批量随机梯度下降进行训练时,在每次迭代中,我们随机抽样一小批量非零的 x i j x_{ij} xij来计算梯度并更新模型参数。注意,这些非零的 x i j x_{ij} xij是预先计算的全局语料库统计数据;因此,该模型GloVe被称为全局向量。
应该强调的是,当词 w i w_i wi出现在词 w j w_j wj的上下文窗口时,词 w j w_j wj也出现在词 w i w_i wi的上下文窗口。因此, x i j = x j i x_{ij}=x_{ji} xij=xji。与拟合非对称条件概率 p i j p_{ij} pij的word2vec不同,GloVe拟合对称概率 log x i j \log \, x_{ij} logxij。因此,在GloVe模型中,任意词的中心词向量和上下文词向量在数学上是等价的。但在实际应用中,由于初始值不同,同一个词经过训练后,在这两个向量中可能得到不同的值:GloVe将它们相加作为输出向量。
三、从条件概率比值理解GloVe模型
我们也可以从另一个角度来理解GloVe模型。使用带全局语料统计的跳元模型中的相同符号,设 p i j = d e f P ( w j ∣ w i ) p_{ij} \stackrel{\mathrm{def}}{=} P(w_j \mid w_i) pij=defP(wj∣wi)为生成上下文词 w j w_j wj的条件概率,给定 w i w_i wi作为语料库中的中心词。表1根据大量语料库的统计数据,列出了给定单词“ice”和“steam”的共现概率及其比值。
| w k w_k wk= | solid | gas | water | fashion |
|---|---|---|---|---|
| p 1 = P ( w k ∣ ice ) p_1=P(w_k\mid \text{ice}) p1=P(wk∣ice) | 0.00019 | 0.000066 | 0.003 | 0.000017 |
| p 2 = P ( w k ∣ steam ) p_2=P(w_k\mid\text{steam}) p2=P(wk∣steam) | 0.000022 | 0.00078 | 0.0022 | 0.000018 |
| p 1 / p 2 p_1/p_2 p1/p2 | 8.9 | 0.085 | 1.36 | 0.96 |
从表1中,我们可以观察到以下几点:
- 对于与“ice”相关但与“steam”无关的单词 w k w_k wk,例如 w k = solid w_k=\text{solid} wk=solid,我们预计会有更大的共现概率比值,例如8.9。
- 对于与“steam”相关但与“ice”无关的单词 w k w_k wk,例如 w k = gas w_k=\text{gas} wk=gas,我们预计较小的共现概率比值,例如0.085。
- 对于同时与“ice”和“steam”相关的单词 w k w_k wk,例如 w k = water w_k=\text{water} wk=water,我们预计其共现概率的比值接近1,例如1.36.
- 对于与“ice”和“steam”都不相关的单词 w k w_k wk,例如 w k = fashion w_k=\text{fashion} wk=fashion,我们预计共现概率的比值接近1,例如0.96.
由此可见,共现概率的比值能够直观地表达词与词之间的关系。因此,我们可以设计三个词向量的函数来拟合这个比值。对于共现概率 p i j / p i k {p_{ij}}/{p_{ik}} pij/pik的比值,其中 w i w_i wi是中心词, w j w_j wj和 w k w_k wk是上下文词,我们希望使用某个函数 f f f来拟合该比值:
f ( u j , u k , v i ) ≈ p i j p i k (5) f(\mathbf{u}_j, \mathbf{u}_k, {\mathbf{v}}_i) \approx \frac{p_{ij}}{p_{ik}} \tag{5} f(uj,uk,vi)≈pikpij(5)
在 f f f的许多可能的设计中,我们只在以下几点中选择了一个合理的选择。因为共现概率的比值是标量,所以我们要求 f f f是标量函数,例如 f ( u j , u k , v i ) = f ( ( u j − u k ) ⊤ v i ) f(\mathbf{u}_j, \mathbf{u}_k, {\mathbf{v}}_i) = f\left((\mathbf{u}_j - \mathbf{u}_k)^\top {\mathbf{v}}_i\right) f(uj,uk,vi)=f((uj−uk)⊤vi)。在式(5)中交换词索引 j j j和 k k k,它必须保持 f ( x ) f ( − x ) = 1 f(x)f(-x)=1 f(x)f(−x)=1,所以一种可能性是 f ( x ) = exp ( x ) f(x)=\exp(x) f(x)=exp(x),即:
f ( u j , u k , v i ) = exp ( u j ⊤ v i ) exp ( u k ⊤ v i ) ≈ p i j p i k (6) f(\mathbf{u}_j, \mathbf{u}_k, {\mathbf{v}}_i) = \frac{\exp\left(\mathbf{u}_j^\top {\mathbf{v}}_i\right)}{\exp\left(\mathbf{u}_k^\top {\mathbf{v}}_i\right)} \approx \frac{p_{ij}}{p_{ik}} \tag{6} f(uj,uk,vi)=exp(uk⊤vi)exp(uj⊤vi)≈pikpij(6)
现在让我们选择 exp ( u j ⊤ v i ) ≈ α p i j \exp\left(\mathbf{u}_j^\top {\mathbf{v}}_i\right) \approx \alpha p_{ij} exp(uj⊤vi)≈αpij,其中 α \alpha α是常数。从 p i j = x i j / x i p_{ij}=x_{ij}/x_i pij=xij/xi开始,取两边的对数得到 u j ⊤ v i ≈ log α + log x i j − log x i \mathbf{u}_j^\top {\mathbf{v}}_i \approx \log\,\alpha + \log\,x_{ij} - \log\,x_i uj⊤vi≈logα+logxij−logxi。我们可以使用附加的偏置项来拟合 − log α + log x i - \log\, \alpha + \log\, x_i −logα+logxi,如中心词偏置 b i b_i bi和上下文词偏置 c j c_j cj:
u j ⊤ v i + b i + c j ≈ log x i j (7) \mathbf{u}_j^\top \mathbf{v}_i + b_i + c_j \approx \log\, x_{ij} \tag{7} uj⊤vi+bi+cj≈logxij(7)
通过对式(7)的加权平方误差的度量,得到了式(4)的GloVe损失函数。
小结
- 诸如词-词共现计数的全局语料库统计可以来解释跳元模型。
- 交叉熵损失可能不是衡量两种概率分布差异的好选择,特别是对于大型语料库。GloVe使用平方损失来拟合预先计算的全局语料库统计数据。
- 对于GloVe中的任意词,中心词向量和上下文词向量在数学上是等价的。
- GloVe可以从词-词共现概率的比率来解释。
