Word2Vec - Skip-gram是如何训练出词向量的

Stanford / Winter 2020 CS224n 课程学习笔记02


根据统计学,比如一句话:"我想吃X",根据训练文本,输出最有可能出现的X。比如训练文本出现最多的是"我想吃苹果",那么"苹果"则应是最有可能被预测出来。
假设我们有一个列表D(字典),D = ['problems','turning','into','banking','crises','as']
字典总长度为6,我们假设窗口为3,目前窗口位置在这里['problems','turning','into']。我们想预测'turning'的上下文(一个窗口内)最有可能出现的单词。按照从左到右进行预测,我们理想状态下第一个词的预测输出为 = problems 。即直接对字典D进行索引。但现实是不可能的,所以概率可能就变为了[0.92,0.03,0.01,0.06,0.07,0.25]。

疑问一:那么这个概率矩阵是怎么得到的?


计算完毕后,会得到一个和词汇表长度一样的概率输出:即

疑问二:词向量是怎么训练出来的?

首先要用到交叉熵损失函数 (cross-entropy loss) :

即预测值与真实值(目标值)的差异,即,差异性越大,交叉熵损失越大。所以为了让预测更准确,我们要降低交叉熵损失

tips:这里对交叉熵函数进行推导,得到更简便的形式
loss_{cross-entropy} = -\sum_{w \in Vocab} y_{w} \log \left(\hat{y}_{w}\right) = - y_{o} \log \left(\hat{y}_{o}\right) - \sum_{w \in Vocab, w \neq o} y_{w} \log \left(\hat{y}_{w}\right) = - \log \left(\hat{y}_{o}\right)

当 越来越小,即我们的准确率越来越高时,就达到我们想要的的效果了。降低loss的方法是利用梯度下降进行梯度更新。
这是当激活函数为softmax时,我们的 计算公式:

\begin{aligned} J_{naive-softmax(v_{c},o,U)} & = -logP(O = o|C = c) \\& = -log( \frac{e^{u_{o}^{T} v_c}}{ \sum_{W \in Vocab} e^{u_{w}^{T} v_c}}) \\& = - u_{o}^{T} v_c + log(\sum_{W \in Vocab} e^{u_{w}^{T} v_c} ) \end{aligned}

进行梯度更新时,我们要更新两个向量,一个是中心词向量,一个是外部词向量。

一、使用激活函数为Softmax,进行梯度下降并更新词向量:

\begin{aligned} \frac{\partial J\left(v_{c}, o, U\right)}{\partial v_{c}} & =-\frac{\partial\left(u_{o}^{T} v_{c}\right)}{\partial v_{c}}+\frac{\partial\left(\log \left(\sum_{w} \exp \left(u_{w}^{T} v_{c}\right)\right)\right)}{\partial v_{c}} \\ & =-u_{o}+\frac{1}{\sum_{w} \exp \left(u_{w}^{T} v_{c}\right)} \frac{\partial\left(\sum_{w} \exp \left(u_{w}^{T} v_{c}\right)\right)}{\partial v_{c}} \\ & =-u_{o}+\sum_{w} \frac{\exp \left(u_{w}^{T} v_{c}\right) u_{w}}{\sum_{w} \exp \left(u_{w}^{T} v_{c}\right)} \\ & =-u_{o}+\sum_{w} p(O=w | C=c) u_{w} \\ & =-u_{o}+\sum_{w} \hat{y}_{w} u_{w} \\ & = -u_{o} + u_{new} \\ & = U^T (\hat{y} - y) \end{aligned}

更新词向量时,分为两种情况,①时 ②时
when

