在文章词嵌入的那些事儿(一)中,咱们获得了如下结论:html
本文主要是在上文的基础上,对模型的隐藏层-输出层的设计作进一步探索。算法
霍夫曼编码(Huffman Coding),又译为哈夫曼编码、赫夫曼编码,是一种用于无损数据压缩的熵编码(权编码)算法。网络
霍夫曼树常处理符号编写工做。根据整组数据中符号出现的频率高低,决定如何给符号编码。若是符号出现的频率越高,则给符号的码越短,相反符号的号码越长。假设咱们要给一个英文单字"F O R G E T"进行霍夫曼编码,而每一个英文字母出现的频率分别以下图所示。dom
进行霍夫曼编码前,咱们先建立一个霍夫曼树,具体步骤以下:机器学习
给霍夫曼树的全部左节点设置为'0',全部右节点设置为'1'。函数
从根节点到叶子节点依序记录全部字母的编码,以下图所示:post
以上步骤就是对词进行霍夫曼编码的操做步骤。能够看到,词的出现频率越高,越靠近根节点,且编码长度越短。学习
首先回顾一下softmax函数。softmax(规范化指数函数)是网络输出层的函数,用于计算包含至少两种不一样类型的词嵌入向量。此外,它也常常被用做为神经网络的激活函数,相似的还包括sigmoid和tanh等函数。softmax的公式以下:编码
其中,激活输出向量的每一个元素都是在给定输入单词I的状况下,等于词汇表中第j个单词时的几率。同时,激活输出向量的全部元素之和等于1且每一个元素映射到区间[0,1]。这个算法的计算复杂度便是词汇表的大小O(V)。实践代表,咱们能够经过使用二叉树结构来有效地地减小此计算复杂度。下面,将介绍Hierarchical Softmax。url
使用Hierarchical Softmax的主要缘由是其计算复杂度是以2为底V的对数。
每一个单词均可以经过从根节点-内部节点的路径到达,此外,对这个路径的度量能够由沿着这条路径的各几率乘积表示。各个几率值由sigmoid函数产生:
其中x由输入和输出向量的点积求出,n(w,j)表示为从根节点到叶子结点w(即上下文单词)的路径上的第j个节点。
实际上,咱们能够用几率p来代替sigmoid函数。对于每一个内部节点,咱们都选择了一个任意子节点(左或右),并将正的sigmoid函数值赋给其中的一个(一般是左子节点)。
经过保留这些约束,节点n的左子节点的sigmoid函数能够描述为:
同理,节点n的右子节点的sigmoid函数能够描述为:
因此,输出词的计算几率为:
其中,L(w)表示霍夫曼树的深度,ch(n)表示节点n的子节点;角大括号表示布尔检验是否为真或假:若是布尔检验为True,说明节点n与其子节点ch(n)都在树的左边,即其子节点为左子节点。反之,若是布尔值为False,即其子节点ch(n)为右子节点。
回顾词嵌入的那些事儿(一)基于Tensorfow的Skip-Gram极简实现的内容,模型输出的实际上是预测目标词的几率,也就是说每一次预测都要基于所有的数据集进行softmax()几率计算。神经网络结构以下图所示:
而采用Hierarchical Softmax后,因为替换了以前的softmax()函数,因此,隐藏层的词嵌入向量不须要对词汇表每一个单词计算其为输出词的几率。
例如假设输出词是w2,所以能够沿着霍夫曼树从根节点(即词嵌入向量)一直走到咱们的叶子节点w2(输出词)。由下图能够观察到,仅需执行3步的sigmoid函数计算,就能够肯定叶子节点w2的位置。这无疑大大减小了操做数。
实际上,咱们在计算词嵌入向量所采用的霍夫曼编码与第一节的介绍基本一致,区别只是对左右节点的0 1计数有所不一样,好比:
那么,霍夫曼树是否是计算词嵌入向量的最优解?假设咱们的训练样本里的中心词w是一个很生僻的词,那么就得在霍夫曼树中一直往下寻找路径。能不能不用搞这么复杂的一颗霍夫曼树,将模型变的更加简单呢?Negative Sampling就是这么一种求解word2vec模型的方法,它摒弃了霍夫曼树,采用了Negative Sampling(负采样)的方法来求解,下面咱们就来看看Negative Sampling的求解思路。
首先,须要了解噪声对比估计(NCE)。
噪声对比估计(NCE)的核心思想是经过logistic回归将一个多分类问题转化为一个二分类问题,同时保留学习到的词向量的质量。在NCE中,词向量再也不是经过从中心词中预测上下文单词来学习,相反经过学习如何从(target, random word from vocabulary)对中区分出真实的(target, context)对从而完成词向量的计算。换句话说,若是一个模型可以从随机噪声中分辨出实际的目标词对和上下文词对,那么好的词向量就会被学习。
而Negative Sampling是基于噪声对比估计(相似于生成对抗性网络)的一种方法。
即一个好的模型应该经过逻辑回归来区分假信号和真实信号。同时Negative Sampling背后的思想相似于随机梯度降低:不是每次都改变全部的权重,考虑到咱们所拥有的成千上万的观测数据,咱们只使用了其中的K个,而且显著地提升了计算效率:
正如上图公式,与随机梯度降低法的区别在于,咱们不只考虑了一个观测结果还考虑了其中的K个。
对于训练数据集,咱们使用的是具备噪声分布的数据集。之因此使用这种噪声分布数据集,是为了区分真实数据和咱们试图解决的假数据。具体来讲,对于每一个正样本(即 true target/context pair),咱们从噪声分布中随机抽取k个负样本,并feed进模型。对于小的训练数据集,建议k值在5到20之间,而对于很是大的数据集,k值在2到5之间就足够了。咱们的模型只有一个输出节点,它能够预测这对数据是随机噪声数据仍是真实有效的target/context对。
因为采用了随机采样,因此须要假定一个几率分布。在词汇表中每一个单词wi被采样到的几率由下式决定,其中幂为3/4。之所取3/4是由于能够减弱因为不一样频次差别过大形成的单词采样差别的影响,使得小频次的单词也有必定被采样的几率。f(w)是词汇表中单词w出现的频率:
举例说明:
在采样前,咱们将长度为1的线段划分红M等份,这里M>>V,这样能够保证每一个词对应的线段都会划分红对应的区间块。在采样时,咱们只须要从M个区间中采样出neg个区间,此时采样到的每个区间块对应到的线段所属的词就是咱们的负例词。
可能会有疑问:使用Negative Sampling后,负样本数量较多,正样本只有一个,会不会出现样本不均衡的现象从而致使逻辑回归模型分错左右子节点?实际上,样本不均衡这种问题主要出如今分类算法中。而咱们这里词向量的训练本质不是一个分类问题,因此问题不大。
最后,通常来说,NCE是一种渐近无偏的通常参数估计技术,而Negative Sampling更常常被用在二分类模型(例如逻辑回归)中,它们对词向量学习有用,但不是做为通用估计器去执行其余机器学习任务。具体能够参考这篇论文:Notes on Noise Contrastive Estimation and Negative Sampling 。
[1] 维基百科:霍夫曼编码
[2] Language Models, Word2Vec, and Efficient Softmax Approximations
[3] word2vec(cbow skip-gram hierarchical softmax Negative sampling)模型深度解析