赞
踩
词嵌入(Word embedding)的概念是近年来自然语言处理 ( NLP )领域最引人注目的发展。单词向量是用来表示单词的向量,也可以被认为是单词的特征向量或表示。将单词映射到实向量的技术称为词嵌入。
这篇文章中为您提供了一个简短的概述,并在底部提供了指向其他材料的链接。这篇文章重点介绍三种“经典”的词嵌入风格:Word2Vec、GloVe和FastText。他们举例说明了查看词嵌入的三种不同方式。
Word2Vec始于 2013 年,当时 Tomas Mikolov 周围的谷歌研究人员发表了这篇论文。他们提出了一种方法,著名的Word2Vec。它使用小型神经网络根据单词的上下文计算单词嵌入。有两种具体模型可以实现这种方法。
首先,有continuous bag of words(CBOW,连续词袋模型)。在这种方法中,网络试图根据上下文预测中心词。以文本序列“the”,“man”,“loves”,“his”,“son”为例。让我们选择“love”作为中心词,设置上下文窗口大小为2, 此时神经网络试图根据“the”,“man”,“his”,“son”来预测“love”。
P
(
"loves"
∣
"the"
,
"man"
,
"his"
,
"son"
)
.
P(\textrm{"loves"}\mid\textrm{"the"},\textrm{"man"},\textrm{"his"},\textrm{"son"}).
P("loves"∣"the","man","his","son").
这是怎么预测的呢?
这里其实结合实现来进行说明会更直观,我们刚刚提到Word2Vec。它使用小型神经网络根据单词的上下文计算单词嵌入,这个小型的神经网络如下所示(摘自word2vec Parameter Learning Explained,Xin Rong):
整个模型以contexts中的词为输入,最大化输出中心词的概率。
可以看到上面的示意图,这个模型其实就是两层的神经网络。
W
V
×
N
W_{V\times N }
WV×N是一个V行N列的矩阵,其中V是词典中单词的数量,N是embedding的维度,(注意,尽管上图左侧有多个W符号,实际上是同一个参数矩阵,这里只是表示多个词所以画了了多个分支)
。
CBOW的输入是contexts(记为
o
1
,
.
.
.
,
o
2
m
o_1,...,o_{2m}
o1,...,o2m)的独热编码,然后经过两层相应权重的计算,得到归一化条件概率
P
(
w
c
∣
w
o
1
,
…
,
w
o
2
m
)
=
exp
(
1
2
m
u
c
⊤
(
v
o
1
+
…
,
+
v
o
2
m
)
)
∑
i
∈
V
exp
(
1
2
m
u
i
⊤
(
v
o
1
+
…
,
+
v
o
2
m
)
)
.
P(w_c \mid w_{o_1}, \ldots, w_{o_{2m}}) = \frac{\text{exp}\left(\frac{1}{2m}\mathbf{u}_c^\top (\mathbf{v}_{o_1} + \ldots, + \mathbf{v}_{o_{2m}}) \right)}{ \sum_{i \in \mathcal{V}} \text{exp}\left(\frac{1}{2m}\mathbf{u}_i^\top (\mathbf{v}_{o_1} + \ldots, + \mathbf{v}_{o_{2m}}) \right)}.
P(wc∣wo1,…,wo2m)=∑i∈Vexp(2m1ui⊤(vo1+…,+vo2m))exp(2m1uc⊤(vo1+…,+vo2m)).
式子中
v
o
1
\mathbf{v}_{o1}
vo1表示在
W
V
×
N
W_{V\times N }
WV×N中,第一个context词(比如“the”,“man”,“loves”,“his”,“son”中的“the”)对应的权重,即
W
V
×
N
W_{V\times N }
WV×N中的第
o
1
{o_1}
o1行。
u
c
⊤
\mathbf{u}_c^\top
uc⊤代表在第二个
W
N
×
V
′
W^{'}_{N\times V }
WN×V′中心词loves对应的权重。这个式子其实就对应了上面的神经网络的计算,等价于两层的Perceptron+softmax层(当然在实现中只计算网络中相关的权重,如上面式子展示的那样,我们将在本节最后给出参考代码实现)。
那这个网络的训练目标是什么呢?我们可以很自然地想到,我们希望所有中心词都能被它的context准确的预测(赋予一个很高的概率),如下所示。
∏ t = 1 T P ( w ( t ) ∣ w ( t − m ) , … , w ( t − 1 ) , w ( t + 1 ) , … , w ( t + m ) ) . \prod_{t=1}^{T} P(w^{(t)} \mid w^{(t-m)}, \ldots, w^{(t-1)}, w^{(t+1)}, \ldots, w^{(t+m)}). t=1∏TP(w(t)∣w(t−m),…,w(t−1),w(t+1),…,w(t+m)).
进一步,我们去log并求偏微分,即可使用梯度下降训练这个网络。
−
∑
t
=
1
T
log
P
(
w
(
t
)
∣
w
(
t
−
m
)
,
…
,
w
(
t
−
1
)
,
w
(
t
+
1
)
,
…
,
w
(
t
+
m
)
)
-\sum_{t=1}^T \text{log}\, P(w^{(t)} \mid w^{(t-m)}, \ldots, w^{(t-1)}, w^{(t+1)}, \ldots, w^{(t+m)})
−t=1∑TlogP(w(t)∣w(t−m),…,w(t−1),w(t+1),…,w(t+m))
注意到
log
P
(
w
c
∣
W
o
)
=
u
c
⊤
v
ˉ
o
−
log
(
∑
i
∈
V
exp
(
u
i
⊤
v
ˉ
o
)
)
.
\log\,P(w_c \mid \mathcal{W}_o) = \mathbf{u}_c^\top \bar{\mathbf{v}}_o - \log\,\left(\sum_{i \in \mathcal{V}} \exp\left(\mathbf{u}_i^\top \bar{\mathbf{v}}_o\right)\right).
logP(wc∣Wo)=uc⊤vˉo−log(i∈V∑exp(ui⊤vˉo)).
所以我们可求得梯度
∂
log
P
(
w
c
∣
W
o
)
∂
v
o
i
=
1
2
m
(
u
c
−
∑
j
∈
V
exp
(
u
j
⊤
v
ˉ
o
)
u
j
∑
i
∈
V
exp
(
u
i
⊤
v
ˉ
o
)
)
=
1
2
m
(
u
c
−
∑
j
∈
V
P
(
w
j
∣
W
o
)
u
j
)
.
\frac{\partial \log\, P(w_c \mid \mathcal{W}_o)}{\partial \mathbf{v}_{o_i}} = \frac{1}{2m} \left(\mathbf{u}_c - \sum_{j \in \mathcal{V}} \frac{\exp(\mathbf{u}_j^\top \bar{\mathbf{v}}_o)\mathbf{u}_j}{ \sum_{i \in \mathcal{V}} \text{exp}(\mathbf{u}_i^\top \bar{\mathbf{v}}_o)} \right) = \frac{1}{2m}\left(\mathbf{u}_c - \sum_{j \in \mathcal{V}} P(w_j \mid \mathcal{W}_o) \mathbf{u}_j \right).
∂voi∂logP(wc∣Wo)=2m1⎝⎛uc−j∈V∑∑i∈Vexp(ui⊤vˉo)exp(uj⊤vˉo)uj⎠⎞=2m1⎝⎛uc−j∈V∑P(wj∣Wo)uj⎠⎞.
很重要的一点,然后这个网络是怎么word2vec的呢?
注意到 W V × N W_{V\times N } WV×N其实是有V个行向量组成,经过大量语料的训练,CBOW方法直接将 W V × N W_{V\times N } WV×N中的每一行作为相应词的向量表示,也就是说通常使用context word vector作为单词表示。
那为什么可以这样做呢?一个直观的解释就是某个词作为context在训练过程中,实际上在不断的预测它的所有的可能的中心词,也就是说,当训练完成后,将该词的行向量输入到后一层的Perceptron中,就可以赋予与它相关中心词很高的输出概率。而word2vec的哲学思想
就是一个词的语义是由与它相关的词定义的。很明显,
W
V
×
N
W_{V\times N }
WV×N中的行向量已经聚合了与它相关的中心词的信息(因为可以给这些中心词赋予很高的概率),因此我们可以将该向量作为词的向量表示。
代码实现
: 引自SeanLee97, github地址
Skip-Gram模型与CBOW相反,网络试图根据中心词预测上下文。采取文本序列“the”, “man”, “loves”, “his”, “son”作为一个例子。让我们选择“loves”作为中心词,并将上下文窗口大小设置为2.其中一个例子是我们希望最大化以下概率。
P ( "the" , "man" , "his" , "son" ∣ "loves" ) . P(\textrm{"the"},\textrm{"man"},\textrm{"his"},\textrm{"son"}\mid\textrm{"loves"}). P("the","man","his","son"∣"loves").
其实Skip-gram的网络与CBOW是类似的,如下图所示
(注意,尽管上图右侧有多个W符号,实际上是同一个参数矩阵,这里只是表示多个词所以画了了多个分支)
因此相似地,根据以上的网络计算给定中心词,预测上下文单词的条件概率公式为
P ( w o ∣ w c ) = exp ( u o ⊤ v c ) ∑ i ∈ V exp ( u i ⊤ v c ) , P(w_o \mid w_c) = \frac{\text{exp}(\mathbf{u}_o^\top \mathbf{v}_c)}{ \sum_{i \in \mathcal{V}} \text{exp}(\mathbf{u}_i^\top \mathbf{v}_c)}, P(wo∣wc)=∑i∈Vexp(ui⊤vc)exp(uo⊤vc),
同样我们的目标函数也是最大化所有中心词预测其context的概率
∏
t
=
1
T
∏
−
m
≤
j
≤
m
,
j
≠
0
P
(
w
(
t
+
j
)
∣
w
(
t
)
)
,
\prod_{t=1}^{T} \prod_{-m \leq j \leq m,\ j \neq 0} P(w^{(t+j)} \mid w^{(t)}),
t=1∏T−m≤j≤m, j=0∏P(w(t+j)∣w(t)),
这等价于最小化
−
∑
t
=
1
T
∑
−
m
≤
j
≤
m
,
j
≠
0
log
P
(
w
(
t
+
j
)
∣
w
(
t
)
)
.
- \sum_{t=1}^{T} \sum_{-m \leq j \leq m,\ j \neq 0} \text{log}\, P(w^{(t+j)} \mid w^{(t)}).
−t=1∑T−m≤j≤m, j=0∑logP(w(t+j)∣w(t)).
同样地可以通过求梯度来训练网络。
很重要的一点,然后这个网络是怎么word2vec的呢?
与CBOW相反,Skip-gram使用center word vectors作为词的向量表示。因为两种方法的输入输出事实上是相反的,尽管CBOW使用context word vector,Skip-gram使用center word vectors,实际上都是两层神经网络中第一层的权重。
代码实现
: 引自SeanLee97, github地址
回想上面两种方法的计算,其实都涉及了softmax的计算,由于softmax操作的性质,由于上下文单词可以是字典V中的任何词,因此计算Skip-gram模型中的 P ( w o ∣ w c ) = exp ( u o ⊤ v c ) ∑ i ∈ V exp ( u i ⊤ v c ) P(w_o \mid w_c) = \frac{\text{exp}(\mathbf{u}_o^\top \mathbf{v}_c)}{ \sum_{i \in \mathcal{V}} \text{exp}(\mathbf{u}_i^\top \mathbf{v}_c)} P(wo∣wc)=∑i∈Vexp(ui⊤vc)exp(uo⊤vc)时,分母中需要包含所有乘积的总和。因此,skip-gram模型和CBOW模型的梯度计算都包含求和。不幸的是,在一个大字典(通常有数十万或数百万个单词)上累加这种梯度的计算成本非常高。
所以在具体实现中通常需要摆脱分母softmax的求和项,但是也必须将
P
(
w
o
∣
w
c
)
P(w_o \mid w_c)
P(wo∣wc)规范化到[0,1]
。出于这个考虑,人们提出了两种具体算法。
A. Negative Sampling负采样
负采样的流程(以skip-gram的负采样为例,负采样设计原理见下,可粗略浏览该流程,再上下对比):
获取中心词和它的上下文单词( w o 1 . . . , w o i , . . . w o N ) w_{o1}...,w_{oi},...w_{oN}) wo1...,woi,...woN)
对于每一个上下文单词 w o i w_{oi} woi,从词典中采样K个跟中心词无关的词(即不为中心词的任何上下文)
定义以下概率
P
(
D
=
1
∣
w
c
,
w
o
)
=
σ
(
u
o
⊤
v
c
)
P(D=1\mid w_c, w_o) = \sigma(\mathbf{u}_o^\top \mathbf{v}_c)
P(D=1∣wc,wo)=σ(uo⊤vc)
P
(
D
=
0
∣
w
(
t
)
,
w
k
)
=
1
−
σ
(
u
h
k
⊤
v
i
t
)
P(D=0\mid w^{(t)}, w_k)=1-\sigma(\mathbf{u}_{h_k}^\top \mathbf{v}_{i_t})
P(D=0∣w(t),wk)=1−σ(uhk⊤vit)
其中,D=1表示两词为中心词和上下文单词关系,D=0表示负采样样本和中心词的关系。其中
σ
表
示
s
i
g
m
o
i
d
函
数
σ
(
x
)
=
1
1
+
exp
(
−
x
)
.
\sigma 表示sigmoid函数 \sigma(x) = \frac{1}{1+\exp(-x)}.
σ表示sigmoid函数σ(x)=1+exp(−x)1.
自然地,我们希望当输入中心词时,网络输出上下文单词的相关概率
P
(
D
=
1
∣
w
c
,
w
o
)
P(D=1\mid w_c, w_o)
P(D=1∣wc,wo)接近于1,
P
(
D
=
0
∣
w
(
t
)
,
w
k
)
P(D=0\mid w^{(t)}, w_k)
P(D=0∣w(t),wk)也接近于1(因为1-相应概率的缘故),因此可以重新定义给定中心词,输出某个上下文单词的最终条件概率为(也就是我们把原始的目标函数赋值给该条件概率):
P
(
w
(
t
+
j
)
∣
w
(
t
)
)
=
P
(
D
=
1
∣
w
(
t
)
,
w
(
t
+
j
)
)
∏
k
=
1
,
w
k
∼
P
(
w
)
K
P
(
D
=
0
∣
w
(
t
)
,
w
k
)
.
P(w^{(t+j)} \mid w^{(t)}) =P(D=1\mid w^{(t)}, w^{(t+j)})\prod_{k=1,\ w_k \sim P(w)}^K P(D=0\mid w^{(t)}, w_k).
P(w(t+j)∣w(t))=P(D=1∣w(t),w(t+j))k=1, wk∼P(w)∏KP(D=0∣w(t),wk).
因此对于单条样本,为取消连乘操作,我们的目标函数变为
−
log
P
(
w
(
t
+
j
)
∣
w
(
t
)
)
=
−
log
P
(
D
=
1
∣
w
(
t
)
,
w
(
t
+
j
)
)
−
∑
k
=
1
,
w
k
∼
P
(
w
)
K
log
P
(
D
=
0
∣
w
(
t
)
,
w
k
)
=
−
log
σ
(
u
i
t
+
j
⊤
v
i
t
)
−
∑
k
=
1
,
w
k
∼
P
(
w
)
K
log
(
1
−
σ
(
u
h
k
⊤
v
i
t
)
)
=
−
log
σ
(
u
i
t
+
j
⊤
v
i
t
)
−
∑
k
=
1
,
w
k
∼
P
(
w
)
K
log
σ
(
−
u
h
k
⊤
v
i
t
)
.
为什么negative sampling work?
我们回顾以下整个网络的缺点:
我们可以把整个网络的训练视作一个多分类问题,比如在Skip-gram里,就是输入中心词,输出context单词。也就是说,这样的网络只是一个“标准”多类分类器(每个单词作为一类)。并且该网络必须具有与存在的类别一样多的输出神经元。由于类别是实际的单词,所以神经元数量是巨大的。
多分类神经网络通常具有交叉熵损失函数,该交叉熵损失函数需要输出神经元的值来表示概率 。这意味着由每个类计算的网络计算的输出“得分”必须归一化,转换为每个类的实际概率。通过SoftMax功能实现该归一化步骤。当施加到巨大的输出层时,Softmax非常昂贵(上面已经提过)。
因此,negative sampling简化softmax计算的基本思想是将多项类问题到二分类问题,也就是直接判断某个词跟输入的中心词是不是相关的(对应上面公式的0和1),因此这时目标函数应该最大化相关的输出概率
σ
(
u
o
⊤
v
c
)
\sigma(\mathbf{u}_o^\top \mathbf{v}_c)
σ(uo⊤vc),最小化不相关的
σ
(
u
h
k
⊤
v
i
t
)
\sigma(\mathbf{u}_{h_k}^\top \mathbf{v}_{i_t})
σ(uhk⊤vit), 这恰恰对应最大化在上面定义的
P
(
w
(
t
+
j
)
∣
w
(
t
)
)
=
P
(
D
=
1
∣
w
(
t
)
,
w
(
t
+
j
)
)
∏
k
=
1
,
w
k
∼
P
(
w
)
K
P
(
D
=
0
∣
w
(
t
)
,
w
k
)
.
P(w^{(t+j)} \mid w^{(t)}) =P(D=1\mid w^{(t)}, w^{(t+j)})\prod_{k=1,\ w_k \sim P(w)}^K P(D=0\mid w^{(t)}, w_k).
P(w(t+j)∣w(t))=P(D=1∣w(t),w(t+j))k=1, wk∼P(w)∏KP(D=0∣w(t),wk).
这时我们不使用SoftMax来估计输出词的概率,而是使用sigmoid函数判断是不是相关(这是一种任务的重新定义)。而且这个时候,我们可以不用计算所有负样本(与中心词无关的词)的概率,而是通过部分采样负样本来进行模拟,实验证明同样可以到达很好的效果。这就是称为负采样的原因。
skip-gram的负采样实现:
gihub链接
cbow的负采样实现:
gihub链接
具体的,以skip-gram为例,
在标准的非优化实现中,模型的输入输出为(一个中心词的独热编码,一个上下文单词的softmax概率)
在负采样实现中,模型的输入和输出为 (一个中心词的独热编码,一个上下文单词和多个负样本的sigmoid概率)
在CBOW中
在标准的非优化实现中,模型的输入输出为(w个上下文单词的独热编码,一个中心词的softmax概率),其中,w为上下文窗口的大小。
在负采样实现中,模型的输入输出为(w个上下文单词的独热编码,一个中心词和w*n个负样本的sigmoid概率),其中n为一个上下文单词对应的负样本的个数。
在CBOW中,负样本指的是与输入的上下文单词不是中心词-上下文单词关系的其他词语。需要注意的是
,在CBOW中,我们一次输入w个上下文单词,这是为了提升效率,因为其效果跟依次输入w个(上下文单词,中心词)样本是一样的。
A. hirarchical softamx
这种方法根据词频建立词典的哈夫曼编码树,树的每个叶节点代表字典中的一个单词,如下所示。它为每个叶子节点赋予一个向量。为每个内部节点也赋予一个向量。
注意所有叶子节点对应一个单词,这个单词对应一个哈夫曼编码,比如
w
3
w_3
w3是010, 这对应着三条边。我们再negative sampling中提到未经优化下的网络实际上是一个多分类任务,有多少类就有多少个输出神经元。
在层次softmax中,实施上是将多分类任务转换成了路径判断任务,也就是从根节点出发,不断地判断向左走还是向右走,最终走到一个叶子节点,我们希望根据最大概率选择路径最终是走到目标节点地(比如以上下文单词作为输入,希望走到中心词的路径概率是最大的。
根据上面的解释,我们输入上下文单词 w c w_c wc,它对应的词向量为 v c v_c vc,若 w 3 w_3 w3是中心词,我们希望最大化得到中心词的路径概率。此外,我们在第二层网络层中,每个权重不对应单词,而是对应哈夫曼编码树的一个内部节点,我们使用 u n ( w 3 , 1 ) \mathbf{u}_{n(w_3, 1)} un(w3,1)表示到达 w 3 w_3 w3的路径上第一个内部节点的向量表示(即第二层网络的权重), σ ( u n ( w 3 , 1 ) ⊤ v c ) \sigma(\mathbf{u}_{n(w_3, 1)}^\top \mathbf{v}_c) σ(un(w3,1)⊤vc)表示在输入 w c w_c wc的情况下,从该内部节点向左走到达中心词的概率。
以此类推,从
w
c
w_c
wc预测
w
3
w_3
w3的条件概率就是
P
(
w
3
∣
w
c
)
=
σ
(
u
n
(
w
3
,
1
)
⊤
v
c
)
⋅
σ
(
−
u
n
(
w
3
,
2
)
⊤
v
c
)
⋅
σ
(
u
n
(
w
3
,
3
)
⊤
v
c
)
.
P(w_3 \mid w_c) = \sigma(\mathbf{u}_{n(w_3, 1)}^\top \mathbf{v}_c) \cdot \sigma(-\mathbf{u}_{n(w_3, 2)}^\top \mathbf{v}_c) \cdot \sigma(\mathbf{u}_{n(w_3, 3)}^\top \mathbf{v}_c).
P(w3∣wc)=σ(un(w3,1)⊤vc)⋅σ(−un(w3,2)⊤vc)⋅σ(un(w3,3)⊤vc).
它抛弃了softmax中的全部求和项,只需计算以哈夫曼编码对应的那几个内部节点即可。我们将最大化上述条件概率作为目标函数以训练网络,最终就可得到单词的向量表示。
同时它保证了概率归一化,因为对于每一层的节点,都有 σ ( x ) + σ ( − x ) = 1 \sigma(x) + \sigma(-x) = 1 σ(x)+σ(−x)=1,因此容易证明它能够使概率归一化。
2014年,斯坦福大学的研究人员发表了GloVe,GloVe是global vector的简写。
我们知道,Word2Vec 通过将目标词与其上下文相关联来学习嵌入。但是,它忽略了某些上下文词是否比其他词出现得更频繁。上下文窗口中的词-词共现可能携带丰富的语义信息。例如,在大型语料库中,单词solid比steam更容易与ice同时出现,而单词gas可能比ice更容易与steam同时出现。这种共现的全局语料库统计可以预先计算,这可以带来更有效的训练。
相比之下,GloVe强调同时出现的频率是至关重要的信息,不应“浪费”作为额外的训练示例。相反,GloVe 以一种词向量的组合与这些词在语料库中同时出现的概率直接相关的方式构建词嵌入。可以这样理解,GloVe其实是在Skip-gram的基础上加入了全局的共现信息。
回想在skip-gram中,给定中心词
w
i
w_i
wi,其上下文单词
w
j
w_j
wj的条件概率为
q
i
j
=
exp
(
u
j
⊤
v
i
)
∑
k
∈
V
exp
(
u
k
⊤
v
i
)
,
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)},
qij=∑k∈Vexp(uk⊤vi)exp(uj⊤vi),
我们希望最小化以下概率(加入了全局共现频率)
− ∑ i ∈ V ∑ j ∈ V x i j log q i j . -\sum_{i\in\mathcal{V}}\sum_{j\in\mathcal{V}} x_{ij} \log\,q_{ij}. −i∈V∑j∈V∑xijlogqij.
细想,这个损失函数其实就相当于加入了权重,给定词 w i , w j w_i,w_j wi,wj,如果他们的共现频率 x i j x_{ij} xij较高,那么其对应的 − l o g q i j -log q_{ij} −logqij就会对整体的损失函数影响较大,根据梯度下降优化算法,模型会比其他词对更倾向于调整权重以得到更小的 − l o g q i j -log q_{ij} −logqij,即更大的 q i j q_{ij} qij,这个符合我们的初衷,即共现频率更大的词 w i , w j w_i,w_j wi,wj, 若以 w i w_i wi作为输入,输出 w j w_j wj的概率应该更大。
那原来的skip-gram网络是否就学不到这种分布信息呢?由于 w j w_j wj的条件概率是由两个权重决定的,即 u j ⊤ v i \mathbf{u}_j^\top \mathbf{v}_i uj⊤vi,网络训练的过程就是不断调整这两个权重来是的目标函数最大化(损失函数最小化),如果我们在训练集中共现频率高的作为训练语料的次数也多,那么从个人浅薄的认识来看,即使是两层的权重也是可以在一定程度上学习这种分布的。可能Glovec从目标函数上进行修改,能够进一步加强这个能力。
转回来,我们可以对损失函数做进一步的优化,上述式子可以改写为
− ∑ i ∈ V x i ∑ j ∈ V p i j log q i j . -\sum_{i\in\mathcal{V}} x_i \sum_{j\in\mathcal{V}} p_{ij} \log\,q_{ij}. −i∈V∑xij∈V∑pijlogqij.
其中
p
i
j
=
x
i
j
/
x
i
p_{ij}=x_{ij}/x_i
pij=xij/xi,表示统计概率,
q
i
j
q_{ij}
qij意义不变,表示预测概率。显然,
−
∑
j
∈
V
p
i
j
log
q
i
j
-\sum_{j\in\mathcal{V}} p_{ij} \log\,q_{ij}
−∑j∈Vpijlogqij实际上是在计算两个分布的交叉熵。原论文中提到交叉熵损失函数有一个不幸的特性,即长尾分布的建模往往很差,对不可能发生的事件赋予了太多的权重。此外,为了使测度有界,需要对模型分布q进行适当的softmax归一化。由于Eqn中整个词汇表的总和,这造成了计算瓶颈。因此原作者将该损失函数改为了方差损失,并且将模型输出概率的计算中去掉softmax,为了度量一致,
p
i
j
p_{ij}
pij也减去归一化因子,如下所示
p
i
j
′
=
x
i
j
,
q
i
j
′
=
exp
(
u
j
⊤
v
i
)
p'_{ij}=x_{ij},q'_{ij}=\exp(\mathbf{u}_j^\top \mathbf{v}_i)
pij′=xij,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
因此,损失函数变为
∑
i
∈
V
∑
j
∈
V
h
(
x
i
j
)
(
u
j
⊤
v
i
+
b
i
+
c
j
−
log
x
i
j
)
2
.
\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.
i∈V∑j∈V∑h(xij)(uj⊤vi+bi+cj−logxij)2.
其中, h ( x ) = ( x / c ) α h(x) = (x/c) ^\alpha h(x)=(x/c)α是关于 x x x的递增函数。至于为什么这里相比于方差多了两个量 b i , c j b_i,c_j bi,cj呢?这是作者提出的另一个设计所带来的。
考虑下面一种情况
设
w
i
=
i
c
e
,
w
j
=
c
r
e
a
m
w_i=ice,w_j=cream
wi=ice,wj=cream,对于一个与“ice”相关但与“steam”无关的单词
w
k
w_k
wk,例如
w
k
w_k
wk=solid,我们预期其共现概率的比更大,例如8.9,相反则更小。因此我们定义一个函数来模拟这个比值\frac{p_{ij}}{p_{ik}}。如下
f ( u j , u k , v i ) = exp ( u j ⊤ v i ) exp ( u k ⊤ v i ) ≈ p i j p i k . 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}}. f(uj,uk,vi)=exp(uk⊤vi)exp(uj⊤vi)≈pikpij.
上式中应该有
exp
(
u
j
⊤
v
i
)
≈
α
p
i
j
(
1
)
\exp\left(\mathbf{u}_j^\top {\mathbf{v}}_i\right) \approx \alpha p_{ij}(1)
exp(uj⊤vi)≈αpij(1),其中
α
\alpha
α是常数,由于
p
i
j
=
x
i
j
/
x
i
p_{ij}=x_{ij}/x_i
pij=xij/xi,我们对式子(1)取对数后有
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
j
\log\,\alpha + \log\,x_{ij}
logα+logxij视为一个偏置项,即可得到
u
j
⊤
v
i
+
b
i
+
c
j
≈
log
x
i
j
.
\mathbf{u}_j^\top \mathbf{v}_i + b_i + c_j \approx \log\, x_{ij}.
uj⊤vi+bi+cj≈logxij.
因此,损失函数变为
∑
i
∈
V
∑
j
∈
V
h
(
x
i
j
)
(
log
p
i
j
′
−
log
q
i
j
′
)
2
=
∑
i
∈
V
∑
j
∈
V
h
(
x
i
j
)
(
u
j
⊤
v
i
+
b
i
+
c
j
−
log
x
i
j
)
2
.
\sum_{i\in\mathcal{V}} \sum_{j\in\mathcal{V}} h(x_{ij}) \left(\log\,p'_{ij} - \log\,q'_{ij}\right)^2=\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.
i∈V∑j∈V∑h(xij)(logpij′−logqij′)2=i∈V∑j∈V∑h(xij)(uj⊤vi+bi+cj−logxij)2.
2016 年,人工神经网络获得了相当大的关注,Word2Vec 已在 NLP 的许多领域证明了它的实用性。然而,有一个未解决的问题:对未知词的泛化。FastText ——Facebook 于 2016 年发布的开发项目——承诺克服这一障碍。
FastText与 Word2Vec 非常相似,但有很大的不同。FastText不是使用单词来构建单词嵌入,而是更深一层。由部分单词和字符组成,也就是subword embedding。比如数字1001这个词将会被分割为100 ##1,并分别进行embedding,同样英文单词也会分割两两部分,分布进行embedding。也就是说不在是进行完整的词嵌入,而是子词(subword)嵌入。
FastText 输出的词嵌入看起来与 Word2Vec 提供的词嵌入非常相似。但是,它们不是直接计算的。相反,它们是低级嵌入的组合。
这种方法有两个主要优点。首先,只要新词与已知词具有相同的特征,就可以进行泛化,减少出现OOV情况。其次,需要更少的训练数据,因为可以从每段文本中提取更多信息。这就是为什么有比其他嵌入算法更多的语言的预训练FastText 模型。
这三种算法,代表了关于如何计算词嵌入的三种一般思想:
Word2Vec将文本作为神经网络的训练数据。生成的嵌入捕获单词是否出现在相似的上下文中。
GloVe专注于在整个语料库中同时出现的单词。它的嵌入与两个单词一起出现的概率有关。
FastText通过考虑单词部分来改进 Word2Vec。这个技巧可以在较小的数据集上训练嵌入并泛化到未知单词。
目前预训练模型BERT对于词语的表示是效果更好的,但是并不是在所有情况下都能支持BERT的预训练词向量,比如在c端或小型机器上,简单的词嵌入方法仍可以应用,因此是值得去仔细地学习的。
[1].https://github.com/SeanLee97
[2] https://d2l.ai/chapter_natural-language-processing-pretraining/glove.html
[3] https://www.youtube.com/watch?v=pzyIWCelt_E&t=1035s&ab_channel=ChrisMcCormickAI
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。