①\begin{aligned} \frac{ \partial J\left(v_{c}, o, U\right)}{\partial u_{w} } & = -\frac{ \partial \left(u_{o}^{T} v_{c}\right)} { \partial u_{w} }+ \frac{ \partial \left( \log \left( \exp \left(u_{w}^{T} v_{c} \right) \right) \right)} { \partial u_{w} } \\ & = -v_c + \frac{1}{ \sum_{w} \exp \left(u_{w}^{T} v_{c} \right)} \frac{ \partial \left( \exp \left(u_{w}^{T} v_{c} \right) \right) } { \partial u_{w} } \\ & = -v_c + \frac{ \exp \left(u_{w}^{T} v_{c} \right) v_{c} } { \sum_{w} \exp \left( u_{w}^{T} v_{c} \right) } \\ & = -v_c + p(O=w | C=c) v_{c} \\ & = -v_c + \hat {y}_{w=o} v_{c} \end{aligned}
when

then
\begin{aligned} \frac{ \partial J \left(v_{c}, o, U \right)}{ \partial u_{w} } & = ① + ② = -v_c + \hat{y}_{w=o} v_{c} + \sum_{w-1} \hat {y}_{w \neq o} v_{c} \\& = \hat{y}·v_c - y·v_c = (\hat{y} - y)^{T}v_c \end{aligned}

根据求导结果,我们发现计算时仅需即可。

注:在开始时生成两个同样大小的矩阵。初始为0矩阵,则进行随机初始化,两个矩阵大小都是Vocab * dim。但是,进行更新时, 只在内更新,只在内更新。

为了更直观的理解,下面是我做的动画演示。

softmax_vc的更新

Softmax_U的更新

二、使用激活函数为Sigmoid,进行梯度下降并更新词向量:

在课程中,又提出了一种对损失函数的优化算法,其更新时,取随机L个窗口外的词,这样在在更新时,不是更新几乎整个词汇表的词向量矩阵(Vocab * dim),而是更新(L * dim)大小的矩阵。从计算成本上要节省了许多。下面是实现步骤。
我们将激活函数改为sigmoid

这是当激活函数为sigmoid时,我们的 计算公式:

因为要计算梯度,根据求导链式法则,后面会对sigmoid进行求导,所以先在这里求了。

\begin{aligned} \sigma(x)' & = (\frac{1}{1+e^{-x}})' \\& = \frac{e^{-x}}{(1 +e{^{-x}})^2} \\& = \frac{1+e^{-x} -1}{(1 +e{^{-x}})^2} \\& = \frac{1}{1+e^{x}}(1-\frac{1}{1+e^{x}}) \\& = \sigma(x)(1-\sigma(x)) \end{aligned}

对中心词向量计算偏导

tips:
\begin{aligned} \frac{\partial J_{\text {neg-sample } }}{\partial v_{c}} & =\left(\sigma\left(u_{o}^{T} v_{c}\right)-1\right) u_{o}+\sum_{k=1}^{K}\left(1-\sigma\left(-u_{k}^{T} v_{c}\right)\right) u_{k} \\& =\left(\sigma\left(u_{o}^{T} v_{c}\right)-1\right) u_{o}+\sum_{k=1}^{K} \sigma\left(u_{k}^{T} v_{c}\right) u_{k} \end{aligned}

对负样本向量计算偏导
因为是负样本,所以。 ,其向量表示为

\begin{aligned} \frac {\partial J_{ \text { neg-sample } } } { \partial u_{k} } & = \sum_{k=1}^{K} (1- \sigma (-u_{k}^{T} v_{c}) ) v_{c} \\& = \sum_{k=1}^{K} (\sigma (u_{k}^{T} v_{c}) ) v_{c} \end{aligned}

动画演示。

sigmoid_U的更新

sigmoid_Vc的更新

梯度更新:

。为学习率。因为代码里矩阵是拼接后进行计算的,所以和同为 2Vocab * dim大小的矩阵。

最后,训练出的词向量就是V矩阵。

新手上路,欢迎大家批评指正!

参考资料

[1]Stanford / Winter 2020 CS224n
[2]CS224n-2019 学习笔记(looperxx)

你可能感兴趣的:(Word2Vec - Skip-gram是如何训练出词向量的)