手撕word2vec
最近看了一些招聘的面经,深感面试官问的问题很多都是理论基础,但是如果只是浅尝辄止,了解不深入的话一般很可能回答不上来。譬如说机器学习里的一些算法细节、深度学习里的一些优化,只会调包而没有透彻理解原理是万万不行的。
我感觉我之前学习方式的对找工作有很大弊端,一般都是对原理稍作了解就开始运用代码,实则并没有将理论消化吸收。比如说接触了很久的word embedding,经典模型word2vec的原理大致了解,知道skip-gram和CBOW的基本原理(如图),只知道运用了层次softmax和负采样(negetive sample),却不明了这两者是为什么而设置的,又是怎么实现的。
一、模型
1.CBOW
2.Skip-gram
其中:(来自cs224笔记)
二、负采样
1.为什么设置负采样?
当计算属于某个分类的概率,就要把所有分类的概率都计算出来,有的时候计算能力不够计算这么多。譬如在Word2vec进行最优化的求解过程中,从隐藏层到输出的softmax层的计算量很大,因为要计算所有词的softmax概率,再去找概率最大的值。
负采样借鉴了NCE想法,是把多分类变成二分类,对每个正例(中央词语及上下文中的一个词语)采样几个负例(中央词语和其他随机词语),训练binary logistic regression(也就是二分类器),减少计算量。
2.word2vec中负采样的实现
推导过程如下:
3.如何选择负集
采样算法都应该保证频次越高的样本越容易被采样出来。基本的思路是对于长度为1的线段,根据词语的词频将其公平地分配给每个词语。
三、层次softmax
1.为什么设置层次softmax
和上面负采样一样的目的,为了减少计算复杂度。由于是二叉树,之前计算量为V(词汇表长度),现在变成了log2V。
层次Softmax使用一种二叉树结构来表示词典里的所有词,V个词都是二叉树的叶子结点,而这棵树一共有V−1个非叶子结点。对于每个叶子结点(词),总有一条从根结点出发到该结点的唯一路径。(如图所示)这个路径很重要,因为要靠它来估算这个词出现的概率。
2.word2vec里如何实现
在模型的训练过程中,通过Huffman编码,构造了一颗庞大的Huffman树(构造最短路径)。我们要计算的是目标词w的概率,这个概率的具体含义,是指从root结点开始随机走,走到目标词w的概率。因此在途中路过非叶子结点(包括root)时,需要分别知道往左走和往右走的概率,每次选择就是一个二分类。
例如:
四、源码详解
看到一篇博客讲的很详细,搬运下
取对数之后可得: