赞
踩
提示:这里可以添加本文要记录的大概内容:
在上一篇博文中,详细探讨了NLP(自然语言处理)领域中两个核心技术:基于统计的N-gram模型与基于深度学习的NNLM(神经网络语言模型)。阐明了N-gram模型在处理单词时倾向于将它们视为孤立的单位(独热编码),这种方法可能忽略了单词之间在某些层面上的相似性,从而在语义理解方面有所不足。这些模型主要依赖于对统计信息的聚合。为了克服这些局限性并赋予词向量丰富的语义信息,可以利用深度神经网络。通过利用目标词语之前的词向量去预测它本身,这种方法成功地为词向量赋予了包含语义信息的能力。然而,这种算法最大的挑战是它所需的多分类运算——分类的数量与词汇表的规模相匹敌,这在处理大型词汇库时无疑是计算上与性能上的巨大挑战。正因如此,Word2Vec模型对此技术进行了创新和优化,极大地加快了词向量的语义信息学习过程。
在这篇文章中,旨在帮助读者深入理解相关知识,为此,选择了将算法原理和应用思想分开讲解,以便于提供一个更加清晰的学习路径。
Word2Vec是由Google的研究团队成员Tomas Mikolov等人在2013年提出的,他们的两篇开创性论文《Distributed Representations of Words and Phrases and their Compositionality》和《Efficient Estimation of Word Representations in Vector Space》为这一技术奠定了基础。尽管如此,现有论文在一些细节上表述并不充分清晰。因此,本文以Xin Rong的深入论文作为参考,旨在提供一个详尽而易于理解的Word2Vec算法讲解,以确保读者能够真正掌握其精髓。
提示:Xin Rong大佬于2017年飞机失事,感谢他为当前技术做的贡献。新闻在这里
https://arxiv.org/pdf/1411.2738.pdf&xid=25657,15700021,15700124,15700149,15700168,15700186,15700191,15700201,15700208&usg=ALkJrhhNCZKc2CO7hRoTrGd6aH2nBc-ZVQ。Xin Rong 论文地址
上文中对NNLM 模型进行了详细的讲解,在抛开优化算法不谈的情况下,NNLM(神经网络语言模型)与Word2Vec的关键区别的确在于它们对上下文信息的处理方式。NNLM通常根据前面的词来预测目标词,而Word2Vec则根据上下文中的周围词来进行预测。
在初高中的课程中,对于"函数"这一概念进行了深入的讲解,目的是让学生领会到在这个世界上,存在着一些确定的客观规律,正如函数所体现的那样。函数,亦可被视为一种模式的体现。假若以日常生活中的电饭锅作为类比:函数就好像电饭锅一样简单易用。用户只需投入大米(即输入X
),无需关心其内部复杂的工作原理,便能自动得到米饭(即输出Y
)。这个将大米转变为米饭的过程,即可理解为"电饭锅"这一"函数"的特定功能。同理,当谈到数学中的函数,例如
y
=
x
2
y=x^2
y=x2,当将x
设定为3时,y
的值便自然而然成为9。这正说明了函数具有将任何数值进行平方的"功能",两者完成的作用类似。
现代神经网络,得益于它们复杂的多层结构和非线性激活函数,具有模拟和拟合多种函数的潜力。从而神经网络一定程度上可以完成各种功能。
通过神经网络构建的语言模型实质上也是一个函数,记作y = f(x)
,其中上下文词语作为输入X
,目标输出为y
。在这个方程中,f
代表的是“语言模型”(language model)。这个模型的核心任务是推断出文本中缺失的单词,它就像是完形填空。通过反复训练模型,能够使其预测能力逐渐提升。
在自然语言处理(NLP)的领域内,单词是人类对世界认知的符号性概括,存在多种形式,如中文、英文、拉丁文等。为了能够在数学模型中处理这些符号,需要将它们转换为数值形式,这一步骤被称作“词嵌入”。通过词嵌入,模型能够对每个单词赋予一个数值向量,这些向量捕捉了词与词之间的复杂关系和语义特征,从而赋能模型理解和生成人类语言。Word2vec的副产物就是词向量。从而通过填词游戏的训练就会得到具备语义信息的词嵌入表示。
Word2Vec模型利用上下文去预测目标词汇,并在这一过程中作为副产品生成了词向量。那么,Word2Vec模型具体是如何构建和训练的呢?
Word2Vec模型通过两种主要的架构来实现这一目标:连续词袋(CBOW)和Skip-gram。在CBOW模型中,模型基于其周围的上下文词汇去预测目标单词,而在Skip-gram模型中,以当前词汇为基点,反过来预测其上下文。模型的核心组成是神经网络,其隐藏层权重矩阵作为词嵌入向量存在。在训练过程中,模型不断调整这些权重值,以最小化预测词汇和实际词汇间的差异。通过这种迭代优化,Word2Vec模型的每个单词最终都能获得一个独特的向量表示,而这些向量能够捕捉词与词之间的语义和句法关系。
上图解释了Word2Vec模型的两种核心架构。在图中,左侧展示的是连续词袋(CBOW)模型。该模型的目标是利用中心词周围的上下文(即词序列
w
t
−
2
,
⋯
,
w
t
+
1
,
w
t
+
2
w_{t-2}, \cdots, w_{t+1}, w_{t+2}
wt−2,⋯,wt+1,wt+2)来预测中心词
w
t
w_t
wt本身。这些周围词的索引用于生成它们的独热编码表示,其中索引对应的位置为1,其余位置为0。随后,独热编码向量与隐藏层的权重矩阵相乘,得到每个词的嵌入向量。将这些向量求和后,输入模型并进行内积计算,与字典中所有词的嵌入向量比较,预测概率分布。模型会选择具有最高预测概率的词作为输出。通过这样的迭代优化过程,CBOW模型能够逐步精化其词向量表示,提高预测准确率。相反的操作就是SG(Skip-gram)模型。
在Xin Rong的关于Word2Vec的讲解文中中,他指出Word2Vec模型采纳了神经网络的经典设计,即包含输入层、隐藏层和输出层。该模型利用输入层至隐藏层和隐藏层至输出层的权重矩阵来实现对词汇输入的向量化表示。具体到训练过程中,重点在于学习并迭代这两个权重矩阵。为了便于理解文中只用一个单词去预测另一个单词最简单的版本对整个过程进行讲解:
可以看到上图中的模型就是一个最简单的神经网络,其中输入是
x
x
x向量,这个是
x
x
x是一个独热编码即一个单词。
举个例子:
单词 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
apple | 1 | 0 | 0 | 0 | 0 |
banana | 0 | 1 | 0 | 0 | 0 |
cherry | 0 | 0 | 1 | 0 | 0 |
date | 0 | 0 | 0 | 1 | 0 |
elderberry | 0 | 0 | 0 | 0 | 1 |
苹果就可以使用(1,0,0,0,0)这个向量来进行唯一表示,而图中的 V V V就是整个单词的数量,也可以说是字典的大小,词汇表的长度。
神经网络的权重矩阵可以分别标记为 W V × N W_{V\times N} WV×N 和 W N × V ′ W'_{N\times V} WN×V′,其中 W W W和 W ′ W' W′分别是其简写。而 N N N指的是隐藏层中神经元的数目,它也同时表示词向量的维度。
W V × N W_{V\times N} WV×N 是输入层到隐藏层的权重矩阵,其中 V V V 表示词汇表中单词的个数, N N N 表示每个单词的嵌入向量维度。传统上,单词是以 V V V个维度的独热编码表示,而通过嵌入层,可以将每个单词表示缩减到 N N N个维度。
这是通过矩阵乘法实现的:一个单词的独热编码向量与权重矩阵 W W W进行乘积操作,结果是 W W W中对应该单词的一行,也就是该单词的嵌入表示。
接着,这个单词的嵌入表示将与第二个权重矩阵 W N × V ′ W'_{N\times V} WN×V′进行操作, W ′ W' W′是一个维度为 N × V N\times V N×V的矩阵,就是隐藏层到输出层的权重矩阵。在这里,每一列代表了一个单词的嵌入表示。
当第一个矩阵 W W W中的行向量与第二个矩阵 W ′ W' W′进行矩阵乘法时,实际上是将这个向量与 W ′ W' W′的每一行做乘积操作,从而得到当前单词与词汇表中其他所有单词的乘积结果。
通过softmax函数可以将这些乘积结果归一化为概率值,这个概率分布可用来计算损失并指导模型通过反向传播更新权重矩阵,最终得到每个单词的最佳嵌入表示。
更通俗一点就是得到了模型的权重矩阵作为最终每个单词的嵌入表示。
对于想理解这个算法思想的读者,这部分就够了。具体的公式部分如果想了解本文会对出现的公式进行超级详细的讲解也不要过多担心。
在1.3节,概述了算法的总体逻辑流程。为了进一步明确和深化对整个过程的理解,参考Xin Rong的论文对这里的公式进行详细解释。为了易于理解和直观,采用和原文一致的表示形式。
正向传播
文中公式(1):
矩阵乘法 h = W T x h = W^T x h=WTx 用于获取嵌入向量,这里 W T W^T WT 指的是 W W W输入层到隐藏层的权重矩阵 的转置。这个操作可以被理解为利用独热编码 x x x 来选取权重矩阵 W W W 中对应该单词的嵌入表示。具体来说:
介绍这些不同的表示方法的目的是为了后续在求导过程中避免混淆,确保各种符号的使用清晰一致。之所以一个符号可以表示要,使用多种就是为了求导过程中链式求导法则可以观察到,是哪部分的偏导数。
现在得到了单词的嵌入表示结果
h
h
h:
h
h
h 和
v
′
v'
v′ 是核心概念:
这将 v w j ′ v'_{wj} vwj′(单词的向量表示)和 h h h (输入嵌入)进行转置和乘法运算。两个向量的点乘结果 u j u_j uj 是一个实数,量化了 h h h 和 v w j ′ v'_{wj} vwj′之间的匹配度或紧密度。
在自然语言处理的应用中,这样的计算通常用来为后续的操作提供一个评分依据,例如词汇预测或文本生成
上图公式(3)中,
p
(
w
j
∣
w
I
)
p(w_j | w_I)
p(wj∣wI)表示给定上下文
w
I
w_I
wI 时单词
w
j
w_j
wj 的条件概率,也就是在特定上下文后单词
w
j
w_j
wj 出现的概率。公式使用了
s
o
f
t
m
a
x
softmax
softmax函数来归一化神经网络输出层的得分
u
j
u_j
uj,将其转换为概率分布。
另外的一种表示可以被写成第一个输入层到隐藏层矩阵
W
W
W的一行
v
w
I
v_{wI}
vwI,输入单词word Input 和隐藏层到输出层的矩阵
W
′
W'
W′中一行
v
w
j
′
v'_{wj}
vwj′ 第
j
j
j个单词的乘积的形式,最终得到了实数
u
j
u_j
uj。
损失函数
在深度学习的实践中,模型参数的更新是至关重要的步骤。这一过程通过损失函数来驱动,损失函数衡量模型输出与真实目标值之间的差异。为了最小化损失,我们要利用损失函数相对于模型参数的梯度信息。
参数更新机制:
先来看下文中的损失函数构成公式(5-7)
先解释下公式(5):
神经网络模型输出单词的条件概率时,会用到一个softmax函数的特殊函数。对于给定的单词 w I w_I wI,模型输出单词 w j w_j wj 的条件概率,即` p ( w j ∣ w I ) p(w_j | w_I) p(wj∣wI),由如下公式确定:
p ( w j ∣ w I ) = exp ( v ′ w j T v w I ) ∑ j ′ = 1 V exp ( v ′ w j T v w I ) p(w_j | w_I) = \frac{\exp(v'{_{w_j}^T v_{w_I}})}{\sum_{j'=1}^{V} \exp(v'{_{w_j}^T v_{w_I}})} p(wj∣wI)=∑j′=1Vexp(v′wjTvwI)exp(v′wjTvwI)
y j y_j yj 指的是给定输入上下文 w I w_I wI 时,网络预测任意单词 w j w_j wj作为下一个单词出现的概率。当用 y j ∗ y_{j*} yj∗ 来表示这个概率时,意味着它是对应于真实标签的预测概率,也就是说,这是在给定词向量输入之后,希望模型输出的目标单词。
使用幂函数 exp \exp exp 用于将点乘结果转换为正数,以便进行归一化。分母是所有单词在相同上下文 w I w_I wI 下的点乘结果的指数和,确保了所有单词概率加起来为1。
训练模型的就是要最大化公式(5),即模型在真实label上的概率是最大的接近于1。所以使用 m a x y j ∗ max y_{j*} maxyj∗。
公式(6)的解释:
最终的分类器使用了softmax,是比值形式进行的计算,求导过程会十分麻烦,因此通过log 对数函数将除法转换成减法形式,从而简化求导过程。
举个例子
p
(
w
j
∣
w
I
)
=
exp
(
v
′
w
j
T
v
w
I
)
∑
j
′
=
1
V
exp
(
v
′
w
j
T
v
w
I
)
p(w_j | w_I) = \frac{\exp(v'{_{w_j}^T v_{w_I}})}{\sum_{j'=1}^{V} \exp(v'{_{w_j}^T v_{w_I}})}
p(wj∣wI)=∑j′=1Vexp(v′wjTvwI)exp(v′wjTvwI)
可以通过对数的性质简化为:
log ( p ( w j ∣ w I ) ) = v ′ w j T v w I − log ( ∑ j ′ = 1 V e x p ( v ′ w j T v w I ) ) \log(p(w_j | w_I)) = v'{_{w_j}^T} v_{w_I} - \log\left(\sum_{j'=1}^{V}exp( v'{_{w_j}^T} v_{w_I})\right) log(p(wj∣wI))=v′wjTvwI−log j′=1∑Vexp(v′wjTvwI)
log
(
p
(
w
j
∣
w
I
)
)
=
u
j
−
log
(
∑
j
′
=
1
V
e
x
p
(
u
j
′
)
)
\log(p(w_j | w_I)) = u_j - \log\left(\sum_{j'=1}^{V}exp(u_{j'})\right)
log(p(wj∣wI))=uj−log
j′=1∑Vexp(uj′)
当这个
j
j
j为真实输出结果的概率时,从而得到了最终的公式(7):
log
(
p
(
w
j
∗
∣
w
I
)
)
=
u
j
∗
−
log
(
∑
j
′
=
1
V
e
x
p
(
u
j
′
)
)
\log(p(w_{j*} | w_I)) = u_{j*} - \log\left(\sum_{j'=1}^{V}exp(u_{j'})\right)
log(p(wj∗∣wI))=uj∗−log
j′=1∑Vexp(uj′)
其中
E
=
−
log
p
(
w
O
∣
w
I
)
E = - \log p(w_O | w_I)
E=−logp(wO∣wI) 是损失函数(希望最小化E–>之前的是最大化问题所以添加负号)。
最终的损失函数就是:
E
=
log
(
∑
j
′
=
1
V
e
x
p
(
u
j
′
)
)
−
u
j
∗
E = \log\left(\sum_{j'=1}^{V}exp(u_{j'})\right)-u_{j*}
E=log
j′=1∑Vexp(uj′)
−uj∗
反向传播
更新
W
′
W'
W′
在进行更新的过程中首先更新,隐藏层到输出层的权重矩阵
W
′
W'
W′,损失函数计算依赖于
u
j
u_j
uj而
u
j
u_j
uj的计算依赖于
W
′
W'
W′,因此通过链式求导法则,对求导
W
′
W'
W′的过程进行分解,得到两部分:
先看下公式的左侧是如何得到:
可以看到公式中出现了
u
j
u_j
uj,在上文中描述这个
u
j
u_j
uj存在两种形式,一种是
j
j
j不是真实label,一种是真实label,用
u
j
∗
u_{j*}
uj∗,在这部分求导的过程中也存在两种形式。
考虑损失函数:
E = log ( ∑ j ′ = 1 V e x p ( u j ′ ) ) − u j ∗ E = \log\left(\sum_{j'=1}^{V}exp(u_{j'})\right)-u_{j*} E=log j′=1∑Vexp(uj′) −uj∗
其中 u j ∗ u_{j*} uj∗ 是 j j j为目标单词得分, ∑ j ′ = 1 V e x p ( u j ′ ) \sum_{j'=1}^{V}exp(u_{j'}) ∑j′=1Vexp(uj′) 是softmax函数的分母。
要计算关于 u j u_j uj 的导数 ∂ ∂ u j log ( p ( w j ∣ w I ) ) \frac{\partial}{\partial u_j}\log(p(w_j | w_I)) ∂uj∂log(p(wj∣wI))。为了便于理解,分解为两部分:
∂ u j ∂ u j = 1 \frac{\partial u_j}{\partial u_j} = 1 ∂uj∂uj=1
∂ ∂ u j log ( ∑ j ′ = 1 V e x p ( u j ′ ) ) = 1 ∑ j ′ = 1 V e x p ( u j ′ ) exp ( u j ) = y j \frac{\partial}{\partial u_j}\log\left(\sum_{j'=1}^{V}exp(u_{j'})\right) = \frac{1}{\sum_{j'=1}^{V}exp(u_{j'})} \exp(u_j) = y_j ∂uj∂log j′=1∑Vexp(uj′) =∑j′=1Vexp(uj′)1exp(uj)=yj
合并这两部分,我们得到:
∂ ∂ u j log ( p ( w j ∣ w I ) ) = y j − 1 \frac{\partial}{\partial u_j}\log(p(w_j | w_I)) = y_j-1 ∂uj∂log(p(wj∣wI))=yj−1
这就是对于正确类别 j ∗ = j j^*=j j∗=j 的 u j u_j uj 的导数。
对于错误类别 j ∗ ≠ j j^* \neq j j∗=j,第一部分的导数为0,因为 u j u_{j} uj 不会影响 j ∗ j^* j∗。所以我们只需计算第二部分:
∂ ∂ u j log ( ∑ j ′ = 1 V e x p ( u j ′ ) ) = y j \frac{\partial}{\partial u_{j}}\log\left(\sum_{j'=1}^{V}exp(u_{j'})\right) = y_{j} ∂uj∂log j′=1∑Vexp(uj′) =yj
所以,对于错误类别 j j j 的导数为:
∂ ∂ u j log ( p ( w j ∣ w I ) ) = y j \frac{\partial}{\partial u_{j}} \log(p(w_j | w_I)) = y_{j} ∂uj∂log(p(wj∣wI))=yj
当前得到了一个重要结论,当计算交叉熵损失函数的梯度时,发现该函数关于网络权重的导数实际上给出了预测概率与真实概率之间的差值。具体来说,
对于 正确类别 j ∗ j^* j∗ 的导数,得到 预测概率 y j y_j yj 减去 1(即真实概率):
∂ log ( p ( w j ∣ w I ) ) ∂ u j = y j − 1 \frac{\partial \log(p(w_j | w_I))}{\partial u_j} = y_j-1 ∂uj∂log(p(wj∣wI))=yj−1
对于错误类别 j ∗ ≠ j j^* \neq j j∗=j,得到的导数就是 y j y_{j} yj:
∂ log ( p ( w j ∣ w I ) ) ∂ u j = y j − 0 \frac{\partial \log(p(w_j | w_I))}{\partial u_{j}} = y_{j}-0 ∂uj∂log(p(wj∣wI))=yj−0
故此得到了公式(8):
接下来看公式看公式(9)的右侧:
和左侧比起来很好理解,只需要对
W
i
j
′
W'_{ij}
Wij′进行求导即可:
利用公式(2)求导即可得到
h
i
h_i
hi,为了防止遗忘,这部分的
v
′
v'
v′向量和
W
′
W'
W′中的某一行都是一样的意思。因此最终得到了公式(9)的求导公式。导数完毕后更新当前的参数值:
使用当前权重的导数值,利用学习率
η
η
η 来控制更新的幅度,从而实现对参数矩阵
W
′
W'
W′的迭代。
更新 W W W
在神经网络的训练过程中,既有输出层的权重矩阵 W ′ W' W′ 更新,也需要关注从输入层到隐藏层的权重矩阵 W W W 的迭代。它决定了输入数据如何被转换和编码为隐藏层表示,从而影响模型整体的学习效能.
按照链式求导法则,将对权重矩阵
W
W
W 的部分分成两部分:
首先来看下公式左侧,对
h
i
h_i
hi的部分:
上图公式(12)对 h i h_i hi进行求导,而 h i h_i hi是矩阵的每一行,和更新权重矩阵 W ′ W' W′不一样的地方是,增加了一个求和的符号。 描述的是在进行反向传播算法时更新权重矩阵 W W W 所需要的步骤。这里的 h i h_i hi 是隐藏层的输出,也即 W W W权重矩阵的每一行; u j u_j uj 是输出层的净输入; e j e_j ej 是预测误差;而 w i j ′ w'_{ij} wij′ 是从隐藏层到输出层的权重。
不同于 W ′ W' W′,在这里,我们要计算 h i h_i hi 对于误差 E E E 的影响,需要将所有输出单元 u j u_j uj 相对于 h i h_i hi 的影响累加起来。这正是求和符号的作用,它反映了一个隐藏单元 h i h_i hi 对所有输出 u j u_j uj 的总影响。这也意味着,更新隐藏层的每个单元 h i h_i hi,需要综合其对所有输出单元 u j u_j uj 的贡献,这是由于在前向传播中,每个隐藏单元的输出都会影响所有输出单元的净输入。
这种求和过程是基于神经网络求导的链式法则:误差对某个权重的偏导数是通过将所有该权重直接影响的单元对误差的偏导数求和计算的。所以,这正体现了在训练神经网络时权值更新的全局性质,一个权重的更新受到了与该权重相关的所有路径上的梯度的影响。
接下来公式(14)中的右侧部分:
上文这个 x k x_k xk表示单词独热编码中为1的位置和权重矩阵 W W W进行乘积得到的结果。对当前部分求导的就够就是 x k x_k xk。故此得到了最终的公式(14)。
最终求导公式就是:
对权重矩阵
W
W
W进行更新公式:
在上文的讨论中,主要针对一个基本的单词预测模式进行了详细的阐述。但实际上,Word2Vec 提供了两种不同的模型,即连续词袋(CBOW)和 Skip-gram,它们在构建损失函数和进行优化迭代时有着各自独特的处理方式。
值得注意的是,虽然两种模型在推导和实现上有所不同,但他们的核心思想是相似的——即利用上下文信息去预测中心词(CBOW),或利用中心词去预测上下文信息(Skip-gram)。这两种模型的不同之处主要表现在他们如何定义上下文以及如何损失函数的具体形式,因此在详细讨论这两种模型时,需要分别讨论他们的损失函数以及优化策略。
在连续词袋(CBOW)模型中,对于输入层的每个上下文单词,首先获取它们的独热编码表示
x
x
x。这些独热编码随后与词向量矩阵
W
W
W 相乘,以检索它们各自对应的词向量。接着,这些词向量会被串联或者平均后形成一个完整的隐藏层表示
h
i
h_i
hi, 该表示被送入网络的下一个层次进一步处理。这一模型流程的直观展示,可以帮助更好地理解 CBOW 模型的机制和相应的词向量的形成过程。
在讨论 “Xin Rong” 的论文时,CBOW 模型采用的是一种均值策略,公式(17)展示了这部分计算,即通过计算并获取上下文单词词向量的均值,将它们转化为单一的上下文向量。具体而言,这涉及到对上下文中涉及的所有单词的词向量进行求和,然后求取平均值,以此产生能有效表示上下文信息的向量 h i h_i hi,为模型后续的处理提供基础。
在求导部分值得注意的是:
权重更新公式(23):
其中:
公式(23) 反映的是权重更新规则。在这里,更新规则使用了由多个上下文单词贡献的梯度的均值 (
1
/
C
1/C
1/C倍的梯度),这是因为 CBOW 模型预测当前单词时是利用整个上下文的信息。因此,每个上下文单词对于预测产生的影响是平均分摊的。更新规则如下:
v
new
w
I
,
c
=
v
old
w
I
,
c
−
1
C
⋅
η
⋅
E
H
T
v_{\text{new}}^{w_{I,c}} = v_{\text{old}}^{w_{I,c}} - \frac{1}{C} \cdot \eta \cdot E H^T
vnewwI,c=voldwI,c−C1⋅η⋅EHT
Skip-gram 与 CBOW(连续词袋)模型相对。Skip-gram 模型的核心思想是使用一个单词来预测它的上下文。具体而言,模型试图根据中心词来预测周围的单词,这些周围的单词被称为“上下文”。
上图中描述了Skip-gram 模型的核心流程:
因此Skip-gram和CBOW的不同的部分是多次进行多分类,因此损失函数的结果是一个联合概率,即多个概率的乘积:
论文中给出的公式(27)中也利用log函数的特性,变成乘积的形式,从而计算模型的整体损失情况。后续的损失部分和迭代过程和之前的部分重叠,故此本文不再过多赘述。
上文中讨论的几种词向量模型,包括“二元”模型(单输入输出的简单模型)、CBOW 和 Skip-gram,在原始形态下并未采取效率优化措施。尽管输入向量的学习成本较低,但输出向量的学习成本却很高。原因在于,每次更新输出向量时,需要遍历词汇表中的每个词,进行一系列的计算并更新预测误差。如此大规模的运算使得模型难以应用于大型词汇表或大规模训练语料库。
为了解决这一问题,有两种方式一种是层次 softmax ,另一种是负采样策略。
为简化理解,首先让我们简短定义一下所谓的层次softmax算法。它并非是softmax的一种变体,而是一种将多分类问题转化为二分类问题的技术。这种定义方式可以避免对该算法的误解和混淆
那么这个算法是如何实现将一个多分类问题转换成二分类问题的呢?
直观的说就是通过构造哈夫曼树从而对每个单词构成的类别进行一个1和0的编码。从而模型只需要通过多次二分类操作就能得到最终的类别结果。
哈夫曼树的最直接应用就是编码,比如ASCII 编码对熟知的英文字母都进行编码便于计算机识别。
那么哈夫曼编码跟 ASCII 编码有什么区别?
ASCII 编码是对照ASCII 表进行的编码,每一个字符符号都有对应的编码,其编码长度是固定的。而哈夫曼编码对于不同字符的出现频率其使用的编码是不一样的。其会对频率较高的字符使用较短的编码,频率低的字符使用较高的编码。这样保证总体使用的编码长度会更少,从而实现到了数据压缩的目的。
好的现在明确了本质就是对所有的类别进行编码,即所有的单词进行编码,并且单词的词频越高编码的长度越短。
如何构建哈夫曼树?
给定一个词汇表和对应的频率:
单词 | in | to | and | of | the |
---|---|---|---|---|---|
频率 | 200 | 400 | 600 | 800 | 1000 |
按照步骤步骤来构建哈夫曼树如下:
构建步骤的具体举例:
创建叶子节点并排序:
找到列表中频率最低的两个合并,合并in
和to
,创建600
:
现在列表中最低的就是600
和and
,合并600
和and
,创建1200
:
现在列表中最低的就是of
和the
,合并of
和the
,创建1800
:
现在列表中只有1800
和1200
,合并1800
和1200
作为跟节点,3000
:
哈夫曼树的分支中左侧为0,右侧分支为1。故此得到了全部的单词编码。
and | of | the | in | to |
---|---|---|---|---|
00 | 10 | 11 | 010 | 011 |
上文中介绍了哈夫曼树进行的哈夫曼编码,具体的层次softmax是如何实得到的呢?
上图中展示了当前模型的架构,基本框架并未有大的改变。仍会构建一个代表上下文的向量表示 h i h_i hi。然而,差别在于向量表示 h i h_i hi不再需要和所有的单词向量做乘积后再通过softmax进行分类。相替代地,它会和目标词的哈夫曼树路径上的每个节点向量做乘积,然后通过sigmoid函数进行二分类预测,得到每个节点的预测结果。接着,将预测得到的概率向量和真实的哈夫曼编码做比较以计算损失,通过这一步骤来实现模型的迭代更新。
本文为了一致性采用Xin Rong大佬论文中的图进行讲解:
首先来解释下上图中符号和节点信息,可以看到上图中对所有的单词进行了哈夫曼编码,而每一个单词都有一个独立的路径。图中黑色节点是内部单元,由一个向量和激活函数构成,用于和输入
h
i
h_i
hi做乘积然后投射到0-1之间。白色的节点是单词节点。
n
(
w
2
,
2
)
n(w_2,2)
n(w2,2)表示的是这是通往
w
2
w_2
w2单词遇到的第二个黑色节点(内部单元)
n
n
n就是node的缩写。
在层级Softmax模型中,每一个内部单元(黑色节点)都有一个向量表示 v n ( w , j ) ′ v^{'}_{n(w,j)} vn(w,j)′。一个词汇被选为输出词的概率是通过它在霍夫曼树中从根节点到该词叶节点的唯一路径上的黑色节点和 h i h_i hi的向量来定义的。
公式(37)展示了预测真实输出的概率计算,
w
w
w表示目标单词的,
L
(
w
)
L(w)
L(w)则表示到这个单词的路径的全部节点个数,即上图
w
2
w_2
w2一共有4个节点
L
(
w
)
=
4
L(w)=4
L(w)=4,但是黑色单元只有三个所以哈夫曼编码对
w
2
w_2
w2的编码维度是3,因此使用输入单词向量分别在三个黑色单元中进行处理,得到三个概率值,最终概率就是联合概率,即这三个概率的乘积,从第一个黑色单元开始计算至最后一个黑色单于的结果。
首先看公式的右侧部分 v n ( w , j ) ′ h v^{'}_{n(w,j)}h vn(w,j)′h。模型得到了上下文的嵌入表示 h h h和图中黑色的节点向量进行乘积的过程,得到了一个数值的输出。送入到sigmoid函数中即可得到预测为1或者是0的概率。
而中间这个判断的语句就是 n ( w , j + 1 ) n(w,j+1) n(w,j+1)就是到达词节点 w w w路过的第 j + 1 j+1 j+1个黑色节点是否等于是黑色节点 j j j的左子项。判断下当前位置的真实label是0还是1。如果为真就是当前位置的判断的标签是1那么就✖️1,如果是为假是0就✖️-1。
为什么判断左右后,使用1和-1呢做乘积呢?
真实单词标签是假如是(1,1,0)因此需要判断每一个维度位置是1还是0,中间的公式就是做这个作用的,判断真假,即是0和1,在哈夫曼编码部分知道0代表左侧,1代表右侧,实际上就是判断接下来要去的是左侧节点还是右侧节点也就是真实标签中的当前位置是否0还是1,便于计算损失。
公式(39)和公式(40)揭示了为什么要采用1和-1这种形式。原因在于,sigmoid函数在计算取值为1的概率时,会直接对输入数据进行映射处理;而在计算取值为0的概率时,它实际上是1减去取值为1的概率。换句话说,这部分的概率等同于在进行sigmoid操作之前对要处理的数值加上负号,然后再进行sigmoid操作的结果。这样的处理方式提供了一种便利的数学形式,使得模型可以更有效地进行计算和优化。即通过判断是不是左侧节点得到了这是单词标签中当前位置的1,0取值。由于sigmoid的特性,只需要赋予1,-1就能计算总体的损失。
上图则是一种更详细的解释,判断的部分就是左右的判断从而推导出最终结标签是1还是0,然后赋予sigmoid的1还是-1计算总体损失。
后续的梯度计算无特别之处本文不再赘述。
负采样的理念相较于分层softmax更为直接。负采样的策略是通过转化问题规模来简化问题,将原本复杂的多分类问题通过选择负样本转变为简单的二分类问题,从而优化整个网络的训练过程。这种方法旨在通过减少每轮需要更新的向量数量来缓解大规模多类问题带来的计算压力。
在机器学习模型中,正标签指的是模型在给定输入上下文时期望预测出的目标单词,这个单词的理想预测概率应该是1。通常使用独热编码来表示这个目标单词,并将其与模型的第一个权重矩阵进行乘积运算,以获得代表上下文信息的向量 h h h。这个上下文向量接着与 W ′ W' W′矩阵中对应目标单词的行向量进行点乘操作,并将结果传递至Sigmoid函数进行映射,这样就能够将其输出转换为介于0到1之间的概率值。
相反地,负标签代表了模型在输入相同上下文时希望其预测概率为0的单词。同样地,将独热编码的上下文向量与第一个权重矩阵做乘积,得到向量 h h h。然后,这个向量与 W ′ W' W′矩阵中非目标单词的向量进行点乘,产生的结果再送入Sigmoid函数,目的是使得模型将这些不相关单词的预测概率映射为接近0的值。
通过这种方式,正负标签共同指导神经网络在复杂的高维空间中找到正确的决策边界,从而提高了模型对目标上下文中单词预测的准确性与泛化能力。
公式(55)是论文中所给出的损失函数。正标签的概率是由向量 h h h与矩阵 W ′ W' W′中的一行 v o ′ v'_o vo′相乘得到的结果,经过sigmoid函数映射,期望这个概率尽可能接近于1,对应的损失函数的值应该尽可能小。因此,使用了对数(log)函数。当sigmoid函数的结果越接近1时,对应的对数值就越接近0。由于对数函数的输出是负数,添加了一个负号来反转其图像。
对于负标签部分,希望模型预测的概率尽可能接近0。sigmoid函数计算概率为假的是1减去概率为真的部分。只需在正标签部分添加负号即可。这样,当概率越接近1时,这部分的值就越接近0。同样,使用-log的目的也是一样的。通过优化这个损失函数并进行迭代操作,可以得到每个单词的嵌入表示。同样模型求导迭代的过程和上述模型接近不再赘述。
这部分的操作生成的损失函数就是负对数似然的内容
这一章节揭示了Word2vec算法的工作原理,而Rong Xing大佬的研究成果毫无疑问是对该技术最为深入的阐释。对于那些有意深挖这一领域的读者,结合大佬的文章和本笔记进行学习将大有裨益。Word2vec模型提供了两种训练模式,其引入的优化算法极大地增强了算法的实用性并为这一领域带来了实质性的发展。
学习这篇文章不仅加深了我对词嵌入概念及其先进训练方法的理解,更为迈入自然语言处理(NLP)技术领域铺设了坚实的基石。下一篇文章会对于革命性的Transform模型的讲解也即将展开,其真正的创新之处在于高效的自注意力机制,这一机制已经成为当今大型模型架构的核心。为了掌握更复杂模型算法,深入理解当前技术所蕴含的思想是必不可少的。希望通过本文对相关内容的透彻解读,能够帮助读者轻松跨越入门的门槛。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。