• (六) 语言模型 Language Madel 与 word2vec


    语言模型简介(Language Model)

    简单的说,语言模型 (Language Model) 是用来计算一个句子出现概率的模型,假设句子  ,其中  代表句子中的第  个词语,则语句 W 以该顺序出现的概率可以表示为:

      

    其中 ,  $p(w_n|w_1^{n-1}) = p(w_n|w_1,w_2,...,w_{n-1})$  ,  $ p(w_n|w_1^{n-1})$ 即为 Language Model 的参数,。通常参数的求解用方法是 N-gram 模型,最大熵模型,HMM,CRF 以及本文将重点讲述的 Neural Network Lauguage Model ,对于 N-gram 中的 $ p(w_n|w_1^{n-1})$ 是这样计算的,先引入大小为  的词表,与语料库  :

      

     ,即在语料库  中出现的次数注意到 $ p(w_n|w_1^{n-1})$ 计算的复杂性与稀疏性,所以计算一般是引入 Markov 假设,即词语的出现仅与其前 k 个词相关 即  ,  这样就大大简化了计算,k 即为 N-Gram 中的 N,比如 K = 2 ,有

      

    这里还有一些平滑的技巧,比如   =  0 时的处理等等,这里不再赘述。将计算好后的参数保存起来,之后即可用到各种各样的NLP任务重,比如分词,词性标注,NER 等等。

    神经网络语言模型(Neural Network Lauguage Model,NNLM)

    神经网络语言模型(以下简称 NNLM )正式由 Bengio 与于 2003 年提出,他也是用于计算  的一种模型(该模型同样假设语料库中词语只与前 k 个相关),这里为了便于表示, 另 $context(w_n) = w_{n-k+1}^{n-1}$ ,便可以得到给定词语 $w$ 在当前上下文中出现的概率为  ,不同于 N-gram 的直接统计频率的方式, NNLM 用一个关于 $ heta$ 的函数 $F(w,context(w), heta)$ 来表示  ,意思就是说,当前词为  时,其上下文为  的概率可以用一个关于  的函数 $F(w,context(w), heta)$ 表示,然后问题就转变为了求得最优的参数  来生成 Language Model , 待求得 $ heta^*$ 后 ,对于任意在词表  中的词语  ,都可以直接带入到 $F(w,context(w), heta^*)$ 中,得到其对应的概率 , NNLM 即是采用神经网络结构来构造函数 $F(w,context(w), heta^*)$ 的,构造完成后,根据训练语料  来求得最优的参数  即可。这里求解算法采用的是参数估计中极大似然估计,即:

      

    以上公式何解呢?就是假设语料库 $C$ 是按照 $F(w,context(w), heta)$ 生成的 , 现在 $C$ 已经在那里了,但参数 $ heta^*$ 还不知道,很简单的 MLE 的思想就可解决了,此处 $R( heta)$ 是引入 $ heta$ 的先验信息来构造成 MAP ,也可以叫做正则化,但是 NNLM 里是没有引入任何先验信息的,所以这里不考虑 $R( heta)$ ,Bengio 提出的 NNLM 就长下边的那个样子

    很复杂的图,其实 idea 并不复杂,来看 NNLM 构造 ,首先,引入了词向量的概念,即将词表中的词语  表示为一个固定长度为 $M$ 向量的形式   ,(m 为人工定义的词向量的长度),这样整个词表可以用 一个  的矩阵表示,每一列为一个词向量,现在找到词 $w_t$ 的上下文 $context(w_t)$ ,  这里 Bengio 设定的上下文 $context(w_t)$ 是词 $w_t$ 的前  个词语,并把这  个词语的词向量首尾相接的拼起来,形成维度为 $(n-1)m$ 的向量来当做神经网络的输入,所以 NNLM 输入层的大小已经确定为 $(n-1)m$ , 隐层的规模就是人工指定了,输出层的大小为  $|V|$ ,为什么是 $|V|$ 呢,因为这里类似于 supervised learning ,输入特征为 $context(w_t)$ 对应的 $(n-1)m$ 维的向量,通过 NNLM 后期望的输出应该是词语 $w_t$ 了,即输出类似于模型学习到的到标签的映射,因为共有 $|V|$ 个词语,所以输出层维度为 $|V|$ , $w_t$ 在词表 $V$ 中的下标对应的维度就是映射 $w_t$ 的得分,而 softmax 正好可以把该得分归一化为概率。

    假设输入为词语 $w$ ,其上下文 $context(w)$ 拼接成一个输入 $mathbf{x}_w$ ,在 NN 中的计算如下所示:

      

    最后得到的向量  , 现在为了让  的每个分量  表示当前当前词为词表的第  个且当前上下文为  的概率,做一个softmax 归一化即可:

      

     此处, =  表示为词表中的第 i 个词,以上便为我们用 NN 构造出的代表概率的函数  ,然后采用 MLE 估计即可,这里待估计参数  分别为整个词表词语的词向量与 NN 中的权值  ,网络中还有一些需要设定的参数,比如上下文词语  的设定一般不大于 5 ,词向量的长度  一般介于  之间,另外需要注意 NNLM是自带平滑的,因为任意词语  的概率  都经过了 softmax 归一化,所以  取值介于(0-1)之间。计算还是用先前的公式:

      

    该 log 似然可以用梯度上升法来求解,具体这里不涉及了。参数求解完后,便得到了我们的语言模型,现在估计一个现实任务中的词语   对应的   时,只需将该词语  对应的词向量输入到  里,就会得到其对应的概率值。

     NNLM 的副产品词向量也包含了丰富的信息,因为每个词语都被表示为长度为  的向量,在词向量空间  中,语义相似的词语的距离会很接近,且会有 man - woman = king - queen 这种神奇的效果出现。另外除了词向量外,还有字向量,句子向量与文章向量 。之后的关于词向量的工作大部分都是对于这里词向量复杂性的进一步改进,13年的 mikolov 的word2vec 工作比较典型,分为为基于 Hierarchical Softmax 与 Negative Sampling 的,下边来一一介绍。

    基于 Hierarchical Softmax 的模型

    1)Continuous Bag-of-Words Model  CBOW

     CBOW 是在给定当前词   后,预测上下文信息为   ,而 Skip-gram 与之相反,是给定  ,预测中间空缺的词为  ,两个模型分别如下图所示:

    语言模型还是那个问题,映射函数的构造,这里根据任务不同 CBOW 需要构造的是  ,而 Skip-gram 需要构造的是  ,在CBOW 中,改进了 NNLM 中计算复杂的环节,去掉了 NNLM 中的隐藏层,且最后的 softmax 层在CBOW中也变成了一个 Huffman 树的结构。整个网络如下图所示:

    CBOW 的任务是给定词 $w_t$ ,预测其上下文  ,这里其上下文 $context(w_t)$ 是取其前后长度各位 c 共 2c 的词语,将这些词语的词向量作为输入,下面来看CBOW网络的结构:

    Input Layer

      输入为词语  对应的  ,取前后各 c 个词语,共 2c 个词语对应的词向量为  ,词向量的长度为 m(同 NNLM ,m为人工指定的词向量的长度)。

    Projection Layer

      将  中所有的词向量累加,   即为投影层的输出,将  送入Output Layer 即可, 的计算如下:

         

    Output Layer

      这里的输出层不再是 NNLM 中的 softmax 了,而改为了 Huffman 树结构,该树是通过统计词表 V 的词语构建的,通过统计预料 C 中的词语的词频,来构建这颗 Huffman 树,根据 Huffman 数的性质,词频大的词语所处的层数一般会很浅,树中的每个叶节点均代表一个词表 V 中的词语。可见共有 |V| 个叶节点,且叶节点的顺序为左大右小。

    CBOW这种层次的设计很大程度提高了网络的效率,但输出层树形结构的设计也导致了前向传导计算  的过程不同于 softmax ,为了方便推到,引入以下的符号:


      : 从根节点出发到词语  对应的叶节点的路径;

    : : 路径中包含的节点的个数为

     : 路径  中的各个节点, 代表根节点,  代表词语   对应的叶节点;

    : 词语  的 Huffman 编码(左 1 右 0),由  位编码构成( 从  开始 ), 表示路径  中节点  对应的编码;

     :路径中非叶子节点(共  个)对应的向量, 表示路径  中的第  个非叶子节点对应的向量。


    上边的符号太多,用一个例子来说明,设当前的词表 V 为 {我,喜欢,观看,巴西,足球,世界杯} ,在语料库 C 中统计的词频分别为 {15,8,6 ,5,3,1} ,构建的 Huffman 树如下图所示:(注意建树时词频大的当做左子树,词频小的当做右子树,且编码为左 1 右 0)。

    若当前的词语  为 “足球” , 则  为红线连接的路径,该路径包含  个节点,分别为  ,对应的 Huffman 编码  为 1001  ,  为路径上非叶节点对应的向量。

    当输入词语  后,会找到  前后的各 c 个词语的词向量,在投影层累加起来构造出  ,接下来  会传导到输出的 Huffman 层来构造最终的假设函数也即语言模型所要求的概率  。CBOW 是这样做的,从根节点  的过程中,每向下传导一层,即从根节点开始,每选择一次左右孩子的分支,就进行一次二分类。 分类器选择的是 Logistic Regression(LR),LR 中代表正负类的标签是用  {1 ,0}  表示的,正好对应了 Huffman 编码 中的 {1 ,0} ,  需要注意的是 CBOW 中 LR 采用的是左 0 右 1 的标签模式,节点  对应的标签  ,  分到左边即为标签为 0 的负类,分到右边即为 标签为 1 的正类。当在第  层分类时,节点  对应的参数为  根据 LR 的公式,分到正类的概率为:

      

    分到负类的概率自然为: 

    注意  会决定下一层的标签 ,最终通过不断二分类向下传导到词语 $w$ 对应的叶节点,词语  对应的概率  即把这些二分类联合起来:

    其中:

    写到一起有 $p(d_i^w|mathbf{x}_w, heta_{i-1}^w) = left [sigma ( heta^{w T}_{i-1}mathbf{x}_w)^{1-d_i^w} ight ] cdotleft [(1-sigma ( heta^{w T}_{i-1}mathbf{x}_w) ^{d_i^w} ight]$,现在就可以进行最后的 MLE 了,列出语料库中的所有词语,最大化以下似然函数即可 ,形式如下:

    egin{aligned}
    L &= prod_{w in C} p(w|context(w)) \
    &Rightarrow \
    logL&= sum_{w in C} logp(w|context(w)) \
    &=sum_{w in C} logleft [prod_{i=2}^{l^w} p(d_i^w|mathbf{x}_w, heta^w_{i-1}) ight ]\
    &= sum_{w in C} log left {prod_{i=2}^{l^w} left [ sigma ( heta^{w T}_{i-1}mathbf{x}_w)^{1-d_i^w} ight ] cdotleft [(1-sigma( heta^{w T}_{i-1}mathbf{x}_w) ^{d_i^w} ight ] ight } \
    &=sum_{w in C} sum_{i=2} ^{l^w} left { (1-d_i^w) cdot log left [ sigma ( heta^{w T}_{i-1}mathbf{x}_w) ight ] +d_i^w cdot left [1-sigma ( heta^{w T}_{i-1}mathbf{x}_w) ight ] ight }
    end{aligned}

    为了便于推倒,将上式花括号的内容写作 $L(w,i)$  ,即  $L(w,i)  =  (1-d_i^w) cdot log left [ sigma ( heta^{w T}_{i-1}mathbf{x}_w) ight ] +d_i^w cdot left [1-sigma ( heta^{w T}_{i-1}mathbf{x}_w) ight ] $ 。

    $ L $  便是 CBOW 的目标函数 ,对于 $ L$ 的优化,CBOW 采用的是梯度上升算法(因为要寻找的是 $max $ 值,寻找 $min $ 时采用梯度下降的方法即可),目标函数 $ L$ 中的参数包括 $ mathbf{x}_w   ,   heta_{i}^w $ ,其中 $ w in C $ , $ i = 1,2,...,l^{w-1} $ , 也就是所有非叶节点对应的权值向量 $ heta^w$ , 给定输入为 $w in C$ 时,要计算 $L$ 首先看 $L(w,j)$ 对$ mathbf{x}_w   ,   heta_{i-1}^w $ 的到倒数:

    egin{aligned}
    frac{partial L(w,i) }{partial heta_{i-1}^w}
    &= frac{partial }{partial heta_{i-1}^w}left { (1-d_i^w) cdot log left [ sigma ( heta^{w T}_{i-1}mathbf{x}_w) ight ] +d_i^w cdot left [1-sigma ( heta^{w T}_{i-1}mathbf{x}_w) ight ] ight } \
    &=(1-d_i^w) cdot left [ 1- sigma ( heta^{w T}_{i-1}mathbf{x}_w) ight ] cdot mathbf{x}_w - d_i^w cdot sigma ( heta^{w T}_{i-1}mathbf{x}_w) cdot mathbf{x}_w \
    &=left [ 1-d_i^w -sigma( heta^{w T}_{i-1}mathbf{x}_w) ight ] cdot mathbf{x}_w
    end{aligned}

    于是 $ heta_{i-1}^w $ 的梯度更新公式为:$  heta_{i-1}^w := heta_{i-1}^w + eta cdot left [ 1-d_i^w -sigma( heta^{w T}_{i-1}mathbf{x}_w) ight ] cdot mathbf{x}_w $

    同时根据 $ mathbf{x}_w $ 与 $  heta_{i-1}^w $ 的对称性可得到 $ mathbf{x}_w $ 的梯度:

    [frac{partial L(w,i) }{partial mathbf{x}_w }  =  left [ 1-d_i^w -sigma( heta^{w T}_{i-1}mathbf{x}_w) ight ] cdot heta_{i-1}^w ]

    因为 $ mathbf{x}_w $ 表示的是 $context(w)$ 中的词向量的和,如何采用 $frac{partial L(w,i) }{partial  mathbf{x}_w} $ 来对 $context(w)$ 中 $2c$ 个词向量的和进行更新呢, CBOW 是这样做的:

    [ mathbf{v}(ar{w}) := mathbf{v}(ar{w}) + eta sum_{i=2}^{l^w}frac{partial L(w,i)}{partial mathbf{x}_w}    , ar{w} in context(w)] 

    注意这里有 $ mathbf{x}_w = sum mathbf{v}(ar{w}) $ ,因为梯度的更新是对向量的和进行的,那么是否有必要对 $sum_{i=2}^{l^w}frac{partial L(w,i)}{partial mathbf{x}_w} $ 做平均,来使其分别贡献到求和前的各个词向量呢,其实不用,只用控制 $ eta  $ 的大小就可以了,这样就可以把  $sum_{i=2}^{l^w}frac{partial L(w,i)}{partial mathbf{x}_w} $ 贡献到 $ar{w} in context(w)$ 中每个词的词向量了。

    综上,当给定输入为 $w ,context(w)$ 时,给出 CBOW 的实现 word2vec 中主要部分的伪代码:

    egin{aligned}
      &e = 0 \
      &mathbf{x}_w = sum_{ar{w}  in context(w) } mathbf{v}(ar{w} ) \
      &for i=2 ightarrow l^w do: \
    & q = sigma( heta^{w T}_{i-1}mathbf{x}_w) \
    & g = eta (1-d_i^w-q)\
    & e := e+ g cdot heta^{w }_{i-1} \
    & heta^{w }_{i-1} := heta^{w}_{i-1} +g cdot mathbf{x}_w \
      &for ar{w}  in conetxt(w) : \
    & mathbf{v}(ar{w} ) := mathbf{v}(ar{w} ) +e
    end{aligned}

      需要注意3中最后两步顺序不能颠倒,即  $ heta_{j-1}^w$  先贡献到 $e$ 然后进行相应的更新,至此,CBOW  模型已全部推倒完成。接下来便是另一种基于  Hierarchical Softmax 的模型 Skip-gram 模型。

    2)Skip-gram Model

    Skip-gram  的任务是给出词 $w$ 来预测其前后各 $c$ 个词语 $context(w)$ ,其推倒与 CBOW 大同小异,网络结构也是大体相同,如下图:

    Input  Layer

      对于输入词语 $w$ ,转化为词向量的形式  $mathbf{v}(w) in mathbb{R}^m$ 当做输入

    Projection  Layer

      由于只有一个词向量 $mathbf{v}(w)$ ,投影层其实是多于的,只是为了和 CBOW 做对比

    Output  Layer

      同 CBOW 一样为 一颗 Huffman 树

     CBOW 的任务是给定 $context(w)$ 计算 $w$, 对应概率为 $p(w|context(w))$ ,而 Skip-gram 的任务是给定 $w$ ,来预测 $context(w)$ ,其对应的概率为 $p(w|context(w))$ , Skip-gram将 $p(w|context(w))$ 定义为如下的形式:

    [ p(context(w)|w) = prod p(w'|w)   , w' in context(w) ]

    类似于 CBOW 中 Hierarchical Softmax 的思想,每个 $w'$ 的概率可以表达为 $p(w'|w) = prod_{i=2}^{l^{w'}}p(d_i^{w'}|mathbf{v}(w), heta_{i-1}^{w'})$ ,其中:

    [p(d_i^{w'}|mathbf{v}(w), heta_{i-1}^{w'}) = left[ sigma( heta^{w' T}_{i-1}mathbf{v}(w))   ight]^{1-d_i^{w'}} cdot left[ 1-sigma( heta^{w' T}_{i-1}mathbf{v} (w))   ight]^{d_i^{w'}} ]

    接下来写出似然函数的具体形式:

    有了以上目标函数,接下来就可以进行进一步的对 $ heta^{w'} ,  mathbf{v}(w)$ 求导.

    同样,记 $L(w,w',i) =left { (1-d_i^{w'}) cdot log left [sigma ( heta^{w' T}_{i-1}mathbf{v}(w)) ight ] +d_i^{w'} cdot logleft [1-sigma ( heta^{w' T}_{i-1}mathbf{v}(w)) ight ] ight }$ ,接下来对 $L(w,w',i)$ 对参数分别进行求导:

    egin{aligned}
    frac{partial L(w,w',i)}{partial heta_{i-1}^{w'}}
    &= frac{partial}{partial heta_{i-1}^{w'}}left { (1-d_i^{w'}) cdot log left [sigma ( heta^{w' T}_{i-1}mathbf{v}(w)) ight ] +d_i^{w'} cdot logleft [1-sigma ( heta^{w' T}_{i-1}mathbf{v}(w)) ight ] ight } \
    &= (1-d_i^{w'}) cdot left [1- sigma ( heta^{w' T}_{i-1}mathbf{v}(w)) ight ] cdot mathbf{v}(w) +d_i^{w'} cdot left [1-sigma ( heta^{w' T}_{i-1}mathbf{v}(w)) ight ] cdot mathbf{v}(w) \
    &=left [ 1 -d_i^{w'}-sigma ( heta^{w' T}_{i-1} mathbf{v}(w)) ight ]cdot mathbf{v}(w) \
    end{aligned}

    根据对称性可得到 $mathbf{v}(w)$ 的导数:

    egin{aligned}
    frac{partial L(w,w',i)}{partialmathbf{v}(w)} =left [ 1 -d_i^{w'}-sigma ( heta^{w' T}_{i-1} mathbf{v}(w)) ight ]cdot heta^{w' T}_{i-1} \
    end{aligned}

    现在可以得到 $mathbf{v}(w)$ 与 $ heta^{w' T}_{i-1}$ 的更新公式分别为:

    egin{aligned}
    heta^{w'}_{i-1} &: = heta^{w'}_{i-1} + eta left[1-d_i^{w'} -sigma( heta^{w' T}_{i-1} mathbf{v}(w)) ight ] cdot mathbf{v}(w) \
    mathbf{v}(w) &: =cdot mathbf{v}(w) + eta sum_{w' in context(w)} sum_{i=2}^{l^{w'}}left[1-d_i^{w'}- sigma( heta^{w' T}_{i-1} mathbf{v}(w)) ight ] cdot heta^{w'}_{i-1}
    end{aligned}

    综上,当给定输入为 $w ,context(w)$ 时,给出 Skip-gram  主要部分的伪代码:

    egin{aligned}
    & e = 0 \
    & for w'in context(w) do: \
    & for i=2 ightarrow l^{w'} do: \
    & q = sigma( heta^{w' T}_{i-1}mathbf{v}(w)) \
    & g = eta (1-d_i^{w'}-q)\
    & e := e+ g cdot heta^{w'}_{i-1} \
    & heta^{w'}_{i-1} := heta^{w'}_{i-1} +g cdot mathbf{v}(w) \
    &mathbf{v}(w) := mathbf{v}(w) +e
    end{aligned}

    但 Skip-gram 的实现 word2vec 并不是等 $context(w)$ 中的所有词 $w'$ 处理完后才刷新 $ mathbf{v}(w) $ ,而是每处理一个词就刷新一次,即

    egin{aligned}
    & for w'in context(w) do: \
    & e = 0 \
    & for i=2 ightarrow l^{w'} do: \
    & q = sigma( heta^{w' T}_{i-1}mathbf{v}(w)) \
    & g = eta (1-d_i^{w'}-q)\
    & e := e+ g cdot heta^{w'}_{i-1} \
    & heta^{w'}_{i-1} := heta^{w'}_{i-1} +g cdot mathbf{v}(w) \
    & mathbf{v}(w) := mathbf{v}(w) +e
    end{aligned}

    至此,基于 Hierarchical Softmax 的两个模型 CBOW 与 Skip-gram 均介绍完成。接下来是更加快速的基于 Negative-Sampling 的模型。

    基于 Negative-Sampling 的模型

    基于 Hierarchical Softmax 两个模型采用的 Huffman 树结构虽然大大优化了 NNLM 中的 softmax 层,但仍属于比较复杂的结构,有咩有更简单的方法呢,Mikolov提出的一种基于 Negative Sampling 的模型,他可以用来进一步提高训练速度,并且可以改善词向量的质量

    1)CBOW 模型

    在 CBOW 中,任务是给定词语 $w$ 来预测期上下文 $context(w)$ ,因此对于给定的 $context(w)$ , $w$ 就是一个正样本,语料库中其他词就是负样本了,所谓的负采样就是说在语料库中采样得到一批负样本 $hat{w}_i$ 构造负样本集合 $ N(w) = left { hat{w}_i ight } eq phi $ ,合起来写作 $ Neg(w) = N(w) cup left{  w ight } $ ,则样本 $w' in Neg(w)$ 对应的正负标签可表示为:

    [L^w(w')=left{
    egin{aligned}
    1 , w' = w \
    0 , w' = hat{w} \
    end{aligned}
    ight.]

    现在通过集合 $Neg(w)$ 来构造合适的语言模型 $p(w,context(w))$ ,首先写出单个词语,我们希望最大化:[ prod_{w' in Neg(w)}p(w'|context(w))]

    其中:

    [p(w'|context(w))=left{
    egin{aligned}
    sigma(mathbf{x}_w^T heta^{w'}), & L^{w}(w') = 1 \
    1-sigma(mathbf{x}_w^T heta^{w'}), & L^{w}(w') = 0 \
    end{aligned}
    ight.]

    写到一起有:

    [p(w'|context(w))= left [sigma(mathbf{x}_w^T heta^{w'})   ight ] ^{L^w(w')} cdot left [1-sigma(mathbf{x}_w^T heta^{w'})   ight ] ^{1-L^w(w')}]

    这里 $mathbf{x}_w$ 仍为 $context(w)$ 中词向量的和, $ heta^{w'} inmathbb{R}^m$ 表示词语 $w'$ 对应的辅助向量,对于单个输入 $w$ ,现在就要最大化:

    [left[ sigma(mathbf{x}_w^T heta^{w})   ight ] prod_{hat{w}in N(w)}  left [1-sigma(mathbf{x}_w^T heta^{hat{w}})   ight ]  ]

    最大化上式等价于最大化 $w$ 为正类,而所有 $hat{w}$ 为负类的联合概率。即增大正样本概率的同时,降低负样本的概率,现在对于给定的语料库 $C$ ,似然函数可以写成:

    [L = prod_{w in C} prod_{w' in Neg(w)} p(w'|context(w))]

    现在根据似然函数来找到参数的极大值即可:

    egin{aligned}
    L &= prod_{w in C} prod_{w' in Neg(w)} p(w'|context(w)) \
    Rightarrow \
    logL &=log left [ prod_{w in C} prod_{w' in Neg(w)} p(w'|context(w)) ight ] \
    &= sum_{w in C} log prod_{w' in Neg(w)} p(w'|context(w)) \
    &=sum_{w in C} log prod_{w' in Neg(w)} left { left [sigma(mathbf{x}_w^T heta^{w'}) ight ] ^{L^w(w')} cdot left [1-sigma(mathbf{x}_w^T heta^{w'}) ight ] ^{1-L^w(w')} ight } \
    &=sum_{w in C} sum_{w' in Neg(w)} left { L^w(w') cdot logleft [sigma(mathbf{x}_w^T heta^{w'}) ight ] + left [1-L^w(w') ight ] cdot log left [1-sigma(mathbf{x}_w^T heta^{w'}) ight ] ight }
    end{aligned}

    同样通过梯度上升的方式求解,首先记:

    [L(w,w') = left { L^w(w') cdot logleft [sigma(mathbf{x}_w^T heta^{w'}) ight ] + left  [1-L^w(w') ight ] cdot log left[1-sigma(mathbf{x}_w^T heta^{w'}) ight ] ight }]

    首先看 $L(w,w')$ 对 $ heta^{w'}$ 的梯度:

    egin{aligned}
    frac{partial L(w,w') }{partial heta^{w'}} &=frac{partial }{partial heta^{w'}} left { L^w(w') cdot logleft [sigma(mathbf{x}_w^T heta^{w'}) ight ] + left [1-L^w(w') ight ] cdot log left[1-sigma(mathbf{x}_w^T heta^{w'}) ight ] ight } \
    &=L^w(w') cdot left [1-sigma(mathbf{x}_w^T heta^{w'}) ight ]mathbf{x}_w - left [1-L^w(w') ight ] cdot left[sigma(mathbf{x}_w^T heta^{w'}) ight ]mathbf{x}_w \
    &=left [ L^w(w') - sigma(mathbf{x}_w^T heta^{w'}) ight ]mathbf{x}_w
    end{aligned}

    同样,考虑 $mathbf{x}_w$ 与 $ heta^{w'}$ 的对称性,可得到 $L(w,w')$ 关于 $mathbf{x}_w$ 的导数:

    [frac{partial L(w,w') }{partial mathbf{x}_w} = left [ L^w(w') - sigma(mathbf{x}_w^T heta^{w'}) ight ] heta^{w'} ]

    因此当给定输入为 $w$ ,$context(w)$ ,对于 $ar{w} in context(w)$ 与 $ heta^{w'} , w' in Neg(w)$ ,分别给出$ heta^{w'} ,mathbf{v}(ar{w}) $ 的梯度更新公式:

    [ heta^{w'}  = heta^{w'}  + eta left [  L^{w}(w') - sigma(mathbf{x}_w^T heta^{w'}) ight ] mathbf{x}_w    mathbf{v}(ar{w})  = mathbf{v}(ar{w})  + eta sum_{w' in Neg(w)} frac{partial L(w,w') }{partial mathbf{x}_w}  ]

     综上给出 基于 Negative Sampling 的 CBOW 的梯度上升代码

    egin{aligned}
    &e = 0 \
    &mathbf{x}_w = sum_{ar{w} in context(w) } mathbf{v}(ar{w} ) \
    &for w' in Neg(w) do: \
    & q = sigma(mathbf{x}_w^T heta^{w'}) \
    & g = eta (L^w(w')-q)\
    & e := e+ g cdot heta^{w' } \
    & heta^{w'} := heta^{w'} +g cdot mathbf{x}_w \
    &for ar{w} in conetxt(w) : \
    & mathbf{v}(ar{w} ) := mathbf{v}(ar{w} ) +e
    end{aligned}

    至此,基于 Negative-Sampling 的CBOW 全部介绍完毕。

    2) Skip-gram 模型

     与 CBOW 任务相反,Skip-gram 的任务是给定 $w$ ,来预测 $context(w)$ ,这时我们要对每个 $ar{w} in context(w)$ ,来产生一个负采样集合 $N(ar{w})$ ,与 $left { ar{w} ight}$ 一起生成 $Neg(ar{w})$ ,可见对于每个样本  $ar{w}$  Skip-gram的任务是这样的

    [p(context(w)|w) = prod_{ar{w} in context(w)} p(ar{w}|w)]

    结合构造的负样本集,对每个 $hat{w}$ ,我们要最大化的联合概率是:

    [p(context(w)|w) = prod_{ar{w} in context(w)} p(ar w|w)prod_{w' in Neg(ar{w})}p(w'|ar w)]

    这里,如果对 $w'$ ,满足 $w' in Neg(ar w) $ 且 $w' = ar w$ ,(即 $w'$ 为负采样集合中的自身),则 $L^{w}(w') = 1$,否则 $L^{w}(w') = 0$ ,这即为人工指定的标签。 现在可以写出:

    [ p(w'|ar w)=egin{cases}
    &sigma(mathbf{v}(w)^T heta^{(w')}), L^{w}(w') = 1\ 
    &1-sigma(mathbf{v}(w)^T heta^{(w')}), L^{w}(w') = 0\ 
    end{cases} ]

    写到一起:

    [p(w'|ar w) = left [sigma(mathbf{v}(w)^T heta^{(w')})   ight ]^{L^w(w')}+left [1-sigma(mathbf{v}(w)^T heta^{(w')})   ight ]^{1-L^w(w')}]

    现在可以写出整个语料库的似然函数:

    egin{aligned}
    L &= prod_{w in C}p(context(w)|w) \
    &= prod_{w in C}prod_{ar w in context(w)}p(ar w|w) \
    &= prod_{w in C}prod_{ar w in context(w)}prod_{w' in Neg(ar w)}p(w'|ar w,w)\
    Rightarrow \
    logL&=sum_{w in C}logprod_{ar w in context(w)}prod_{w' in Neg(ar w)}left { left [sigma(mathbf{v}(w)^T heta^{w'}) ight ]^{L^w(w')}+left [1-sigma(mathbf{v}(w)^T heta^{w'}) ight ]^{1-L^w(w')} ight }\
    &=sum_{w in C}sum_{ar w in context(w)}sum_{w' in Neg(ar w)}left {L^w(w') cdot log left [sigma(mathbf{v}(w)^T heta^{w'}) ight ]+ left [1- L^w(w') ight ] cdot log left [1-sigma(mathbf{v}(w)^T heta^{w'}) ight ] ight }
    end{aligned}

     接下来对参数求导即可,另:

    [L(w,ar w, w') = L^w(w') cdot log left [sigma(mathbf{v}(w)^T heta^{w'}) ight ]+ left [1- L^w(w') ight ] cdot log left [1-sigma(mathbf{v}(w)^T heta^{w'}) ight ]]

    从而得到 $L(w,ar w ,w')$ 关于 $mathbf{v}(w)$ 与 $ heta^{w'}$ 的梯度:

     egin{aligned}
    frac{partial L(w,ar w, w')}{partial heta^{w'}} &= frac{partial }{partial heta^{w'}}L^w(w') cdot log left [sigma(mathbf{v}(w)^T heta^{w'}) ight ]+ left [1- L^w(w') ight ] cdot log left [1-sigma(mathbf{v}(w)^T heta^{w'}) ight ] \
    &=L^w(w') left [1-sigma(mathbf{v}(w)^T heta^{w'}) ight ]mathbf{v}(w)-left [1- L^w(w') ight ]sigma(mathbf{v}(w)^T heta^{w'})mathbf{v}(w) \
    &=left [L^w(w')- sigma(mathbf{v}(w)^T heta^{w'}) ight ]mathbf{v}(w)
    end{aligned}

    根据对称性:

    [frac{partial L(w,ar w, w')}{partial mathbf{v}(w) } = left [L^w(w')- sigma(mathbf{v}(w)^T heta^{w'}) ight ] heta^{w'}]

    接下来可以写出随机坐标上升法的参数更新公式:

    [ heta^{w'} := heta^{w'} + eta left [L^w(w')- sigma(mathbf{v}(w)^T heta^{w'}) ight ]mathbf{v}(w)]

    [mathbf{v}(w) := mathbf{v}(w) + eta sum_{ ar w in context(w)} sum_{w' in Neg(ar w)} left [L^w(w')- sigma(mathbf{v}(w)^T heta^{w'}) ight ] heta^{w'}]

    这里给出基于 Negative-Sampling 的 Skip-gram 的随机梯度上升的伪代码:

    egin{aligned} 
    for ar w & in context(w) do:\
    &e = 0 \
    &for w' in Neg(ar w) do: \
    & q = sigma(mathbf{v}(w)^T heta^{w'}) \
    & g = eta (L^w(w')-q)\
    & e := e+ g cdot heta^{w' } \
    & heta^{w'} := heta^{w'} +g cdot mathbf{v}(w) \
    &mathbf{v}(w ) := mathbf{v}(w ) +e
    end{aligned}

     注意,这里并不是等所有  $ar{w}$ 处理完后更新 $mathbf{v}(w )$ ,而是处理一个 $ar{w}$ 更新一次,同层次 softmax 的处理方式。

     3)Negative-Sampling方法

    以上两小节只是给出基于负采样的训练算法,这里承接上文,对给定的词语 $w$ , 给出负样本集 $Neg(w)$ 的选取方法,负样本选取遵循的规律是频率高则被选择的概率较大,反之较小,对于词典 $V$ ,每个词语的权重可以表示为:

    [p(w) = frac{count(w)}{sum_{w' in V}count(w')}]

    $count(w)$表示词语 $w$ 在语料库 $C$ 的计数,类似于 $LDA$ 中的 $Gibbs Sampling$,将 $p(w)$ 累加起来,即

    egin{aligned}
    for &i = 1 ightarrow |V|-1 do: \
    &p[i] :=p[i] +p[i-1]
    end{aligned}

    如果按照 $u sim (0-p[|V|-1])$ 来生成一个随机数,看随机数落在哪个区间 $(p[k] sim p[k+1])$,进而选取词语 $k$ ,这种做法无疑会大大增加时间复杂度,所以,可以对数组 $p$ 建立索引,即建立长度为 $M$ 的数组 $m$ ,使 $M >> |V| -1$ ,这样每个每个 $m[i] , i in (1,M-1) $会对应一个 $p[k]$ ,每次生成一个 $1 sim M$ 的随机数 $n$,采样结果为: $m[n] = p[k]$ 即可,原本已线性时间采样,现在变成了$O(1)$ ,具体可以看下图:

    如果采样到自身,直接跳过即可, Google 的 word2vec 实现采取 $M =10^8$ ,且 p 的计算如下:

    [p(w) = frac{count(w)^{frac{3}{4}}}{sum_{w' in V}count(w')^{frac{3}{4}}} ] 

    至此, word2vec 已经全部介绍完毕,有机会再继续深入,现在一些 paper 的工作集中在词向量的可解释性与词向量的本质,好像说与 LSA 的 SVD 矩阵分解是等价的,具体到时候再看。

    参考:

    [1] Bengio Y, Schwenk H, Senécal J S, et al. A neural probabilistic language model[J]. Journal of Machine Learning Research, 2003, 3(6):1137-1155.

    [2] Mikolov T, Chen K, Corrado G, et al. Efficient Estimation of Word Representations in Vector Space[J]. Computer Science, 2013.

    [3] Mikolov T, Sutskever I, Chen K, et al. Distributed Representations of Words and Phrases and their Compositionality[J]. Advances in Neural Information Processing Systems, 2013, 26:3111-3119.

    [4]word2vec中的数学

  • 相关阅读:
    MD5中使用16进制
    关于mysql函数GROUP_CONCAT
    一个不错的源码网站
    查看jdk 线程 日志
    list 的sublist 隐藏 bug
    web 环境项目(intellj部署的tomcat) 重启时报 Exception in thread "HouseKeeper" java.lang.NullPointerException
    怎么给已有项目引入别的项目
    javascript 和 CoffeeScript 里的类
    express 与 mvc
    express的路由
  • 原文地址:https://www.cnblogs.com/ooon/p/5558119.html
Copyright © 2020-2023  润新知