word2vec中关于霍夫曼树的应用原理

来源:互联网 发布:淘宝助理5.6.4.1 编辑:程序博客网 时间:2024/04/29 11:57
看了word2vec中虽然对霍夫曼原理有所了解。但是没有找到使用霍夫曼编码的原理。
在google上搜到这篇文章,感觉写的很不错,果断转了http://xiaoquanzi.net/?p=156

2013年末,Google发布的word2vec引起了一帮人的热捧,各种兴奋。时至今日,各地讨论的也不似如此频繁,也是时候写一下个人对它的理解,亦可避免被真正的有识之士鄙视。

在大量赞叹word2vec的微博或者短文中,几乎都认为它是深度学习在自然语言领域的一项了不起的应用,各种欢呼“深度学习在自然语言领域开始发力了”。但实际上,简单看看代码就知道它实际上只是一个三层网络,压根算不上所谓的深层网络,学习过程也很简单,并未用太玄妙的东西,以至于在了解完整以后对它的简单叹为观止。

笔者其实也是门外汉,幸好周围有一些高人,几经指点,自认为大体了解,作此鄙文,记录一下。

首先,它的结构就是一个三层网络——输入层、隐层(也可称为映射层),输出层。
其次,代码中让人费解(没学过神经网络,是以费解)的主要是hierarchicalsoftmax。得同事J指导,和同事S讨论,终于弄明白其网络结果,如下图所示:

word2vec_hs_network

word2vec层次softmax网络示意图

输入层读入窗口内的词,将它们的向量(K维,初始随机)加和在一起,形成隐藏层K个节点。输出层是一个巨大的二叉树,叶节点代表语料里所有的词(语料含有V个独立的词,则二叉树有|V|个叶节点)。而这整颗二叉树构建的算法就是Huffman树。这样,对于叶节点的每一个词,就会有一个全局唯一的编码,形如"010011"。我们可以记左子树为1,右子树为0。接下来,隐层的每一个节点都会跟二叉树的内节点有连边,于是对于二叉树的每一个内节点都会有K条连边,每条边上也会有权值。

这样,整体的结构就清晰了。在训练阶段,当给定一个上下文,要预测后面的词(Wn)的时候(word2vec的CBOW和Skip-gram都不是预测后面的词,都是在中间的词上做文章,但是本文这么写并不影响理解),实际上我们知道要的是哪个词(Wn),而Wn是肯定存在于二叉树的叶子节点的,因此它必然有一个二进制编号,如"010011",那么接下来我们就从二叉树的根节点一个个地去便利,而这里的目标就是预测这个词的二进制编号的每一位!即对于给定的上下文,我们的目标是使得预测词的二进制编码概率最大。形象地说,我们希望在根节点,词向量和与根节点相连经过logistic计算得到的概率尽量接近0(即预测目标是bit=1);在第二层,希望其bit是1,即概率尽量接近1……这么一直下去,我们把一路上计算得到的概率相乘,即得到目标词Wn在当前网络下的概率(P(Wn)),那么对于当前这个sample的残差就是1-P(Wn)。于是就可以SGD优化各种权值了。

那么hs(hierarchicalsoftmax)如何保证叶节点输出的概率值(即我们一路沿二进制编号乘下去的概率)是归一化的呢(否则,所谓的残差1-P(Wn)就没什么意义了)?这点其实很简单,请看下图:

hierarchical softmax intuiation

hierarchical softmax说明

从根节点开始,对于一个sample而言,目标词是W2,二进制编码是"110"。我们在根节点计算得到它的第一位是'1'的概率是P,那么它第一位是'0'的概率就是1-P;在左子树里,第二位是"1"的概率是P',那么第二位是"0"的概率就是1-P',而在右子树里,第二位是"1"的概率是P'',那么第二位是"0"的概率就是1-P'';第三位亦如此。为方便表示记,我们只写到第二层。这样,在第二层,整个概率之和就是

(P*(P') + P*(1-P')) + ((1-P)*(P'') + (1-P)*(1-P'')) = P + (1-P) =1

即按照目标词的二进制编码计算到最后的概率值就是归一化的,这也是为啥它被称作hierarchical softmax的原因。

如果没有使用这种二叉树,而是直接从隐层直接计算每一个输出的概率——即传统的softmax,就需要对|V|中的每一个词都算一遍,这个过程时间复杂度是O(|V|)的。而使用了二叉树(如word2vec中的Huffman树),其时间复杂度就降到了O(log2(|V|)),速度大大地加快了。

不过虽然hierarchicalsoftmax一般被认为只是用于加速,但是仍然可以感性地理解一下为啥它会奏效:二叉树里面的每一个内节点实际上是一种隐含概念的分类器(二元分类器,因为二进制编码就是0/1),它的输出值的大小预示着当前上下文能够表达该隐含概念的概率,而一个词的编码实际上是一堆隐含概念的表达(注意,这个隐含概念的表达和词向量的维度所表达的隐含概念是不一样的)。我们的目标就在于找到这些当前上下文对于这些概念分类的最准确的那个表达(即目标词向量)。由于概念之间实际上是有互斥关系的(二叉树保证),即在根节点如果是"1",即可以表达某一概念,那么该上下文是绝对不会再有表达根节点是"0"的其他情况的概念了,因此就不需要继续考虑根节点是"0"的情况了。因此,整个hierarchicalsoftmax可以被看作完全不同于传统softmax的一套。

写到这里,感觉没有想象的那么明白。sigh,果然下笔难成书。再慢慢润色吧。

感谢同事JCH,SC,ZQQ以及软件所LSW博士的指导。

0 0
原创粉丝点击