word2vec

word2vec

Part I:背景

特征表达是很基础的一步,我们通常用向量去表示一个事物,比如文本中的词向量,知识图谱中的知识向量,以及Network Embedding等。

在NLP中传统的one-hot形式表示一个词,存在以下问题:

  • 维度爆炸,词表通常为很大,导致词向量的维度也很大

  • 损失语义信息。

所以word embeding的优势如下:

1)将词语映射成一个固定维度的向量,节省空间。

2)词向量可能会具备一定的语义信息,将相似的词语放到相近的向量空间(比如香蕉和苹果都是属于水果,苹果又会涉及到歧义问题),可以学习到词语之间的关系(比如经典的 男人-女人=国王-王后)。

本文会介绍一下Word2vec原理,这是一种常见的可以用于训练词向量的模型工具。常见的做法是,我们先用word2vec在公开数据集上预训练词向量,加载到自己的模型中,对词向量进行调整,调整成适合自己数据集的词向量。

Part II:训练模式

我们通常是通过将词向量用于某些任务中,用这些任务的衡量指标去衡量模型结果。

作为词向量。从任务形式上看,我们是在训练语言模型,而实际上我们最终的目标是想得到词向量,我们更关心的是这个词向量合不合理。

Word2vec根据上下文之间的出现关系去训练词向量,有两种训练模式,Skip Gram和CBOW,其中Skip Gram根据目标单词预测上下文,CBOW根据上下文预测目标单词,最后使用模型的部分参数作为词向量。

一.CBOW

根据上下文预测目标单词,我们需要极大化这个目标单词的出现概率。

img

假设词表大小为V,词向量维度为N,上下文单词为x1,x2, …, xc,定义上下文窗口大小为c,对应的目标单词为y,我们将x跟y都表示成one hot形式。这里涉及到两个矩阵参数,W是词向量矩阵,每一行都是某个词的词向量v,W’可以看做是一个辅助矩阵,每一列可以看做是某个词对应的相关向量v’。

前向过程:

  • x->hidden:对于每个xi,取出对应的词向量vi,再对这些词向量取平均作为hidden vector,相当于通过简单粗暴的叠加,得到这些词语的语义向量。

  • h->y:将h乘以W’得到一个维度为V的向量u,进行softmax归一化得到概率向量,取概率最大的作为预测单词。

后向过程:

我们需要极大化目标单词的出现概率p(y | x1, x2, … , xc),也就是极小化负对数似然函数,Loss函数定义为:

52568103798

我们需要更新两个矩阵参数,W和W’,先根据loss对参数求梯度,再使用梯度下降法更新参数。具体的求导过程这里略过,请移步原论文。

对于W’,经过求导,v’更新公式为:

52568106232

也就是说,需要更新整个W’矩阵,所有v’向量。(这里造成了巨大的计算量)

对于W,经过求导,v更新公式为:

52568108459

也就是说,这里只需要更新c个上下文单词所对应的词向量。

二. Skip Gram:

根据目标单词预测其上下文,假设输入的目标单词为x,定义上下文窗口大小为c,对应的上下文为y1, y2, … , yc,这些y是相互独立的。

preview

前向过程:

x->hidden:将输入单词x乘以词向量矩阵W,相当于取出该词的词向量v。

h->y:对于每个输出单词y_i,将h乘以矩阵W’得到向量u,再经过softmax归一化得到概率向量,取概率最大的预测为上下文单词,极大化y_i的预测概率。

这些上下文单词是相互独立的,虽然他们共享W’,但是loss是不一样的,我们需要极大化这些词出现的概率。作为一个语言模型这种做法是略显粗糙,但是这里我们的目的只是为了训练词向量,并不是需要训练一个多么好的语言模型。

后向过程:

直观上的样本格式是(x,y1, y2, … , yc),然后极大化p(y|x),因为这些y是相互独立的,又变成极大化p(y1|x)p(y2|x)**…***p(yc|x),取log将连乘变成连加,取负将极大化变成极小化,使用交叉熵作为loss函数:

img

我们需要更新两个矩阵参数,W和W’,先根据loss对参数求梯度,再使用梯度下降法更新参数

对于W’,经过求导,v’更新公式为:

52568425136

也就是说,这里依然需要更新所有v’向量。(无法避免的巨大的计算量)

对于W,经过求导,v更新公式为:

52568429071

这里只需要更新目标词语所对应的那个词向量。

Part III:

原始的方法所存在的问题是计算量太大,体现在以下两方面:

1)前向过程,h->y这部分在对向量进行softmax的时候,需要计算V次。

2)后向过程,softmax涉及到了V列向量,所以也需要更新V个向量。

问题就出在V太大,而softmax需要进行V次操作,用整个W进行计算。

因此word2vec使用了两种优化方法,Hierarchical SoftMax和Negative Sampling,对softmax进行优化,不去计算整个W,大大提高了训练速度。

一. Hierarchical SoftMax

HS用哈夫曼树,把预测one-hot编码改成预测一组01编码,进行层次分类。

img

在哈夫曼树中,每个叶节点是词表中的一个词,每个非叶子节点对应一个v’向量,树的深度为L(w),整颗树有V-1个非叶子节点和V个叶节点。假设输入单词是w_i,目标单词是w_o,那么n(w, i)表示从根节点到叶节点w路径中的第i个节点,v’(w, i)表示n(w, i)所对应的v’向量。

注意:v’不是针对词语w而言,而是针对节点n,每个节点n都有自己的一个向量v’,而不是每个词在每个节点上有一个向量,或者说,这些词在同一个节点上共享向量。

假设h是w_i前面所计算出来的hidden vector,我们在非叶子节点中使用该节点处的v’向量和h点乘,再用sigmoid去判断向左还是向右:(取代softmax)

img

img

那么每个叶节点会有一个概率p(wi=wo),最终我们需要极大化从根节点到预测单词w_o这条路径的概率,比如对于目标单词w2,我们需要极大化p(w2=w_o):

img

在根节点处左右概率之和是1,然后在接下来的每个节点,对应两个子节点的概率值之和等于父节点本身的概率值,那么走到最后,所有叶子节点的概率值之和必定还是等于1:

img

这也就保证了原始softmax概率和为1的前提,因此可以用层次sigmoid去代替softmax函数。

Loss函数定义为:

img

极大化目标单词的路径概率。

现在我们重新定义v’为:

img

那么对于W’,经过求导,v’更新公式为:

img

也就是说,这里只需要更新L(w)-1个v’向量,时间复杂度直接从O(V)降到了O(logV)。

关于空间复杂度,原始方法中每个单词需要一个v’向量,总共需要V个向量,而HS中每个节点也会有一个v’向量,总共需要V-1个向量,这些向量维度是一样的,并不会增加空间复杂度。

二. Negative Sampling

NS仅仅选择一小部分列向量进行更新,和HS相比,显得相对简单一点。

对于每条数据,首先我们将原始的V个词划分成正样本w_o和负样本w_neg,正样本也就是要预测的单词,剩下的就是负样本。负样本非常多,我们需要采样出K个负样本,与正样本一起训练。从前我们需要对所有V个词进行softmax计算,现在对于我们只使用到了正样本和负样本,只针对这几个词进行计算,计算量可以大大减小。

负样本选取方式:

NS是一种概率采样的方式,可以根据词频进行随机抽样,我们倾向于选择词频比较大的负样本,比如“的”,这种词语其实是对我们的目标单词没有很大贡献的。

Word2vec则在词频基础上取了0.75次幂,减小词频之间差异过大所带来的影响,使得词频比较小的负样本也有机会被采到。

img

Loss函数定义为:

img

极大化正样本出现的概率,同时极小化负样本出现的概率,以sigmoid来代替softmax,相当于进行二分类,判断这个样本到底是不是正样本。

那么对于W’,经过求导,v’更新公式为:

img

也就是说,这里不需要更新所有v’向量,只需要更新部分v’向量,这里的wj是正样本w_o和负样本w_neg的集合,只更新这些样本所对应的v’向量。

Part IV:衡量指标

词向量的衡量指标通常有以下几种:

1)词汇相似度任务,比如wordsim353,但是这种方式比较依赖于数据集。

2)类比任务,比如男人-女人=国王-王后

3)应用于实际任务上的效果,比如文本分类,情感分析,句法分析,序列标注,阅读理解等等。这种方法我觉得是比较靠谱的,因为我们训练词向量是希望得到一个好的词向量,然后能在别的任务上work,

4)可视化,可以用谷歌的Embedding Projector工具,用 PCA、t-SNE对高维词向量进行可视化,把数据降到三维,以3D方式查看数据,感觉还挺好玩的。

备注 拓展知识:

softmax函数———>激活函数

  • softmax用于多分类过程中,它将多个神经元的输出,映射到(0,1)区间内,可以看成概率来理解,从而来进行多分类!

假设我们有一个数组,V,Vi表示V中的第i个元素,那么这个元素的softmax值就是

img

更形象的如下图表示:

img

softmax直白来说就是将原来输出是3,1,-3通过softmax函数一作用,就映射成为(0,1)的值,而这些值的累和为1(满足概率的性质),那么我们就可以将它理解成概率,在最后选取输出结点的时候,我们就可以选取概率最大(也就是值对应最大的)结点,作为我们的预测目标!

以下是softmax的例子,现在使用基于神经网络的句法分析器,用到的是基于转移系统来做,那么神经网络的用途就是帮我预测我这一个状态将要进行的动作是什么?比如有10个输出神经元,那么就有10个动作,1动作,2动作,3动作…一直到10动作。也就是根据每个状态(输入),来预测动作(得到概率最大的输出),最终得到的一系列动作序列就可以完成我的任务即可)

原理如下图所示:

img

输入数据;

隐藏层权重计算;softmax激活函数归一化;

那么比如在一次的输出过程中输出结点的值是如下:

[0.2,0.1,0.05,0.1,0.2,0.02,0.08,0.01,0.01,0.23]

