1. 前言
现在 NLP 相关的技术大概率会接触到词向量、word embedding(词嵌入)诸如此类的术语。然后网上一搜,哦,有一个 Word2Vec 的技术,能够把单词表示成一种低维向量,不仅可以方便计算机的计算、还可以捕捉到单词之间的语义关系,哦,真棒,用了都说好!
那么请仔细想想,这个词向量是怎么来的?为什么可以表示单词之间的语义关系?
为了弄清楚这件事情,我们不妨看一下 Word2Vec 这个技术的背景和原理。
2. 目标
Word2Vec 是由 Tomas Mikolov 等人在 2013 年提出的论文 《Efficient Estimation of Word Representations in Vector Space》,并由 Google 在开源工具包中实现。它基于分布式假设,即相似上下文中出现的单词有相似的含义,通过学习上下文信息来生成单词的向量表示,称为 word embedding。
如果有一个句子 “you are a good man”,我希望有计算机语言表示这句话,应该如何表示?
早期一个通用的方法是,我们建立一个词典,词典就包含这5个单词 you, are, a, good, man
并对词典编号,如 the
是第0位,is
是第3位,那么上面这句话则表示为如下的结果:
y
o
u
=
[
1
,
0
,
0
,
0
,
0
]
you =[1, 0, 0, 0, 0]
you=[1,0,0,0,0]
a r e = [ 0 , 1 , 0 , 0 , 0 ] are =[0,1,0,0,0] are=[0,1,0,0,0]
a = [ 0 , 0 , 1 , 0 , 0 ] a =[0,0,1,0,0] a=[0,0,1,0,0]
g o o d = [ 0 , 0 , 0 , 1 , 0 ] good =[0,0,0,1,0] good=[0,0,0,1,0]
m a n = [ 0 , 0 , 0 , 0 , 1 ] man =[0,0,0,0,1] man=[0,0,0,0,1]
这就是熟悉的 one-hot 编码。one-hot 编码有其局限性, 首先,如果词汇表太大(几万都是很常见的),向量长度太大,计算的消耗则过高。此外,如果我们向词汇表中添加或删除单词,所有单词的表示都会发生变化。最关键的是,这种表示无法实现 “国王-男人+女人=女王”的这种带有语义性质的运算效果,即无法捕捉单词深层的语义信息。
那么我们希望达到怎么样的效果呢?
- 所有单词的表示有一个固定的维度,例如300维,举例
you=[0.11, 0.23,0.01,...,0.1] (长度为300)
- 能表示语义信息,相似的词语应该有相近的向量
为了实现这些效果,Word2Vec 提出了一些模型架构,如 CBOW、Skip-Gram,这些算法出现了11年,稍微有接触相关算法的一定不会陌生。本文仅介绍 CBOW 的原理。
3. CBOW
CBOW,即 Continuous Bag of Words 缩写。CBOW 模型的目标是根据上下文中的周围单词预测中心词。
CBOW 模型的基本思想是通过上下文中的多个单词来预测当前单词。给定一个长度为 2c 的上下文窗口,当前单词的前 c 个单词和后 c 个单词(包括当前单词),CBOW 模型通过最大化给定上下文单词的条件下中心词的条件概率来训练模型。
假设还是这个句子 “you are a good man”,我们的窗口大小为2,那么如果 a
做为预测单词,那么就会得到一个上下文窗口 [“you” “are” “a” “good”],
假设词典一共有10个单词,并且 “you are a good man” 都在词典中,那么对于上下文窗口 [“you” “are” “a” “good”]
Input 可以这样表示:
y
o
u
=
[
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
]
you=[1,0,0,0,0,0,0,0,0,0]
you=[1,0,0,0,0,0,0,0,0,0]
a r e = [ 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] are=[0,1,0,0,0,0,0,0,0,0] are=[0,1,0,0,0,0,0,0,0,0]
g o o d = [ 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 ] good=[0,0,0,1,0,0,0,0,0,0] good=[0,0,0,1,0,0,0,0,0,0]
Input 聚合表示:
y
o
u
+
a
r
e
+
g
o
o
d
=
[
1
,
1
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
0
]
you+are+good=[1,1,0,1,0,0,0,0,0,0]
you+are+good=[1,1,0,1,0,0,0,0,0,0]
target 可以这样表示:
a
=
[
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
]
a=[0,0,1,0,0,0,0,0,0,0]
a=[0,0,1,0,0,0,0,0,0,0]
那么现在可以进行训练了,CBOW 使用具有单个隐藏层的浅层神经网络。训练过程如下:
- 将每个单词表示为一个 one-hot 向量,其中单词的维度等于词汇表的大小。
- 将上下文的向量表示作为输入,通过一个隐藏层得到中心词的预测概率分布。
- 使用 softmax 函数将预测概率归一化,得到每个单词作为中心词的条件概率。
- 使用交叉熵损失函数计算预测概率与真实中心词的概率分布之间的差异,并通过反向传播算法更新模型参数。
模型如下:
4. 训练结果
(1)我们经过模型的训练之后,是希望得到模型本身吗?
答:否。
我们在这里训练实际上是希望得到输入层到隐藏层的权重矩阵,就是图中的 U,类似一个“查找表“(lookup table)。假设权重 U 为:
U
=
[
0.01
0.23
0.2
.
.
.
0.05
0.02
0.13
0.05
.
.
.
0.01
.
.
.
0.01
0.03
0.22
.
.
.
0.04
]
U=\begin{bmatrix} 0.01 & 0.23 &0.2&...&0.05\\ 0.02&0.13&0.05&...&0.01\\ &&...\\ 0.01&0.03&0.22&...&0.04\\ \end{bmatrix}
U=
0.010.020.010.230.130.030.20.05...0.22.........0.050.010.04
对于
a
r
e
=
[
0
1
0
0
0
0
0
0
0
0
]
are=\begin{bmatrix} 0&1&0&0&0&0&0&0&0&0 \end{bmatrix}
are=[0100000000]
实际上就是选取U矩阵的第2行的结果作为 embedding 向量,表示 “are” 的向量化结果!矩阵U也就是我们训练需要得到的结果了!
(2)那么,为什么这种方式可以捕捉到单词之间的语义关系呢?
答:Word2Vec 经过大规模的语料训练,可以捕捉到单词之间的语义关系的原因主要有两个方面:
-
分布假设(Distributional Hypothesis):
Word2Vec 基于分布假设,即相似的单词在语料库中通常会在相似的上下文中出现。这意味着具有相似语义的单词在文本数据中通常会有类似的分布模式。Word2Vec 模型通过观察单词在上下文中的分布模式来学习单词之间的语义关系。如果两个单词在语料库中的上下文中经常出现在相似的环境中,那么它们的 Word2Vec 向量表示就会在向量空间中更加接近。 -
向量空间中的相对位置关系:
Word2Vec 将单词映射到一个连续的向量空间中,其中每个维度都表示了一个语义特征。在这个向量空间中,具有相似语义的单词通常会在向量空间中更加接近。例如,通过使用 Word2Vec 模型学习的词向量,可以发现 “king” 和 “queen” 的向量之间的差异与 “man” 和 “woman” 的向量之间的差异非常相似。这种相对位置关系可以捕捉到单词之间的语义关系,使得 Word2Vec 能够在向量空间中准确表示单词的语义信息。
Word2Vec 通过学习单词在语料库中的分布模式和语义特征来捕捉单词之间的语义关系。这使得 Word2Vec 能够生成具有丰富语义信息的单词向量表示,可以应用于各种自然语言处理任务中。
5. 如何使用
一旦训练了 Word2Vec 模型并得到了单词的向量表示,你可以将这些向量用于各种自然语言处理任务中。以下是一些常见的用法:
-
词向量相似度计算:
使用训练好的 Word2Vec 模型,你可以计算单词之间的相似度。通过计算词向量之间的余弦相似度或内积等度量,可以找到语义上相似的单词。这在信息检索、词义消歧等任务中非常有用。 -
词语替换:
通过找到与目标单词在向量空间中相似的单词,你可以进行词语替换。这在数据增强、文本修复等任务中常用,可以帮助生成更加多样和合理的文本。 -
文本分类:
可以将单词的向量表示作为输入特征,用于训练文本分类模型。在训练过程中,可以使用预训练的 Word2Vec 模型加载单词向量,并固定这些向量或在训练过程中进行微调。 -
语言模型:
可以使用单词的向量表示构建语言模型,预测下一个单词或下一个句子。Word2Vec 中学习到的单词向量可以作为输入特征,帮助模型更好地理解语义信息。 -
文本生成:
将训练好的 Word2Vec 模型用于文本生成任务中,可以帮助模型生成更加自然和连贯的文本。通过将单词的向量表示输入到生成模型中,可以使模型更好地理解单词之间的语义关系。
这些也是 LLM 的一些基础能力。
6. 延伸
我们在《LLM 为什么需要 tokenizer?》 中介绍了 LLM 需要 Tokenizer,实际上也就是在训练中建立 embedding 向量。
此外,在介绍 Transformer 模型时:
《NLP深入学习:大模型背后的Transformer模型究竟是什么?(一)》
《NLP深入学习:大模型背后的Transformer模型究竟是什么?(二)》
encoding/decoding 输入向量的 Input Embeddings 也是在训练中建立 embedding 向量。这些思想与 Word2Vec 一致。
7. 参考
《Efficient Estimation of Word Representations in Vector Space》
《NLP深入学习:大模型背后的Transformer模型究竟是什么?(一)》
《NLP深入学习:大模型背后的Transformer模型究竟是什么?(二)》
欢迎关注本人,我是喜欢搞事的程序猿;一起进步,一起学习;
欢迎关注知乎/CSDN:SmallerFL
也欢迎关注我的wx公众号(精选高质量文章):一个比特定乾坤