参考:
https://www.zhihu.com/question/44832436/answer/266068967
http://mccormickml.com/2016/04/19/word2vec-tutorial-the-skip-gram-model/
https://zhuanlan.zhihu.com/p/26306795 感谢三位作者。
目录
Word2Vec包含了两种词训练模型:CBOW模型和Skip-gram模型。
CBOW模型根据中心词W(t)周围的词来预测中心词
Skip-gram模型则根据中心词W(t)来预测周围词
Skip-gram模型
模型计算word2vec的流程:以CBOW模型的流程为例
- 输入层:上下文单词的onehot. {假设单词向量空间dim为V,上下文单词个数为C}
- 所有onehot分别乘以共享的输入权重矩阵W. {V*N矩阵,N为自己设定的数,初始化权重矩阵W},此处没有激活函数.
- 所得的向量 {因为是onehot所以为向量} 相加求平均作为隐层向量, size为1*N.
- 乘以输出权重矩阵W' {N*V}
- 得到向量 {1*V} 激活函数处理得到V-dim概率分布 {PS: 因为是onehot,其中的每一维都代表着一个单词},概率最大的index所指示的单词为预测出的中间词(target word)
- 与true label的onehot做比较,误差越小越好
所以,需要定义loss function(一般为交叉熵代价函数),采用梯度下降算法更新W和W'。训练完毕后,输入层的每个单词与矩阵W相乘得到的向量的就是我们想要的词向量(word embedding),这个矩阵W(所有单词的word embedding)也叫做look up table,也就是说,任何一个单词的onehot乘以这个矩阵都将得到自己的词向量。有了look up table就可以免去训练过程直接查表得到单词的词向量了。
CBOW模型流程举例
假设我们现在的Corpus是这一个简单的只有四个单词的document:
{I drink coffee everyday}
我们选coffee作为中心词,window size设为2
也就是说,我们要根据单词"I","drink"和"everyday"来预测一个单词,并且我们希望这个单词是coffee。
假设我们此时得到的概率分布已经达到了设定的迭代次数,那么现在我们训练出来的look up table应该为矩阵W。即,任何一个单词的one-hot表示乘以这个矩阵都将得到自己的word embedding。
注-帮助理解:
(1)训练是从第一个单词开始的,如果window size是2,对第一个单词而言上下文单词的个数就是2(如下图所示);同理直到最后一个单词;W是整个语料库的矩阵,输入层是每个单词的onehot向量,与W相乘会得到相应的属于该单词的向量。在反向传播梯度下降进行更新的时候也只更新相应单词的W和W'。所以训练得到的W是整个语料库的词向量。
(2)当模型训练完后,最后得到的其实是神经网络的权重,比如现在输入一个 x 的 one-hot encoder: [0,1,0,0],对应刚说的那个词语『drink』,则在输入层到隐含层的权重里,只有对应 1 这个位置的权重被激活,这些权重的个数,跟隐含层节点数是一致的,从而这些权重组成一个向量 W 来表示X,而因为每个词语的 one-hot encoder 里面 1 的位置是不同的,所以,这个向量 W就可以用来唯一表示X。
(3)一般选择W作为词向量,但W'理论上也可作为词向量。设语料库中的词汇量共V个,输出 y 也是用 V 个节点表示的,对应V个词语,所以其实,我们把输出节点置成 [0,1,0,0],它也能表示『drink』这个单词,但是激活的是隐含层到输出层的权重,这些权重的个数,跟隐含层一样,也可以组成一个向量 W',跟上面提到的W 维度一样,并且可以看做是词语『drink』的另一种词向量。而这两种词向量W和 W',正是 Mikolov 在论文里所提到的,『输入向量』和『输出向量』,一般我们用『输入向量』。
(4)需要提到一点的是,这个词向量的维度(与隐含层节点数一致)一般情况下要远远小于词语总数 V 的大小,所以 Word2vec 本质上是一种降维操作——把词语从 one-hot encoder 形式的表示降维到 Word2vec 形式的表示。