Word2vec:理论学习笔记

本篇博文仅仅用于自己学习的笔记。里面有很多地方是出于自己对模型算法的一些理解,若有错误欢迎指正。

参考论文

Efficient Estimation of Word Representations in Vector Space
Distributed Representations of Words and Phrases and their Compositionality

CBOW模型:

概述:

CBOW模型,中文译为“连续词袋模型”,全称(Continuous Bag-of-Words),完成的任务是给定中心词wiw_{i}的一个去心邻域(比如半径为2,通常成为windows,窗口,这里窗口的大小为5)内的单词(wi2,wi1,wi+1,wi+2)(w_{i-2},w_{i-1,w_{i+1},w_{i+2}}),预测w_i的概率,由于没有考虑词之间的顺序,所以称为词袋模型。

模型图:

Word2vec:理论学习笔记

w(t-1),w(t-2),w(t+1),w(t+2) 表示输入的单词的词向量。中间的不是一般的全链接的projection层,而是简单的对输出的词向量进行简单的求和再取平均得到这一层的输出,所有中间叫SUM。输出层是一个softmax层得到词汇表各词的概率。

skip-gram模型:

概述:

Skip-Gram模型和CBOW的思路是反着来的,即输入是特定的一个词的词向量,而输出是特定词对应的上下文词向量。对于这句话:“The quick brown fox jumps over the lazy dog.”的训练样本如下:

Word2vec:理论学习笔记

模型图:

Word2vec:理论学习笔记

Softmax层的限制:

当我们的词汇表大小在百万级别以上时,这意味着我们用softmax计算各个词的输出概率的的计算量很大。

Hierarchical Softmax层(分成的softmax层):

概述:

  • 为了避免要计算所有词的softmax概率,word2vec采样了霍夫曼树来代替从隐藏层到输出softmax层的映射。我们把输出softmax层变成了一颗二叉霍夫曼树,那么我们的softmax概率计算只需要沿着树形结构进行就可以了。
Word2vec:理论学习笔记
  • 霍夫曼树的所有内部节点就类似之前神经网络隐藏层的神经元,根节点是树的入口,叶子节点的个数就是词汇表的大小。在霍夫曼树中,隐藏层到输出层的softmax映射不是一下子完成的,而是沿着霍夫曼树一步步完成的,因此这种softmax取名为"Hierarchical Softmax"。
  • 如何“沿着霍夫曼树一步步完成”呢?在word2vec中,我们采用了二元逻辑回归的方法,即规定沿着左子树走,那么就是负类(霍夫曼树编码1),沿着右子树走,那么就是正类(霍夫曼树编码0)。判别正类和负类的方法是使用sigmoid函数,即:
Word2vec:理论学习笔记
  • 其中xwx_{w}时输入,θ是逻辑回归模型的参数
  • 容易理解,被划分为左子树而成为负类的概率为P(−)=1−P(+)。在某一个内部节点,要判断是沿左子树还是右子树走的标准就是看P(−),P(+)谁的概率值大。而控制P(−),P(+)谁的概率值大的因素一个是输入的词向量和当前节点的模型参数θ。
  • 我们的目标就是找到合适的所有节点的参数θ和所有词的词向量, 使训练样本达到最大似然
  • 霍夫曼树的直观说明:树的每个叶子节点对应词汇表的一个词;数的中间节点和根节点可以看作一个神经元,它由一个与输入向量同维度的权重向量W和一个sigmod**函数组成,其中θ=w;对于与一个样本(wi,wj)即霍夫曼树的根节点的输入是wi,我们的训练目的就是让当输入wi是根节点到wj对应的叶子结点路径的概率最大

