1.背景
2013年,Google开源了一款用于词向量计算的工具—word2vec,引起了工业界和学术界的关注。首先,word2vec可以在百万数量级的词典和上亿的数据集上进行高效地训练;其次,该工具得到的训练结果——词向量(word embedding),可以很好地度量词与词之间的相似性。随着深度学习在自然语言处理中应用的普及,很多人误以为word2vec是一种深度学习算法。其实word2vec算法的背后是一个浅层神经网络。另外需要强调的一点是,word2vec是一个计算word vector的开源工具。当我们在说word2vec算法或模型的时候,其实指的是其背后用于计算word vector的CBoW模型和Skip-gram模型。
2.统计语言模型
什么是统计语言模型呢?
简单来说,统计语言模型就是用来计算一个句子的概率的概率模型,它通常基于一个语料库来构建。
如何计算一段文本序列在某种语言下出现的概率?
例如,在机器翻译的问题中,如果我们知道了目标语言中每句话的概率,就可以从候选集合中挑选出最合理的句子做为翻译结果返回。
统计语言模型给出了这一类问题的一个基本解决框架。对于一段文本序列
S
=
w
1
,
w
2
,
.
.
.
,
w
T
S=w_1, w_2, ... , w_T
S=w1,w2,...,wT , 它的概率可以表示为:
P
(
S
)
=
P
(
w
1
,
w
2
,
.
.
.
,
w
T
)
=
∏
t
=
1
T
p
(
w
t
∣
w
1
,
w
2
,
.
.
.
,
w
t
−
1
)
P(S)=P(w_1, w_2, ..., w_T)=\prod_{t=1}^Tp(w_t|w_1, w_2, ..., w_{t-1})
P(S)=P(w1,w2,...,wT)=t=1∏Tp(wt∣w1,w2,...,wt−1)
即将序列的联合概率转化为一系列条件概率的乘积。问题变成了如何去预测这些给定previous words下的条件概率:
p
(
w
t
∣
w
1
,
w
2
,
.
.
.
,
w
t
−
1
)
p(w_t|w_1,w_2,...,w_{t-1})
p(wt∣w1,w2,...,wt−1)。 一般来说,语言模型都是为了使得条件概率
p
(
w
t
∣
w
1
,
w
2
,
.
.
.
,
w
t
−
1
)
p(w_t|w_1,w_2,...,w_{t-1})
p(wt∣w1,w2,...,wt−1) 最大化,不过考虑到近因效应,当前词只与距离它比较近的n个词更加相关(一般n不超过5),而非前面所有的词都有关。 上述公式可以近似为:
p
(
w
t
∣
w
1
,
w
2
,
.
.
.
,
w
t
−
1
)
≈
p
(
w
t
∣
w
t
−
(
n
+
1
)
,
.
.
.
,
w
t
−
1
)
p(w_t|w_1, w_2, ..., w_{t-1}) \approx p(w_t|w_{t-(n+1)}, ..., w_{t-1})
p(wt∣w1,w2,...,wt−1)≈p(wt∣wt−(n+1),...,wt−1)
N-gram模型仍有其局限性。
-
首先,由于参数空间的爆炸式增长,它无法处理更长程的context( N > 3 N>3 N>3)。
-
其次,它没有考虑词与词之间内在的联系性。
- 例如:“the cat is walking in the bedroom"这句话。如果在训练语料中看到了很多类似“the dog is walking in the bedroom”或是“the cat is running in the bedroom”这样的句子;那么,哪怕此前没有见过这句话"the cat is walking in the bedroom”,也可以从“cat”和“dog”(“walking”和“running”)之间的相似性,推测出这句话的概率。
然而, Ngram模型做不到。 因为Ngram本质上是将词当做一个个孤立的原子单元(atomic unit)去处理的。这种处理方式对应到数学上的形式是一个个离散的one-hot向量(除了一个词典索引的下标对应的方向上是1,其余方向上都是0)。 例如:对于一个大小为5的词典:{“I”, “love”, “nature”, “luaguage”, “processing”},其中的“nature”对应的one-hot向量为: [ 0 , 0 , 1 , 0 , 0 ] [0,0,1,0,0] [0,0,1,0,0]。显然,one-hot向量的维度等于词典的大小。 在动辄上万甚至百万词典的实际应用中,面临着巨大的维度灾难问题(The Curse of Dimensionality)。
3.神经语言模型
NNLM最初由Bengio在2003年发表的一篇论文《A Neural Probabilistic Language Mode》中提出来的,word2vec便是从其中简化训练而来。
NNLM模型的基本思想可以概括如下:
- 假定词表中的每一个word都对应着一个连续的特征向量;
- 假定一个连续平滑的概率模型,输入一段词向量的序列,可以输出这段序列的联合概率;
- 同时学习词向量的权重和概率模型里的参数。
将整个模型拆分成两部分加以理解:
- 一个线性的Embedding层
- 将输入的 N − 1 N−1 N−1个one-hot词向量,通过一个共享的 D × V D×V D×V的矩阵 C C C,映射为 N − 1 N−1 N−1个分布式的词向量(distributed vector)。其中, V V V是词典的大小, D D D是Embedding向量的维度(一个先验参数)。C矩阵里存储了要学习的word vector。
- 一个简单的前向反馈神经网络 g g g
- 它由一个tanh隐层和一个softmax输出层组成。通过将Embedding层输出的 N − 1 N−1 N−1个词向量映射为一个长度为 V V V的概率分布向量,从而对词典中的word在输入context下的条件概率做出预估: p ( w i ∣ w 1 , w 2 , . . . , w t − 1 ) ≈ f ( w i , w t − 1 , . . . , w t − n + 1 ) = g ( w i , C ( w t − n + 1 ) , . . . , C ( w t − 1 ) ) p(w_i|w_1,w_2,...,w_{t-1}) \approx f(w_i, w_{t-1}, ..., w_{t-n+1}) = g(w_i, C(w_{t-n+1}), ..., C(w_{t-1})) p(wi∣w1,w2,...,wt−1)≈f(wi,wt−1,...,wt−n+1)=g(wi,C(wt−n+1),...,C(wt−1))
通过最小化一个cross-entropy的正则化损失函数来调整模型的参数
θ
\ \theta
θ:
L
(
θ
)
=
1
T
∑
t
log
f
(
w
t
,
w
t
−
1
,
.
.
.
,
w
t
−
n
+
1
)
+
R
(
θ
)
L(\theta)=\frac{1}{T}\sum_t{\log{f(w_t, w_{t-1}, ..., w_{t-n+1})}}+R(\theta)
L(θ)=T1t∑logf(wt,wt−1,...,wt−n+1)+R(θ)
其中,模型的参数
θ
\theta
θ 包括了Embedding层矩阵
C
C
C 的元素,和前向反馈神经网络模型
g
g
g 里的权重。这是一个巨大的参数空间。
在用SGD学习更新模型的参数时,并不是所有的参数都需要调整(例如未在输入的context中出现的词对应的词向量)。计算的瓶颈主要是在softmax层的归一化函数上(需要对词典中所有的word计算一遍条件概率)。
神经语言模型解决了两个问题:
- 统计语言模型里关注的条件概率 p ( w t ∣ c o n t e x t ) p(w_t|context) p(wt∣context)的计算
- 向量空间模型里关注的词向量的表达
通过引入连续的词向量和平滑的概率模型,使得可以在一个连续空间里对序列概率进行建模,从而从根本上缓解数据稀疏性和维度灾难的问题。另一方面,以条件概率 p ( w t ∣ c o n t e x t ) p(w_t|context) p(wt∣context)为学习目标去更新词向量的权重,具有更强的导向性。
4.CBOW & Skip-gram Model
NNLM存在的几个问题:
- NNLM模型只能处理定长的序列。 在03年的论文里,Bengio等人将模型能够一次处理的序列长度N提高到了5,虽然相比bigram和trigram已经是很大的提升,但依然缺少灵活性。
- NNLM的训练太慢了。 即便是在百万量级的数据集上,即便是借助了40个CPU进行训练,NNLM也需要耗时数周才能给出一个稍微靠谱的解来。
这时Mikolov注意到,原始的NNLM模型的训练其实可以拆分成两个步骤:
- 用一个简单模型训练出连续的词向量;
- 基于词向量的表达,训练一个连续的Ngram神经网络模型。
而NNLM模型的计算瓶颈主要是在第二步。
如果我们只是想得到word的连续特征向量,是不是可以对第二步里的神经网络模型进行简化呢?
Mikolov是这么想的,也是这么做的。他在2013年一口气推出了两篇paper,并开源了一款计算词向量的工具——至此,word2vec横空出世,主角闪亮登场。
在word2vec中提出了两个模型(假设上下文窗口为3,图来自2013年Mikolov的原始论文,注意这里没有隐藏层,只有输入层、投影层、输出层,且输入层到投影层不带权重,投影层到输出层带权重)
-
CBOW(Continuous Bag-of-Word):以上下文词汇预测当前词,即用 w t − 2 、 w t − 1 、 w t + 1 、 w t + 2 w_{t-2}、w_{t-1}、w_{t+1}、w_{t+2} wt−2、wt−1、wt+1、wt+2去预测 w t w_{t} wt。
-
SkipGram:以当前词预测其上下文词汇,即用 w t w_{t} wt去预测 w t − 2 、 w t − 1 、 w t + 1 、 w t + 2 w_{t-2}、w_{t-1}、w_{t+1}、w_{t+2} wt−2、wt−1、wt+1、wt+2。
5.基于Hierarchical Softmax的模型
5.1 基本介绍
传统的神经网络词向量语言模型,里面一般有三层,输入层(词向量),隐藏层和输出层(softmax层)。最大的问题在于从隐藏层到输出的softmax层的计算量很大,因为要计算所有词的softmax概率,再去找概率最大的值。这个模型如下图所示。其中 V V V是词汇表的大小,
word2vec对这个模型做了改进,
-
首先,对于从输入层到隐藏层的映射,没有采取神经网络的线性变换加激活函数的方法,而是采用简单的对所有输入词向量求和并取平均的方法。
- 输入的是三个4维词向量: ( 1 , 2 , 3 , 4 ) , ( 9 , 6 , 11 , 8 ) , ( 5 , 10 , 7 , 12 ) (1,2,3,4),(9,6,11,8),(5,10,7,12) (1,2,3,4),(9,6,11,8),(5,10,7,12),那么word2vec映射后的词向量就是 ( 5 , 6 , 7 , 8 ) (5,6,7,8) (5,6,7,8)。由于这里是从多个词向量变成了一个词向量。
-
从隐藏层到输出的softmax层这里的计算量做改进。
-
为了避免要计算所有词的softmax概率,word2vec采样了霍夫曼树来代替从隐藏层到输出softmax层的映射。
Q: 如何映射呢?
由于把之前所有都要计算的从输出softmax层的概率计算变成了一颗二叉霍夫曼树,那么softmax概率计算只需要沿着树形结构进行就可以了。如下图所示,沿着霍夫曼树从根节点一直走到叶子节点的词 w 2 w_2 w2。
与神经网络语言模型相比,霍夫曼树的所有内部节点就类似之前神经网络隐藏层的神经元, 其中,根节点的词向量对应投影后的词向量,而所有叶子节点就类似于神经网络softmax输出层的神经元,叶子节点的个数就是词汇表的大小。在霍夫曼树中,隐藏层到输出层的softmax映射不是一下子完成的,而是沿着霍夫曼树一步步完成的,因此这种softmax取名为"Hierarchical Softmax"。
Q: 如何“沿着霍夫曼树一步步完成”呢?
在word2vec中,采用了二元逻辑回归的方法,即规定沿着左子树走,那么就是负类(霍夫曼树编码1),沿着右子树走,那么就是正类(霍夫曼树编码0)。判别正类和负类的方法是使用sigmoid函数,即:
P
(
+
)
=
σ
(
x
w
T
θ
)
=
1
1
+
e
−
x
w
T
θ
P(+) = \sigma(x_w^T\theta) = \frac{1}{1+e^{-x_w^T\theta}}
P(+)=σ(xwTθ)=1+e−xwTθ1
其中
x
w
x_w
xw 是当前内部节点的词向量,而
θ
\theta
θ 则是需要从训练样本求出的逻辑回归的模型参数。
Q: 使用霍夫曼树有什么好处呢?
- 由于是二叉树,之前计算量为 V V V,现在变成了 l o g 2 V log_2V log2V。
- 由于使用霍夫曼树是高频的词靠近树根,这样高频词需要更少的时间会被找到,这符合我们的贪心优化思想。
容易理解,被划分为左子树而成为负类的概率为 P ( − ) = 1 − P ( + ) P(−)=1−P(+) P(−)=1−P(+)。在某一个内部节点,要判断是沿左子树还是右子树走的标准就是看 P ( − ) , P ( + ) P(−),P(+) P(−),P(+)谁的概率值大。 而控制 P ( − ) , P ( + ) P(−),P(+) P(−),P(+)谁的概率值大的因素一个是当前节点的词向量,另一个是当前节点的模型参数 θ \theta θ(从公式里就能看出来)。
对于上图中的 w 2 w_2 w2,如果它是一个训练样本的输出,那么我们期望对于里面的隐藏节点 n ( w 2 , 1 ) n(w_2,1) n(w2,1) 的 P ( − ) P(−) P(−) 概率大, n ( w 2 , 2 ) ) n(w_2,2)) n(w2,2)) 的 P ( − ) P(−) P(−) 概率大, n ( w 2 , 3 ) n(w_2,3) n(w2,3) 的 P ( + ) P(+) P(+) 概率大。
目标就是找到合适的所有节点的词向量和所有内部节点 θ \theta θ, 使训练样本达到最大似然。那么如何达到最大似然呢?
5.2 梯度计算
使用最大似然法来寻找所有节点的词向量和所有内部节点
θ
\theta
θ。先拿上面的
w
2
w_2
w2 例子来看,我们期望最大化下面的似然函数:
∏
i
=
1
3
P
(
n
(
w
i
)
,
i
)
=
(
1
−
1
1
+
e
−
x
w
T
θ
1
)
(
1
−
1
1
+
e
−
x
w
T
θ
2
)
1
1
+
e
−
x
w
T
θ
3
\prod_{i=1}^3P(n(w_i),i) = (1- \frac{1}{1+e^{-x_w^T\theta_1}})(1- \frac{1}{1+e^{-x_w^T\theta_2}})\frac{1}{1+e^{-x_w^T\theta_3}}
i=1∏3P(n(wi),i)=(1−1+e−xwTθ11)(1−1+e−xwTθ21)1+e−xwTθ31
对于所有的训练样本,我们期望最大化所有样本的似然函数乘积。
为了方便,我们定义:
- 输入的词为 w w w ,其从输入层词向量求和平均后的霍夫曼树根节点词向量为 x w x_w xw, 从根节点到 w w w所在的叶子节点,包含的节点总数为 l w l_w lw,
- w w w 在霍夫曼树中从根节点开始,经过的第 i i i 个节点表示为 p i w p^w_i piw ,对应的霍夫曼编码为 d i w ∈ { 0 , 1 } d^w_i\in \{0,1\} diw∈{0,1} ,其中 i = 2 , 3 , . . . l w i=2,3,...l_w i=2,3,...lw。而该节点对应的模型参数表示为 θ i w \theta^w_i θiw, 其中 i = 1 , 2 , . . . l w − 1 i=1,2,...l_{w−1} i=1,2,...lw−1,没有 i = l w i=l_w i=lw 是因为模型参数仅仅针对于霍夫曼树的内部节点。
定义
w
w
w经过的霍夫曼树某一个节点
j
j
j的逻辑回归概率为
P
(
d
j
w
∣
x
w
,
θ
j
−
1
w
)
P(d_j^w|x_w, \theta_{j-1}^w)
P(djw∣xw,θj−1w),其表达式为:
P
(
d
j
w
∣
x
w
,
θ
j
−
1
w
)
=
{
σ
(
x
w
T
θ
j
−
1
w
)
d
j
w
=
0
1
−
σ
(
x
w
T
θ
j
−
1
w
)
d
j
w
=
1
P(d_j^w|x_w, \theta_{j-1}^w)= \begin{cases} \sigma(x_w^T\theta_{j-1}^w)& {d_j^w=0}\\[2ex] 1- \sigma(x_w^T\theta_{j-1}^w) & {d_j^w = 1} \end{cases}
P(djw∣xw,θj−1w)=⎩
⎨
⎧σ(xwTθj−1w)1−σ(xwTθj−1w)djw=0djw=1
那么对于某一个目标输出词
w
w
w,其最大似然为:
∏
j
=
2
l
w
P
(
d
j
w
∣
x
w
,
θ
j
−
1
w
)
=
∏
j
=
2
l
w
[
σ
(
x
w
T
θ
j
−
1
w
)
]
1
−
d
j
w
[
1
−
σ
(
x
w
T
θ
j
−
1
w
)
]
d
j
w
\prod_{j=2}^{l_w}P(d_j^w|x_w, \theta_{j-1}^w) = \prod_{j=2}^{l_w} [\sigma(x_w^T\theta_{j-1}^w)] ^{1-d_j^w}[1-\sigma(x_w^T\theta_{j-1}^w)]^{d_j^w}
j=2∏lwP(djw∣xw,θj−1w)=j=2∏lw[σ(xwTθj−1w)]1−djw[1−σ(xwTθj−1w)]djw
在word2vec中,由于使用的是随机梯度上升法,所以并没有把所有样本的似然乘起来得到真正的训练集最大似然,仅仅每次只用一个样本更新梯度,这样做的目的是减少梯度计算量。这样我们可以得到
w
w
w的对数似然函数
L
L
L如下:
L
=
l
o
g
∏
j
=
2
l
w
P
(
d
j
w
∣
x
w
,
θ
j
−
1
w
)
=
∑
j
=
2
l
w
(
(
1
−
d
j
w
)
l
o
g
[
σ
(
x
w
T
θ
j
−
1
w
)
]
+
d
j
w
l
o
g
[
1
−
σ
(
x
w
T
θ
j
−
1
w
)
]
)
L= log \prod_{j=2}^{l_w}P(d_j^w|x_w, \theta_{j-1}^w) = \sum\limits_{j=2}^{l_w} \left((1-d_j^w) log \left[\sigma(x_w^T\theta_{j-1}^w)\right] + d_j^w log\left[1-\sigma(x_w^T\theta_{j-1}^w)\right]\right)
L=logj=2∏lwP(djw∣xw,θj−1w)=j=2∑lw((1−djw)log[σ(xwTθj−1w)]+djwlog[1−σ(xwTθj−1w)])
要得到模型中
w
w
w 词向量和内部节点的模型参数
θ
\theta
θ, 使用梯度上升法即可。首先我们求模型参数
θ
j
−
1
w
\theta^w_{j-1}
θj−1w 的梯度:
∂
L
∂
θ
j
−
1
w
=
(
1
−
d
j
w
)
(
σ
(
x
w
T
θ
j
−
1
w
)
(
1
−
σ
(
x
w
T
θ
j
−
1
w
)
σ
(
x
w
T
θ
j
−
1
w
)
x
w
−
d
j
w
(
σ
(
x
w
T
θ
j
−
1
w
)
(
1
−
σ
(
x
w
T
θ
j
−
1
w
)
1
−
σ
(
x
w
T
θ
j
−
1
w
)
x
w
=
(
1
−
d
j
w
)
(
1
−
σ
(
x
w
T
θ
j
−
1
w
)
)
x
w
−
d
j
w
σ
(
x
w
T
θ
j
−
1
w
)
x
w
=
(
1
−
d
j
w
−
σ
(
x
w
T
θ
j
−
1
w
)
)
x
w
\begin{align} \frac{\partial L}{\partial \theta_{j-1}^w} & = (1-d_j^w)\frac{(\sigma(x_w^T\theta_{j-1}^w)(1-\sigma(x_w^T\theta_{j-1}^w)}{\sigma(x_w^T\theta_{j-1}^w)}x_w - d_j^w \frac{(\sigma(x_w^T\theta_{j-1}^w)(1-\sigma(x_w^T\theta_{j-1}^w)}{1- \sigma(x_w^T\theta_{j-1}^w)}x_w \\[3ex] & = (1-d_j^w)(1-\sigma(x_w^T\theta_{j-1}^w))x_w - d_j^w\sigma(x_w^T\theta_{j-1}^w)x_w \\[2ex] & = (1-d_j^w-\sigma(x_w^T\theta_{j-1}^w))x_w \end{align}
∂θj−1w∂L=(1−djw)σ(xwTθj−1w)(σ(xwTθj−1w)(1−σ(xwTθj−1w)xw−djw1−σ(xwTθj−1w)(σ(xwTθj−1w)(1−σ(xwTθj−1w)xw=(1−djw)(1−σ(xwTθj−1w))xw−djwσ(xwTθj−1w)xw=(1−djw−σ(xwTθj−1w))xw
θ
j
−
1
w
\theta^w_{j-1}
θj−1w的更新公式为:
θ
j
−
1
w
:
=
θ
j
−
1
w
+
η
[
1
−
d
j
w
−
σ
(
x
w
T
θ
j
−
1
w
)
]
x
w
\theta^w_{j-1}:=\theta^w_{j-1}+\eta\left[1-d_j^w-\sigma(x_w^T\theta_{j-1}^w)\right]x_w
θj−1w:=θj−1w+η[1−djw−σ(xwTθj−1w)]xw
η
\eta
η表示学习率。
同样的方法,可以求出
x
w
x_w
xw的梯度表达式如下:
∂
L
∂
x
w
=
∑
j
=
2
l
w
(
1
−
d
j
w
−
σ
(
x
w
T
θ
j
−
1
w
)
)
θ
j
−
1
w
\frac{\partial L}{\partial x_w} = \sum\limits_{j=2}^{l_w}(1-d_j^w-\sigma(x_w^T\theta_{j-1}^w))\theta_{j-1}^w
∂xw∂L=j=2∑lw(1−djw−σ(xwTθj−1w))θj−1w
有了梯度表达式,我们就可以用梯度上升法进行迭代来一步步的求解我们需要的所有的
θ
j
−
1
w
\theta^w_{j-1}
θj−1w和
x
w
x_w
xw。
5.3 基于Hierarchical Softmax的CBOW模型
CBOW模型(上下文词预测当前词)的网络结构,包括三层:输入层、投影层和输出层。
定义词向量的维度大小 M M M,以及CBOW的上下文大小 2 c 2c 2c,这样对于训练样本中的每一个词,其前面的 c c c 个词和后面的 c c c 个词作为了CBOW模型的输入,该词本身作为样本的输出,期望softmax概率最大。
首先 需要先将词汇表建立成一颗霍夫曼树。
-
输入层:包含上下文中 2 c 2c 2c个词的词向量
-
投影层:将输入层的 2 c 2c 2c个两个做求和积累
x w = 1 2 c ∑ i = 1 2 c x i x_w = \frac{1}{2c}\sum\limits_{i=1}^{2c}x_i xw=2c1i=1∑2cxi -
输出层:对应一棵二叉树(Huffman树),由语料库中出现过的词当作叶子结点,各个词的频率当作权值构建的一棵Huffman树。(叶子结点的个数: N N N(词典的所有词),非叶子结点: N − 1 N-1 N−1)。
构建完Huffman树之后, 通过梯度上升法来更新的
θ
j
−
1
w
\theta^w_{j−1}
θj−1w和
x
w
x_w
xw,注意这里的
x
w
x_w
xw是由
2
c
2c
2c个词向量相加而成,梯度更新完毕后会用梯度项直接更新原始的各个
x
i
(
i
=
1
,
2
,
.
.
.
,
2
c
)
x_i(i=1,2,...,2c)
xi(i=1,2,...,2c),即:
θ
j
−
1
w
=
θ
j
−
1
w
+
η
(
1
−
d
j
w
−
σ
(
x
w
T
θ
j
−
1
w
)
)
x
w
x
i
=
x
i
+
η
∑
j
=
2
l
w
(
1
−
d
j
w
−
σ
(
x
w
T
θ
j
−
1
w
)
)
θ
j
−
1
w
(
i
=
1
,
2..
,
2
c
)
\theta_{j-1}^w = \theta_{j-1}^w + \eta (1-d_j^w-\sigma(x_w^T\theta_{j-1}^w))x_w\\[2ex] x_i= x_i +\eta \sum\limits_{j=2}^{l_w}(1-d_j^w-\sigma(x_w^T\theta_{j-1}^w))\theta_{j-1}^w \;(i =1,2..,2c)
θj−1w=θj−1w+η(1−djw−σ(xwTθj−1w))xwxi=xi+ηj=2∑lw(1−djw−σ(xwTθj−1w))θj−1w(i=1,2..,2c)
其中
η
\eta
η 为梯度上升法的步长。
基于Hierarchical Softmax的CBOW模型算法流程,梯度迭代使用了随机梯度上升法:
输入:基于CBOW的语料训练样本,词向量的维度大小 M M M,CBOW的上下文大小 2 c 2c 2c,步长 η \eta η
输出:霍夫曼树的内部节点模型参数 θ \theta θ,所有的词向量 w w w
基于语料训练样本建立霍夫曼树。
随机初始化所有的模型参数 θ \theta θ,所有的词向量 w w w
进行梯度上升迭代过程,对于训练集中的每一个样本 $(context(w),w) 做如下处理:
a) e = 0 e=0 e=0,计算 x w = 1 2 c ∑ i = 1 2 c x i x_w= \frac{1}{2c}\sum\limits_{i=1}^{2c}x_i xw=2c1i=1∑2cxi
b) for j = 2 j=2 j=2 to l w l_w lw:
f = σ ( x w T θ j − 1 w ) g = ( 1 − d j w − f ) η e = e + g θ j − 1 w θ j − 1 w = θ j − 1 w + g x w f = \sigma(x_w^T\theta_{j-1}^w)\\[2ex] g = (1-d_j^w-f)\eta\\[2ex] e = e + g\theta_{j-1}^w\\[2ex] \theta_{j-1}^w= \theta_{j-1}^w + gx_w f=σ(xwTθj−1w)g=(1−djw−f)ηe=e+gθj−1wθj−1w=θj−1w+gxw
c) 对于 c o n t e x t ( w ) context(w) context(w)中的每一个词向量 x i x_i xi(共 2 c 2c 2c个)进行更新:
x i = x i + e x_i = x_i + e xi=xi+e
d) 如果梯度收敛,则结束梯度迭代,否则回到步骤3继续迭代。
5.4 基于Hierarchical Softmax的Skip-Gram模型
Skip-Gram模型(当前词预测上下文词)的网络结构,包括三层:输入层、投影层和输出层。
定义词向量的维度大小 M M M,以及CBOW的上下文大小 2 c 2c 2c, 对于训练样本中的每一个词,该词本身作为样本的输入, 其前面的 c c c 个词和后面的 c c c 个词作为了Skip-Gram模型的输出,期望这些词的softmax概率比其他的词大。
首先 需要先将词汇表建立成一颗霍夫曼树。
- 输入层:只包含当前样本的中心词 w w w的词向量 v ( w ) \bold v(w) v(w)
- 投影层:将 v ( w ) \bold v(w) v(w) 投影到 v ( w ) \bold v(w) v(w),投影层是多余的
- 输出层:对应一棵二叉树(Huffman树),由语料库中出现过的词当作叶子结点,各个词的频率当作权值构建的一棵Huffman树。(叶子结点的个数: N N N(词典的所有词),非叶子结点: N − 1 N-1 N−1)。
构建完Huffman树之后, 通过梯度上升法来更新我们的 θ j − 1 w \theta^w_{j−1} θj−1w和 x w x_w xw,注意这里的 x w x_w xw周围有 2 c 2c 2c个词向量, 此时期望 P ( x i ∣ x w ) , i = 1 , 2...2 c P(x_i|x_w),i=1,2...2c P(xi∣xw),i=1,2...2c最大。 由于上下文是相互的,在期望 P ( x i ∣ x w ) , i = 1 , 2...2 c P(x_i|x_w),i=1,2...2c P(xi∣xw),i=1,2...2c最大化的同时,反过来也期望 P ( x w ∣ x i ) , i = 1 , 2...2 c P(x_w|x_i),i=1,2...2c P(xw∣xi),i=1,2...2c最大。那么是使用 P ( x i ∣ x w ) ) P(x_i|x_w)) P(xi∣xw))好还是 P ( x w ∣ x i ) P(x_w|x_i) P(xw∣xi)好?
word2vec使用了后者,好处就是在一个迭代窗口内,不是只更新 x w x_w xw 一个词,而是 x i ( i = 1 , 2...2 c ) x_i\ (i=1,2...2c\ ) xi (i=1,2...2c ) 共 2 c 2c 2c 个词。这样整体的迭代会更加的均衡。因此,Skip-Gram模型并没有和CBOW模型一样对输入进行迭代更新,而是对 2 c 2c 2c 个输出进行迭代更新。
基于Hierarchical Softmax的Skip-Gram模型算法流程,梯度迭代使用了随机梯度上升法:
输入:基于 Skip-Gram 的语料训练样本,词向量的维度大小 M M M, Skip-Gram 的上下文大小 2 c 2c 2c,步长 η \eta η
输出:霍夫曼树的内部节点模型参数 θ \theta θ,所有的词向量 w w w
基于语料训练样本建立霍夫曼树。
随机初始化所有的模型参数 θ \theta θ,所有的词向量 w w w
进行梯度上升迭代过程,对于训练集中的每一个样本 ( c o n t e x t ( w ) , w ) (context(w),w) (context(w),w)做如下处理:
a) for i = 1 i=1 i=1 to 2 c 2c 2c:
i) e = 0 e=0 e=0
ii) for j = 2 j=2 j=2 to l w l_w lw:
f = σ ( x w T θ j − 1 w ) g = ( 1 − d j w − f ) η e = e + g θ j − 1 w θ j − 1 w = θ j − 1 w + g x w f = \sigma(x_w^T\theta_{j-1}^w)\\[2ex] g = (1-d_j^w-f)\eta\\[2ex] e = e + g\theta_{j-1}^w\\[2ex] \theta_{j-1}^w= \theta_{j-1}^w + gx_w f=σ(xwTθj−1w)g=(1−djw−f)ηe=e+gθj−1wθj−1w=θj−1w+gxw
iii)
x i = x i + e x_i = x_i + e xi=xi+e
b) 如果梯度收敛,则结束梯度迭代,否则回到步骤a继续迭代。
5.5.举个栗子
假设2014年世界杯期间,从新浪微博中抓取了若干条与足球相关的微博,经统计,“我”、“喜欢”、“观看”、“巴西”、“足球”、“世界杯”这个六个词出现的次数分别为15,8,6,5,3,1。这6个词的Huffman编码,其中约定(词频大的)左孩子结点编码为1,(词频较小)右孩子结点编码为0。“我”、“喜欢”、“观看”、“巴西”、“足球”、“世界杯”这个六个词的Huffman编码为:0,111,110,101,1001,1000。
现在考虑词 w = " 足球 " w="足球" w="足球"的情形。
- 从根结点到足球结点由4条红色边串起来的5个结点构成路径 p w p^w pw,其路径长度 l w = 5 l_w=5 lw=5
- 路径 p w p^w pw上的5个结点分别为: p 1 w , p 2 w , p 3 w , p 4 w , p 5 w p^w_1,p^w_2,p^w_3,p^w_4,p^w_5 p1w,p2w,p3w,p4w,p5w,其中 p 1 w p^w_1 p1w对应根结点
- d 2 w , d 3 w , d 4 w , d 5 w d^w_2,d^w_3,d^w_4,d^w_5 d2w,d3w,d4w,d5w分别为 1 , 0 , 0 , 1 1,0,0,1 1,0,0,1,即足球的Huffman编码为 1001 1001 1001
- θ 1 , θ 2 , θ 3 , θ 4 \theta_1,\theta_2,\theta_3,\theta_4 θ1,θ2,θ3,θ4分别表示路径 p w p^w pw上4个非叶子结点对应的向量
从根结点到“足球”叶子结点,中间经过了4个分支(每条红色的边对应一次分支),而每一次分支可以视为一次二分类。Huffman编码为1的结点定义为负类,编码为0的结点定义为正类(这只是一个约定)。
对于从根结点到“足球”叶子结点,经过了4次二分类,每次分类的结果的概率如下:
- 第1次: p ( d 2 w ∣ x w , θ 1 w ) = 1 − σ ( x w T θ 1 w ) p(d^w_2|x_w,\theta^w_1)=1-\sigma(x^T_w\theta^w_1) p(d2w∣xw,θ1w)=1−σ(xwTθ1w)
- 第2次: p ( d 3 w ∣ x w , θ 2 w ) = σ ( x w T θ 2 w ) p(d^w_3|x_w,\theta^w_2)=\sigma(x^T_w\theta^w_2) p(d3w∣xw,θ2w)=σ(xwTθ2w)
- 第3次: p ( d 4 w ∣ x w , θ 3 w ) = σ ( x w T θ 3 w ) p(d^w_4|x_w,\theta^w_3)=\sigma(x^T_w\theta^w_3) p(d4w∣xw,θ3w)=σ(xwTθ3w)
- 第4次: p ( d 5 w ∣ x w , θ 4 w ) = 1 − σ ( x w T θ 4 w ) p(d^w_5|x_w,\theta^w_4)=1-\sigma(x^T_w\theta^w_4) p(d5w∣xw,θ4w)=1−σ(xwTθ4w)
所以要求的
p
(
足球
∣
C
o
n
t
e
x
t
(
足球
)
)
p(足球|Context(足球))
p(足球∣Context(足球))等于上述4个概率的乘积
p
(
足球
∣
C
o
n
t
e
x
t
(
足球
)
)
=
∏
2
5
p
(
d
j
w
∣
x
w
,
θ
j
−
1
w
)
p(足球|Context(足球))=\prod\limits^5\limits_2p(d^w_j|x_w,\theta^w_{j-1})
p(足球∣Context(足球))=2∏5p(djw∣xw,θj−1w)
5.6 分层softmax(Hierachical Softmax)思想
-
Hierachical Softmax的基本思想就是首先将词典中的每个词按照词频大小构建出一棵Huffman树,保证词频较大的词处于相对比较浅的层,词频较低的词相应的处于Huffman树较深层的叶子节点,每一个词都处于这棵Huffman树上的某个叶子节点。
-
将原本的一个 ∣ V ∣ |V| ∣V∣分类问题变成了 l o g ∣ V ∣ log|V| log∣V∣次的二分类问题。
-
原先要计算 P ( w t ∣ c t ) P(w_t|c_t) P(wt∣ct)的时候,因为使用的是普通的softmax,势必要求词典中的每一个词的概率大小 ,那么如何减少计算量呢?
-
计算当前词 w t w_t wt 在其上下文中的概率大小,只需要把它变成在Huffman树中的路径预测问题就可以了,因为当前词 w t w_t wt 在Huffman树中对应到一条路径,这条路径由这棵二叉树中从根节点开始,经过一系列中间的父节点,最终到达当前这个词的叶子节点而组成,那么在每一个父节点上,都对应的是一个二分类问题(本质上就是一个LR分类器),而Huffman树的构造过程保证了树的深度为 l o g ∣ V ∣ log|V| log∣V∣,所以也就只需要做 l o g ∣ V ∣ log|V| log∣V∣次二分类便可以求得 P ( w t ∣ c t ) P(w_t|c_t) P(wt∣ct) 的大小。
6.基于Negative Sampling的模型
6.1 背景
使用霍夫曼树来代替传统的神经网络,可以提高模型训练的效率。但是如果我们的训练样本里的中心词 w w w是一个很生僻的词,那么就得在霍夫曼树中辛苦的向下走很久了。能不能不用搞这么复杂的一棵霍夫曼树,将模型变的更加简单呢?
Negative Sampling就是这么一种求解word2vec模型的方法,它摒弃了霍夫曼树,采用了Negative Sampling(负采样)的方法来求解。
6.2 语言模型的训练过程
对于文本“”Thou shalt not make a machine in the likeness of a human mind“而言:
- 构造样本,假设窗口大小=5
-
训练过程,用not预测thou
- 预测结果
如上图一样,预测结果极度不靠谱,not本该预测thou,但其却将 0.4 0.4 0.4 的概率预测成了taco,预测错了,如何解决?计算损失loss,利用梯度
- 误差计算
现在误差向量可以被用于更新模型了,所以在下一轮预测中,如果用not作为输入,我们更有可能得到thou作为输出了。接下来继续对数据集内下一份样本进行同样的操作,直到遍历所有的样本。这就是一轮(epoch)了。我们再多做几轮(epoch),得到训练过的模型,于是就可以从中提取嵌入矩阵来用于其他应用了。
如果按照上述训练方法,则not是不是要把整个词表的所有的都要预测一遍?
6.3 理解负采样的过程
比如有一个训练样本,中心词是 w w w,它周围上下文共有 2 c 2c 2c 个词,记为 c o n t e x t ( w ) context(w) context(w)。由于这个中心词 w w w 的确和 c o n t e x t ( w ) context(w) context(w) 相关存在,因此它是一个真实的正例。通过Negative Sampling采样,得到neg个和 w w w不同的词 w i , i = 1 , 2 , . . n e g \ w_i,i=1,2,..neg wi,i=1,2,..neg, 这样 c o n t e x t ( w ) context(w) context(w)和 w i w_i wi就组成了neg个并不真实存在的负例 作为负例。利用这一个正例和neg个负例,进行二元逻辑回归,得到负采样对应每个词 w i w_i wi对应的模型参数 θ i \theta_i θi,和每个词的词向量。
对于上述问题,那么负采样的样本如何获取? 从词汇表中随机抽取单词就可以了
训练流程:
- 在训练过程开始之前,预先处理正在训练模型的文本。确定词典的大小(vocab_size,比如说10,000)以及哪些词被它包含在内。
- 在训练阶段的开始,创建两个矩阵——Embedding矩阵和Context矩阵。
- 在训练过程开始时,用 “随机值初始化” 这些矩阵。开始训练过程。在每个训练步骤中,采取一个相邻的例子及其相关的非相邻例子。
- 输入单词not和输出/上下文单词: thou(实际邻居词),aaron和taco(负面例子)。
对于输入词,查看Embedding矩阵。对于上下文单词,查看Context矩阵
- 计算输入嵌入与每个上下文嵌入的点积。在每种情况下,结果都将是表示输入和上下文嵌入的相似性的数字。计算误差,使用梯度下降法更新参数。
6.4 负采样中的梯度计算
Negative Sampling也是采用了二元逻辑回归来求解模型参数,通过负采样得到了neg个负例 ( c o n t e x t ( w ) , w i ) i = 1 , 2 , . . n e g (context(w),w_i)i=1,2,..neg (context(w),wi)i=1,2,..neg为了统一描述将正例定义为 w 0 w_0 w0。
在逻辑回归中,正例应该期望满足: P ( c o n t e x t ( w 0 ) , w i ) = σ ( x w 0 T θ w i ) , y i = 1 , i = 0 P(context(w_0), w_i) = \sigma(x_{w_0}^T\theta_{w_i}) ,y_i=1, i=0 P(context(w0),wi)=σ(xw0Tθwi),yi=1,i=0
负例期望满足: P ( c o n t e x t ( w 0 ) , w i ) = 1 − σ ( x w 0 T θ w i ) , y i = 0 , i = 1 , 2 , . . n e g P(context(w_0), w_i) =1- \sigma(x_{w_0}^T\theta_{w_i}), y_i = 0, i=1,2,..neg P(context(w0),wi)=1−σ(xw0Tθwi),yi=0,i=1,2,..neg
期望可以最大化: ∏ i = 0 n e g P ( c o n t e x t ( w 0 ) , w i ) = σ ( x w 0 T θ w 0 ) ∏ i = 1 n e g ( 1 − σ ( x w 0 T θ w i ) ) \prod\limits_{i=0}\limits^{neg}P(context(w_0), w_i) = \sigma(x_{w_0}^T\theta_{w_0})\prod\limits_{i=1}\limits^{neg}(1- \sigma(x_{w_0}^T\theta_{w_i})) i=0∏negP(context(w0),wi)=σ(xw0Tθw0)i=1∏neg(1−σ(xw0Tθwi))
似然函数为: ∏ i = 0 n e g σ ( x w 0 T θ w i ) y i ( 1 − σ ( x w 0 T θ w i ) ) 1 − y i \prod\limits_{i=0}\limits^{neg} \sigma(x_{w_0}^T\theta_{w_i})^{y_i}(1- \sigma(x_{w_0}^T\theta_{w_i}))^{1-y_i} i=0∏negσ(xw0Tθwi)yi(1−σ(xw0Tθwi))1−yi
对数似然: L = ∑ i = 0 n e g y i l o g ( σ ( x w 0 T θ w i ) ) + ( 1 − y i ) l o g ( 1 − σ ( x w 0 T θ w i ) ) L = \sum\limits_{i=0}^{neg}y_i log(\sigma(x_{w_0}^T\theta_{w_i})) + (1-y_i) log(1- \sigma(x_{w_0}^T\theta_{w_i})) L=i=0∑negyilog(σ(xw0Tθwi))+(1−yi)log(1−σ(xw0Tθwi))
梯度上升法来更新我们的
θ
w
i
\theta_{w_i}
θwi和
x
w
i
,
i
=
0
,
1
,
.
.
n
e
g
x_{wi},i=0,1,..neg
xwi,i=0,1,..neg,分别求解梯度:
∂
L
∂
θ
w
i
=
y
i
(
1
−
σ
(
x
w
0
T
θ
w
i
)
)
x
w
0
−
(
1
−
y
i
)
σ
(
x
w
0
T
θ
w
i
)
x
w
0
=
(
y
i
−
σ
(
x
w
0
T
θ
w
i
)
)
x
w
0
∂
L
∂
x
w
0
=
∑
i
=
0
n
e
g
(
y
i
−
σ
(
x
w
0
T
θ
w
i
)
)
θ
w
i
\begin{align} \frac{\partial L}{\partial \theta_{w_i} } &= y_i(1- \sigma(x_{w_0}^T\theta_{w_i}))x_{w_0}-(1-y_i)\sigma(x_{w_0}^T\theta_{w_i})x_{w_0} \\[2ex] & = (y_i -\sigma(x_{w_0}^T\theta_{w_i})) x_{w_0} \\[4ex] \frac{\partial L}{\partial x_{w_0} } &= \sum\limits_{i=0}^{neg}(y_i -\sigma(x_{w_0}^T\theta_{w_i}))\theta_{w_i} \end{align}
∂θwi∂L∂xw0∂L=yi(1−σ(xw0Tθwi))xw0−(1−yi)σ(xw0Tθwi)xw0=(yi−σ(xw0Tθwi))xw0=i=0∑neg(yi−σ(xw0Tθwi))θwi
6.5 负采样的方法
如果词汇表的大小为
V
V
V,那么将一段长度为1的线段分成
V
V
V份,每份对应词汇表中的一个词。当然每个词对应的线段长度是不一样的,高频词对应的线段长,低频词对应的线段短。每个词
w
w
w的线段长度由下式决定:
l
e
n
(
w
)
=
c
o
u
n
t
(
w
)
∑
u
∈
v
o
c
a
b
c
o
u
n
t
(
u
)
len(w) = \frac{count(w)}{\sum\limits_{u \in vocab} count(u)}
len(w)=u∈vocab∑count(u)count(w)
在word2vec中,分子和分母都取了
3
/
4
3/4
3/4 次幂如下:
l
e
n
(
w
)
=
c
o
u
n
t
(
w
)
3
/
4
∑
u
∈
v
o
c
a
b
c
o
u
n
t
(
u
)
3
/
4
len(w) = \frac{count(w)^{3/4}}{\sum\limits_{u \in vocab} count(u)^{3/4}}
len(w)=u∈vocab∑count(u)3/4count(w)3/4
在采样前,将这段长度为1的线段划分成
M
M
M等份,这里
M
>
>
V
M>>V
M>>V,这样可以保证每个词对应的线段都会划分成对应的小块。而
M
M
M份中的每一份都会落在某一个词对应的线段上。在采样的时候,我们只需要从
M
M
M个位置中采样出
n
e
g
neg
neg个位置就行,此时采样到的每一个位置对应到的线段所属的词就是我们的负例词。
在word2vec中, M M M取值默认为 1 0 8 10^8 108。
总的来说:非等距切分+等距切分
6.5负采样的技巧点
例如: 选定句子 “The quick brown fox jumps over lazy dog” ,设定窗口大小为2 (
w
i
n
d
o
w
_
s
i
z
e
=
2
window\_size=2
window_size=2) 选输入词前后各两个词和输入词进行组合。下图中,蓝色代表input word,方框内代表位于窗口内的单词。
对高频词进行抽样
但是对于“the”这种常用高频单词,这样的处理方式会存在下面两个问题:
- 当我们得到成对的单词训练样本时,(“fox”, “the”) 这样的训练样本并不会给我们提供关于“fox”更多的语义信息,因为“the”在每个单词的上下文中几乎都会出现。
- 由于在文本中“the”这样的常用词出现概率很大,因此我们将会有大量的(”the“,…)这样的训练样本,而这些样本数量远远超过了我们学习“the”这个词向量所需的训练样本数。
Word2Vec通过“抽样”模式来解决这种高频词问题。它的基本思想如下:对于在训练原始文本中遇到的每一个单词,它们都有一定概率从文本中被删掉,而这个被删除的概率与单词的频率有关。
如果设置窗口大小 s p a n = 10 span=10 span=10,并且从文本中删除所有的“the”,那么会有下面的结果:
- 由于删除了文本中所有的“the”,那么在训练样本中,“the”这个词永远不会出现在上下文窗口中。
- 当“the”作为input word时,训练样本数至少会减少10个。
Q:如何选择抽样率呢?
word2vec的C语言代码实现了一个计算在词汇表中保留某个词概率的公式。
P
(
w
i
)
=
(
Z
(
w
i
)
0.001
+
1
)
×
0.001
Z
(
w
i
)
P(w_i)=(\sqrt{\frac{Z(w_i)}{0.001}}+1)×\frac{0.001}{Z(w_i)}
P(wi)=(0.001Z(wi)+1)×Z(wi)0.001
P
(
w
i
)
P(w_i)
P(wi)表示某个单词被保留的概率。
w
i
w_i
wi是一个单词,
Z
(
w
i
)
Z_(w_i)
Z(wi)是
w
i
w_i
wi这个单词在所有语料中出现的频次。
举个栗子:如果单词“peanut”在10亿规模大小的语料库中出现了1000次,则有 Z ( " p e a n u t " ) = 1000 / 1000000000 = 1 e − 6 Z("peanut")=1000/1000000000=1e-6 Z("peanut")=1000/1000000000=1e−6
在代码中还有一个参数叫“sample”,这个参数代表一个阈值,默认值为0.001**(在gensim包中的Word2Vec类说明中,这个参数默认为0.001,文档中对这个参数的解释为“ threshold** for configuring which higher-frequency words are randomly downsampled”)。这个值越小意味着这个单词被保留下来的概率越小(即有越大的概率被我们删除)。
6.6 负采样的思想
负采样每遍历到一个目标词,为了使得目标词的概率
P
(
w
t
∣
c
t
)
P(w_t|c_t)
P(wt∣ct) 最大,根据softmax函数的概率公式,也就是让分子中的
e
′
(
w
t
)
T
x
e′(w_t)^Tx
e′(wt)Tx 最大,而分母中其他非目标词的
e
′
(
w
i
)
T
x
e′(w_i)^Tx
e′(wi)Tx 最小,普通softmax的计算量太大就是因为它把词典中所有其他非目标词都当做负例了,而负采样的思想特别简单,就是每次按照一定概率随机采样一些词当做负例,从而就只需要计算这些负采样出来的负例了,那么概率公式便相应变为:
P
(
w
t
∣
c
t
)
=
e
x
p
(
e
´
(
w
t
)
T
)
x
∑
i
=
1
K
e
x
p
(
e
´
(
w
i
)
T
)
x
,
x
=
∑
i
∈
c
e
(
w
i
)
P(w_t|c_t)=\frac{exp(e´(w_t)^T)x}{\sum\limits_{i=1}\limits^Kexp(e´(w_i)^T)x}, \quad x=\sum\limits_{i \in c}e(w_i)
P(wt∣ct)=i=1∑Kexp(e´(wi)T)xexp(e´(wt)T)x,x=i∈c∑e(wi)
仔细和普通softmax进行比较便会发现,将原来的|V|分类问题变成了K分类问题,这便把词典大小对时间复杂度的影响变成了一个常数项,而改动又非常的微小,不可谓不巧妙。
7.word2vec的好处
不同于one_hot这种暴力映射,无法衡量字词的语义空间距离。Word2vec采用的是低维稠密矩阵去表征字词的语义关系。
- 降低维度,解决稀疏性
- 相似性(衡量词与词之间的距离远近关系)
- 泛化能力更强
对于泛化能力的理解:假设现有四个特征值woman girl man boy,经过onet-hot编码之后得到
[1,0,0,0]–>woman [0,1,0,0]–>girl 每个特征之间是独立的,放进网络里训练彼此之间是没有任何关系的。如果将特征进行embedding操作为2维度:[性别,年龄]==> 女 40(通过性别和年龄能学习出woman)—>woman 可以学习出泛化性。
8.总结
- 统计语言模型就是用来计算一个句子的概率的概率模型(N-gram方式计算)
- 神经语言模=Embedding层+前馈神经网络
- word2vec主要有两种实现方式
- Skip-gram:输入一个词 x x x,预测它的上下文的词
- CBOW:通过上下文的词,去预测当前的词
- word2vec本质上学习词与词之间的共现关系
- hierarchical softmax: 本质是把 N 分类问题变成 log(N)次二分类
- negative sampling: 本质是预测总体类别的一个子集
- Word2vec学习的参数是两个矩阵(每一个行是一个词向量)
- embedding矩阵有两个矩阵,可以取第一个或者把二者相加做平均做真正的词向量w
本文仅仅作为个人学习记录所用,不作为商业用途,谢谢理解。
参考:
1.https://zhuanlan.zhihu.com/p/88874759
2.https://www.cnblogs.com/peghoty/p/3857839.html
3.https://www.cnblogs.com/pinard/p/7160330.html