从上面看到的是,找出最大。我选取的动作是动作10,因为0.23是这次概率最大的,那么怎么理解多分类呢?很容易,如果你想选取俩个动作,那么就找概率最大的俩个值即可~(这里只是简单的告诉大家softmax在实际问题中一般怎么应用)

softmax相关求导

当我们对分类的loss进行该进的时候,我们要通过梯度下降,每次优化一个step大小的梯度,这个时候我们要求对loss对每个权重矩阵偏导然后用链式法则求解img

们能得到下面公式:

z4 = w41*o1+w42*o2+w43*o3

z5 = w51*o1+w52*o2+w53*o3

z6 = w61*o1+w62*o2+w63*o3

z4,z5,z6分别代表结点4,5,6的输出,01,02,03代表是结点1,2,3往后传的输入.

那么我们可以经过softmax函数得到

a_{4}= \frac{e^{z4} }{z^{z4}+z^{z5}+z^{z6}}

a_{5} =\frac{e^{z5} }{z^{z4}+z^{z5}+z^{z6}} a_{6}= \frac{e^{z6} }{z^{z4}+z^{z5}+z^{z6}}

好了,我们的重头戏来了,怎么根据求梯度,然后利用梯度下降方法更新梯度!

要使用梯度下降,肯定需要一个损失函数,这里我们使用交叉熵作为我们的损失函数

当然,你也可以使用其他函数求解;

交叉熵函数形式如下:

img

备注:

其中y代表我们的真实值,a代表我们softmax求出的值,。i代表的是输出结点的标号!在上面例子,i就可以取值为4,5,6三个结点(当然我这里只是为了简单,真实应用中可能有很多结点)。

现在看起来是不是感觉复杂了,居然还有累和,然后还要求导,每一个a都是softmax之后的形式

但是实际上不是这样的,我们往往在真实中,如果只预测一个结果,那么在目标中只有一个结点的值为1,比如我认为在该状态下,我想要输出的是第四个动作(第四个结点),那么训练数据的输出就是a4 = 1,a5=0,a6=0,哎呀,这太好了,除了一个为1,其它都是0,那么这个0可以取除,看1;

了形式化说明,我这里认为训练数据的真实输出为第j个为1,其它均为0!

那么Loss就变成了Loss = -y_{j}lna_{j} ,累和已经去掉了,太好了。现在我们要开始求导数了!

为了形式化说明,我这里认为训练数据的真实输出为第j个为1,其它均为0!

那么Loss就变成了Loss = -y_{j}lna_{j} ,累和已经去掉了,太好了。现在我们要开始求导数了!

我们在整理一下上面公式,为了更加明白的看出相关变量的关系:

其中y_{j} =1,那么形式变为Loss = -lna_{j}

那么形式越来越简单了,求导分析如下

参数的形式在该例子中,总共分为w41,w42,w43,w51,w52,w53,w61,w62,w63.这些,那么比如我要求出w41,w42,w43的偏导,就需要将Loss函数求偏导传到结点4,然后再利用链式法则继续求导即可,举个例子此时求w41的偏导为:

w51…..w63等参数的偏导同理可以求出,那么我们的关键就在于Loss函数对于结点4,5,6的偏导怎么求,如下:

这里分为俩种情况:

img

j=i对应例子里就是如下图所示:

比如我选定了j为4,那么就是说我现在求导传到4结点这!

那么由上面求导结果再乘以交叉熵损失函数求导

Loss = -lna_{j} ,它的导数为-\frac{1}{a_{j} } ,与上面a_{j}(1-a_{j} ) 相乘为a_{j}-1 形式非常简单,这说明我只要正向求一次得出结果,然后反向传梯度的时候,只需要将它结果减1即可,后面还会举例子!)那么我们可以得到Loss对于4结点的偏导就求出了了(这里假定4是我们的预计输出

第二种情况为:

img

这里对应我的例子图如下,我这时对的是j不等于i,往前传:

那么由上面求导结果再乘以交叉熵损失函数求导

Loss = -lna_{j} ,它的导数为-\frac{1}{a_{j} } ,与上面-a_{j}a_{i}相乘为a_{i}形式非常简单,这说明我只要正向求一次得出结果,然后反向传梯度的时候,只需要将它结果保存即可,后续例子会讲到这里就求出了除4之外的其它所有结点的偏导,然后利用链式法则继续传递过去即可!我们的问题也就解决了!

下面我举个例子来说明为什么计算会比较方便,给大家一个直观的理解

举个例子,通过若干层的计算,最后得到的某个训练样本的向量的分数是[ 2, 3, 4 ],

那么经过softmax函数作用后概率分别就是=[\frac{e^{2} }{e^{2}+e^{3}+e^{4}}

,\frac{e^{3} }{e^{2}+e^{3}+e^{4}} ,\frac{e^{4} }{e^{2}+e^{3}+e^{4}} ] = [0.0903,0.2447,0.665],如果这个样本正确的分类是第二个的话,那么计算出来的偏导就是[0.0903,0.2447-1,0.665]=[0.0903,-0.7553,0.665],是不是非常简单!!然后再根据这个进行back propagation就可以了

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值