词嵌入向量(Word Embedding)的建模

1、Embedding函数

     从前面的定义,我们期望在隐层中找到一个/组嵌入函数W(这里采用lookup table的方式),使得![][3]具体的,假设指定固定的向量维度,W("篮球")=(0.2, -0.4, 0.7, ...),W("苹果")=(0.0, 0.6, -0.1, ...),W初始化时可以赋值给每个维度一个随机数,并通过与output层连接建立学习模型/任务后得到有意义的向量。

2、建模

接下来来看看如何建立和训练模型。

  • 数据准备
    为给模型准备数据,我们首先需要定义或获取n个样本:![][4]
    假如我们有一个句子“姚明 的 篮球 打得 很不错”。常规方式是首先由统计语言模型,由中间词预测周围词(SKIP-GRAM),或由周围词预测中间词(CBOW)等方式,然后以指定的窗口向前推进。以SKIP-GRAM方式为例,假设推进窗口为2(以篮球为中心),我们可以得到样本对:("篮球","的"),("篮球","姚明"),("篮球","打得"),("篮球","很不错"),X skip至"打得"时(以打得为中心),得到样本对 :("打得","篮球"),("打得","的"),("打得","很不错"),以此类推...我们可以得到用于模型的训练样本。

  • 样本表示
    样本拆解出来了,接下来如何用数值来表达这些样本对呢?常用的办法是将所有的训练数据,即“word”对抽取出唯一不重复的单词来构建词典表(vocabulary),然后将样本数据中的“word”表达成one-hot编码,编码时只对有值的位置上为1其他位置均为0,以上面例子为例,“姚明 的 篮球 打得 很不错”。基于这个句子可以构建维度为5的词典表:{:0 "姚明",  :1, "的"  :2,"篮球"  :3,"打得"  :4,"很不错" },那么训练样本("篮球","姚明")即可表达为([0,0,1,0,0],0),看起来比较像常规的多分类数据了,这里为了好理解Y表示成了位置编号,后续在模型中仍以one-hot向量表达。

  • 各层条件分布
    神经网络基于这些训练样本将会输出一个概率分布,这个概率代表着我们的词典中的每个词是output word的可能性。更一般的,假设隐层有K个节点(即生成word对应vector向量的维度),对每个样本,我们需要做两件事情:

    • 给定隐层后预测output word的概率,即需要建个模型来估计![][5]
    • 将观测到的input word喂给隐层嵌入函数,得到隐层的概率分布,![][6]用连接函数表达即上面提到的(常见的一般会是K个关于x线性组合的方程组,后面会讲到为何不用该方式)![][3]

    接下来我们需要构建整体的似然函数进行优化:

  • 目标函数
    分别建立input层-隐层及隐层-output层的连接函数(RGLM),input层和隐层的函数上面已给出,如果假设p(y|w)为正态分布,则 log-likelihood loss便是(negative) L2 loss:![][7],如果假设p(y|w)为多项分布,则likelihood loss便是softmax loss:![][8]从训练样本可以看出,output层为多分类,即隐层-output可采用softmax loss.
    为了准确预测output word,该网络需要根据上述损失函数学习参数矩阵W和R(output层),实际上,对于我们来说,整个学习任务是为了学习隐层的W函数,即隐层节点参数。当然对于其他任务,比如神经网络推荐或Fasttext,网络构造过程类似,只是学习的任务是学习输出层的参数和结构。

  • 模型训练
    常规优化方法会采用梯度下降和反向传播,由上面的样本定义,我们的训练样本中input和output均以one-hot表示,向量极其稀疏(通常完整字典表会是几十万维,假设200000),仅有一个位置的数值为1,其余均为0,如果input到隐层的嵌入函数采用常见方式的话,假设节点数即嵌入向量维度为200,则隐层参数矩阵每个样本的迭代将会是1x200000的向量和200000x200矩阵的相乘,显然会带来巨大计算资源的消耗,其实每个样本的隐层参数仅需要根据one-hot向量中数值为1的索引对应的隐层参数参数矩阵的该索引行对应的向量取出即可:

     

    词嵌入向量(Word Embedding)的建模_第1张图片

    经过抽象后我们可以得到上面定义的Embedding函数/参数矩阵:

    词嵌入向量(Word Embedding)的建模_第2张图片
  • 这种方式其实联系上面提到的lookup table就容易理解了,即模型中的隐层权重矩阵便成了一个”查找表“(lookup table),进行矩阵计算时,只需要直接去查输入的one-hot向量中提取非零位置的索引,在隐层的对应行输出就是每个输入单词的“嵌入词向量”,该过程即完成了嵌入的动作。
    对于输出层:
    经过隐层的嵌入计算,input word会被映射为1x200的dense向量,再喂给输出层经过softmax的分类器的计算,对随机给定任意output word的嵌入向量计算其预测概率:![][8],这样基于同一input word,替换不同的beta(output word的嵌入向量)得到不同output word的预测概率。

    至此,数据的表示及目标损失函数的定义以及模型训练过程已拆解完毕。接下来,再看看训练性能提升和优化的方法。

3、抽样

       基于上面的拆解,我们会发现其实训练过程涉及的参数数量会非常庞大,以上面的200000个单词的字典表为例,隐层嵌入200维的词向量,那么每次迭代的输入-隐层权重矩阵和隐层-输出层的权重矩阵都会有 200000 x 200 = 4000万个权重,在如此庞大的神经网络中进行梯度下降是相当慢的,而且需要大量的训练数据来调整这些权重并且避免过拟合。所以对性能的要求仍然很高,虽然上面已经采用lookup table的方式简化了一些计算,针对这个问题,Word2Vec的作者在论文提出了有效的方法,叫“negative sampling”,每个训练样本的训练只会更新一小部分的模型权重,从而降低计算负担,甚至是词向量的质量。基于对假设是,我们的数据中存在大量冗余和噪音,举例:对于“的”这种常用高频单词,我们会发现一些问题:当我们得到成对的单词训练样本时,**("的", "篮球") *这样的训练样本并不会给我们提供关于“篮球”更多的语义信息,因为“的”这样的噪音词在大部分单词的上下文中几乎都会出现。由于在语料中“的”这样的常用词出现概率很大,因此我们将会有大量的(”的“,...)这样的训练样本,而这些样本数量远远超过了我们学习“的”这个词向量所需的训练样本数。所以在设计抽样方法的时候可以对这样的样本直接排除在训练样本之外,对于其他样本对随机抽取少量的负样本进行参数的更新,而不是对one-hot向量中所有200000个位置对样本都进行计算,从而大大提高训练效率。
上面叙述的有点繁杂,总结起来就是在对给定input word计算softmax时,不去更新所有词表中word的输出概率,而是从该样本的output word之外随机抽样有限个(比如只抽样5个word)作为负样本计算其概率,进一步进行梯度和参数的更新。也就是说通过负样本抽样对于每次训练只更新(5+1)个beta向量对应的参数,也就是2006=1200个参数,这样与4000万个相比,需要更新的参数占比仅为0.003%,效率提升可想而知。

 

“无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。”



 

你可能感兴趣的:(自然语言处理,机器学习,词嵌入向量,Word,Embedding)