训练:

  • 上面树上输出w2的概率如下:
    P(w2w)=(111+e(wTθ1))(111+e(wTθ2))11+e(wTθ3) P(w2│w)=(1-\frac{1}{1+e^{(-w^T θ_{1} )}})(1-\frac{1}{1+e^{(-w^T θ_{2} )}})\frac{1}{1+e^{(-w^T θ_{3} )}}
  • 训练的目标就是将样本对应的概率最大化
  • 为了将树形结构转化为矩阵运算个人的一个想法是:
    P(+)=sigmod(wT×θwPi)P(+)=sigmod(w^T×θ_w*P_i)
    P()=1P(+)P(-)=1-P(+)
    P=(P(+)P())P=(\frac{P(+)}{P(-)})
  • 第三步:我们将为每个叶子节点定义一个mask数组maski=((Mask(i+)Mask(i)))mask_i=(\frac{(Mask_(i+)}{Mask_(i-)} ))该数组的长度等于P长度,Mask(i+)Mask_ {(i+)}是对应P(+),用来取出P(+)中对应于根节点到第i个叶子结点节点路径上往右走的节点;Mask(i)Mask_{(i-)}是对应P(-),用来取出P(-)中对应于根节点到第i个叶子结点节点路径上往左走的节点。
    output=multiply(Mast(P,mast))output=multiply(Mast(P,mast))
  • 说明:
    ××:矩阵乘法 *:对应元素相乘
    multiply(matrix)multiply(matrix):将每列对应所有元素乘起来形成新数组的一个元素
    Mast(list,matrix)Mast(list,matrix):按照matrix中每一列提取list中间的元素形成新矩阵的一列

Negative Sampling(负采样)近似softmax层:

采样方式:

对于给定的词w,我假设负采样集合为NEG(w)={wi},i=1,2,…neg, w的上下文为context(w),那么(context(w),w)就是一个正例,其他(context(w),wi)就是一个负例。现在的问题就是我们如何选取从预料库C中选取NEG(w).我们要求词频高的词容易被随机到,而词频低的词不容易被随机到。步骤如下:

  • 我们先为每个词在长度为1的线段上分一个小段给它,公式如下:
    len(w)=(count(w))(uϵCcount(u))len(w)=\frac{(count(w))}{(\sum_{uϵC}count(u))}
    Count(w)Count(w):是词w的词率
    线段的划分点:l0=0,,lk=i=0klen(wi)l_0=0,…,l_k=\sum_{i=0}^{k}len(w_i),词wiw_i对应的区间就是[l(i1),li][l_(i-1),l_i]
  • 将长度为1的线段等分M=108M=10^8,表示为[m1,m2,,m(108)][m_1,m_2,…,m_{(10^8 )}]
  • 这样每个mim_i都会存一个词wjw_j对应发区间里,这样形成一个M到W的映射。
  • 随机选取:从[m1,m2,,m(108)][m_1,m_2,…,m_(10^8 )]取一个随机一段mim_i,在取这一段对应的词wjw_j。如果对于词wjw_j,正好选到它自己,则跳过。负例样本集合NEG(w)的大小在Word2Vec源码中默认选5.
Word2vec:理论学习笔记

训练:

  • Softmax层是一个sigmod**的全连接层+概率归一化
    y(xi)=(exp(xi))(i=1Mexp(xj))y(x_i )=\frac{(exp⁡(x_i))}{(\sum_{i=1}^{M}exp⁡(x_j))}

  • 现在我们来讨论一下这个全连接的工作过程:

    • 假设现在一个向量X送到sotmax层来,其维度为N,词汇表的大小为V,那么全连接成的权重矩阵W的维度一个为N×V。
    • 最后的输出output=sigmod(XWoutput=sigmod(X*W)是一个V维的向量每个原素o_i代表的是输出词w_i非归一化的概率。
    • 分解开来就是:sigmod(XWi)=oi(wi)sigmod(X*W第i列)=o_i(w_i的概率),这样看来词汇表的每个词与权重矩阵中的列是一一对应关系,我们将W表示维(w1,w2,,wV)(w_1,w_2,…,w_V)
  • 现在我们就将Negative Sampling引入进来,输入X=w的上下文context(w),现在我们不需要考虑词汇表的所有词,只需要考虑NEG(w)=wi,i=0,1,,NegNEG(w)={wi},i=0,1,…, Neg,这里我们令w0=ww_0=w,即我们只需要这几个词的输出概率就ok了,于是我们对于权重矩阵我们也只需要其中NEG(w)对应的几列就ok了,我们将选出来的列组成的矩阵记维U=u0,u1,,uNegU={u_0,u_1,…,u_{Neg}},这样我们的计算变成output=sigmod(context(w)U)output=sigmod(context(w)*U)得到context(w)输出NEG(w)中每个词的概率,然后训练时我们最大化W0W_0对应的概率就ok了。这样可以看到虽然我们采用选的时词汇表的词,但实则我们选的是softmax层中权重矩阵W的列。Neg<<V,这样很大层度上降低那我们的计算量。