2.1-RNN-概率和语言模型

1语言模型的概念

  1. 语言模型使用概率来评估一个单词序列发生的可能性,即在多大程度上是自然的单词序列

    1. 例如在语音识别中,系统会根据人的发言生成多个句子作为候选;此时,使用语言模型,可以按照“作为句子是否自然”这一基准对候选句子进行排序;即按照每个句子是自然的句子的概率来排序;
  2. 用后验概率来表示一个句子(语言模型):

    1. 考虑由 m m m个单词 w 1 , ⋅ ⋅ ⋅ , w m w_1, · · · ,w_m w1,⋅⋅⋅,wm构成的句子,将单词按 w 1 , ⋅ ⋅ ⋅ , w m w_1, · · · ,w_m w1,⋅⋅⋅,wm的顺序出现的概率记为 P ( w 1 , ⋅ ⋅ ⋅ , w m ) P(w_1, · · · ,w_m) P(w1,⋅⋅⋅,wm)​;因为这个概率是多个事件一起发生的概率,所以称为联合概率

    2. 根据概率的知识,两个事件同时发生的概率可以用条件概率来表示,如下式所示;至于谁是谁的条件都可以,这里并没有明确的先后顺序;
      P ( A , B ) = P ( A ∣ B ) P ( B ) (1) P(A,B)=P(A|B)P(B) \tag{1} P(A,B)=P(AB)P(B)(1)
      A A A B B B两个事件共同发生的概率 P ( A , B ) P(A,B) P(A,B) B B B发生的概率 P ( B ) P(B) P(B) B B B发生后 A A A发生的概率 P ( A ∣ B ) P(A|B) P(AB)​的乘积。

    3. 基于这个概率公式,我们可以对上面的联合概率 P ( w 1 , ⋅ ⋅ ⋅ , w m ) P(w_1, · · · ,w_m) P(w1,⋅⋅⋅,wm)​进行分解,分解过程如下:

      1. 首先,令 A = w 1 , ⋅ ⋅ ⋅ w m − 1 A=w_1, · · · w_{m-1} A=w1,⋅⋅⋅wm1,则有:
        P ( w 1 , ⋅ ⋅ ⋅ , w m ) = P ( A , w m ) = P ( w m ∣ A ) P ( A ) (2) P(w_1, · · · ,w_m)=P(A,w_m)=P(w_m|A)P(A) \tag{2} P(w1,⋅⋅⋅,wm)=P(A,wm)=P(wmA)P(A)(2)

      2. 类似地,令 A ′ = w 1 , ⋅ ⋅ ⋅ w m − 2 A^{'}=w_1, · · · w_{m-2} A=w1,⋅⋅⋅wm2,则有:
        P ( A ) = P ( A ′ , w m − 1 ) = P ( w m − 1 ∣ A ′ ) P ( A ′ ) (3) P(A)=P(A^{'},w_{m-1})=P(w_{m-1}|A^{'})P(A^{'}) \tag{3} P(A)=P(A,wm1)=P(wm1A)P(A)(3)

      3. 以此类推,我们最终可以将联合概率分解为:
        P ( w 1 , ⋅ ⋅ ⋅ , w m ) = P ( w m ∣ w 1 , ⋯   , w m − 1 ) P ( w m − 1 ∣ w 1 , ⋯   , w m − 2 ) . . . P ( w 3 ∣ w 1 , w 2 ) P ( w 2 ∣ w 1 ) P ( w 1 ) = ∏ t = 1 m P ( w t ∣ w 1 , ⋯   , w t − 1 ) (4) \begin{aligned} P(w_1, · · · ,w_m)&=P(w_m|w_1,\cdots,w_{m-1})P(w_{m-1}|w_1,\cdots,w_{m-2})...P(w_3 | w_1,w_2)P(w_2 | w_1)P(w_1)\\ &=\prod_{t=1}^mP(w_t|w_1,\cdots,w_{t-1}) \end{aligned} \tag{4} P(w1,⋅⋅⋅,wm)=P(wmw1,,wm1)P(wm1w1,,wm2)...P(w3w1,w2)P(w2w1)P(w1)=t=1mP(wtw1,,wt1)(4)
        即联合概率可以表示为后验概率的乘积。放到句子中就是:以目标词左侧的全部单词为上下文(条件)的后验概率表示到目标词为止的句子的概率。也就是说,要求语言模型的联合概率 P ( w 1 , ⋅ ⋅ ⋅ , w m ) P(w_1, · · · ,w_m) P(w1,⋅⋅⋅,wm),只需要求式(4)中的 P ( w t ∣ w 1 , ⋯   , w t − 1 ) P(w_t|w_1,\cdots,w_{t-1}) P(wtw1,,wt1)

2概率视角下的word2vec

以CBOW模型为例。

  1. CBOW模型是用目标词左右的上下文单词来预测中间的词;在1.6自然语言的分布式表示-word2vec补充说明.md中我们说过,CBOW可以用概率建模为 P ( w t ∣ w t − 1 , w t + 1 ) P(w_t|w_{t-1},w_{t+1}) P(wtwt1,wt+1);并结合交叉熵损失函数进一步转换为 L = − log ⁡ P ( w t ∣ w t − 1 , w t + 1 ) L=-\log P(w_t|w_{t-1},w_{t+1}) L=logP(wtwt1,wt+1)
  2. 如果只考虑目标词左侧的窗口,窗口大小设置为2;即考虑目标词左侧的2个单词;则CBOW可以用概率建模为 P ( w t ∣ w t − 2 , w t − 1 ) P(w_t|w_{t-2},w_{t-1}) P(wtwt2,wt1)

3能否将word2vec用作语言模型

  1. 概括
    1. word2vec 是以获取单词的分布式表示为目的的方法,因此一般不会用于语言模型
    2. 基于 RNN 的语言模型虽然也能获得单词的分布式表示,但是为了应对词汇量的增加、提高分布式表示的质量,word2vec 被提了出来。
  1. 语言模型的联合概率 P ( w 1 , ⋅ ⋅ ⋅ , w m ) P(w_1, · · · ,w_m) P(w1,⋅⋅⋅,wm)是需要求句子中每个单词的 P ( w t ∣ w 1 , ⋯   , w t − 1 ) P(w_t|w_1,\cdots,w_{t-1}) P(wtw1,,wt1),然后相乘;我们如果在CBOW模型中限定只考虑目标词左侧的窗口,窗口大小设置为2,那么语言模型的联合概率 P ( w 1 , ⋅ ⋅ ⋅ , w m ) P(w_1, · · · ,w_m) P(w1,⋅⋅⋅,wm)可以近似表示为下式:
    P ( w 1 , ⋅ ⋅ ⋅ , w m ) = ∏ t = 1 m P ( w t ∣ w 1 , ⋯   , w t − 1 ) ≈ ∏ t = 1 m P ( w t ∣ w t − 2 , w t − 1 ) (5) P(w_1, · · · ,w_m)=\prod_{t=1}^mP(w_t|w_1,\cdots,w_{t-1})\approx\prod_{t=1}^mP(w_t|w_{t-2},w_{t-1}) \tag{5} P(w1,⋅⋅⋅,wm)=t=1mP(wtw1,,wt1)t=1mP(wtwt2,wt1)(5)

  2. 由于这个上下文窗口大小是可以设置的,因此我们可以将其扩大,这样可以考虑足够长的上文单词;

  3. 但是需要注意的是,虽然上下文窗口大小是可以设置的,但是必须是固定的,因为CBOW模型的结构中,我们需要根据上下文窗口大小去生成相应数量的输入层;

  4. 那么,既然是固定的,就可能存在一个很长的句子,我们的上下文窗口没法完全覆盖,那就存在信息的丢失;下图是书上的一个例子:

    在这里插入图片描述

  5. 另外,对于word2vec模型,没有去考虑单词的顺序;例如在CBOW模型中,我们是直接将多个输入层的输出结果相加再求平均的,是没有顺序的;当然,针对这个问题也有相关的改进,比如在中间层拼接上下文的单词向量,这虽然能够将顺序的信息加入,但是当上下文单词很多时,权重参数的数量将与上下文大小成比例地增加,如下图所示:

    在这里插入图片描述

  6. 因此,word2vec模型不适合来表示语言模型;

4 RNN

Recurrent Neural Network 通常译为“循环神经网络”。另外, 还有一种被称为 Recursive Neural Network(递归神经网络)的网络。这个网络主要用于处理树结构的数据,和循环神经网络不是一个东西

4.1 RNN层的简单结构

  1. 循环神经网络得有循环吧;那这个循环直观体现在RNN层的结构上;

  2. RNN层的结构如下图所示:

    1. 时序数据 ( x 0 , x 1 , ⋯   , x t , ⋯   ) (\boldsymbol{x}_0,\boldsymbol{x}_1,\cdots,\boldsymbol{x}_t,\cdots) (x0,x1,,xt,)会被输入到RNN层中;时刻 t t t的输入是 x t \boldsymbol{x}_t xt,得到输出 h t \boldsymbol{h}_t ht;整个时序数据的输出就是 ( h 0 , h 1 , ⋯   , h t , ⋯   ) (\boldsymbol{h}_0,\boldsymbol{h}_1,\cdots,\boldsymbol{h}_t,\cdots) (h0,h1,,ht,)​;
    2. 在各个时刻输入的 x t \boldsymbol{x}_t xt都是向量;对应到句子里面,每个时刻输入的就是某个单词的向量表示;
    3. 下图中输出侧有分支,说明RNN层的输出被**复制**了,一个进入到后面的层, 一个又指向了自己;
    4. 通过这个指向自己的分支,形成循环;通过数据的循环,RNN 一边记住过去的数据,一边更新到最新的数据

    在这里插入图片描述

  3. 为了能够展示RNN层记住过去信息的特点,需要将上图旋转为下图的样子:

    在这里插入图片描述

4.2 RNN层的循环结构

  1. RNN的循环结构如下图所示:

    1. 在循环结构中我们可以引入时刻的概念:时刻 t t t的输入数据为 x t \boldsymbol{x}_t xt;在自然语言处理的情况下, x t \boldsymbol{x}_t xt就是第 t t t个单词或者第 t t t个RNN层,也可以说时刻 t t t的单词或时刻 t t t的RNN层;
    2. 各个时刻的 RNN 层接收传给该层的输入 x t \boldsymbol{x}_t xt和前一个 RNN 层的输出 h t − 1 \boldsymbol{h}_{t-1} ht1
    3. 这样的从左向右延伸的长神经网络,和我们之前看到的前馈神经网络的结构相同;但是需要注意的是,这里虽然展开成多个RNN层,但实际上都是一个层,换句话说,梯度反向传播时,更新的参数只有一组,而不是每个层都有自己的一组参数

    在这里插入图片描述

  2. 单独看一下其中一个RNN层:根据输入和上一个时刻的输出,通过式(6)计算当前时刻的输出:

    1. 式中的 W h \boldsymbol{W}_h Wh W x \boldsymbol{W}_x Wx是两个权重矩阵, b \boldsymbol{b} b是偏置;
    2. 对于自然语言处理而言,当前时刻的 x t \boldsymbol{x}_t xt是一个单词的单词向量,即一个行向量; W x \boldsymbol{W}_x Wx作用于当前时刻输入, W h \boldsymbol{W}_h Wh作用于上一时刻的隐藏状态 h t − 1 \boldsymbol{h}_{t-1} ht1,加上偏置后计算双曲正切,得到当前RNN层的输出 h t \boldsymbol{h}_{t} ht​;
    3. 这个 h t \boldsymbol{h}_{t} ht一方面向上输出到另一个层,另一方面向右输出到下一个 RNN 层(自身)。
    4. 设输入的单词向量的维数是 D D D,隐藏状态向量的维数是 H H H W x \boldsymbol{W}_x Wx将输入变换到隐藏状态空间的维度,因此 W x ∈ R D × H \boldsymbol{W}_x\in R^{D\times H} WxRD×H;通过公式可以知道 h t \boldsymbol{h}_{t} ht x t W x \boldsymbol{x}_t\boldsymbol{W}_x xtWx的维度应该是一样的,即 h t ∈ R 1 × H \boldsymbol{h}_t\in R^{1\times H} htR1×H;如此一来,可以推出其他各个量的形状;
    5. 整个公式的形状变化如式(7)所示;

    h t = tanh ⁡ ( h t − 1 W h + x t W x + b ) (6) \boldsymbol{h}_t=\tanh(\boldsymbol{h}_{t-1}\boldsymbol{W}_h+\boldsymbol{x}_t\boldsymbol{W}_x+\boldsymbol{b}) \tag{6} ht=tanh(ht1Wh+xtWx+b)(6)

    ( 1 , H ) = t a n h ( ( 1 , H ) ⋅ ( H , H ) + ( 1 , D ) ⋅ ( D , H ) + ( 1 , H ) ) (7) (1,H)=tanh((1,H)\cdot(H,H)+(1,D)\cdot(D,H)+(1,H)) \tag{7} (1,H)=tanh((1,H)(H,H)+(1,D)(D,H)+(1,H))(7)

  3. 经过上面的介绍可以看出,现在的输出 h t \boldsymbol{h}_{t} ht是由前一个输出 h t − 1 \boldsymbol{h}_{t-1} ht1计算出来的;也就是说,RNN具有“状态” h \boldsymbol{h} h,并通过式(6)不断被更新,那么之后的 h t \boldsymbol{h}_{t} ht就具有了之前所有隐藏状态 h \boldsymbol{h} h的信息;这就是说RNN层是“具有状态的层”或“具有存储(记忆)的层”的原因。

4.3 RNN的反向传播

  1. 从RNN的结构来看,RNN除了像普通神经网络那样具有纵向的前向计算外,还在水平方向上有一个正向传播计算;但是都是可以遵循计算图的;

  2. 由于水平方向上是按时间顺序展开计算的,即**按时间顺序展开的神经网络的误差反向传播法,因此称为基于时间的反向传播,Backpropagation Through Time,简称BPTT**。

  3. 如下图所示是RNN在水平方向上反向传播的示意图:

    在这里插入图片描述

4.4 Truncated BPTT

意思为被截断的BPTT。

当水平方向上的循环过长时,在反向传播时,需要保留的正向计算时的中间数据就越多,消耗的资源就越多,因此不能对整个时间序列来求梯度,需要进行截断;而且长度过长,梯度反向传播时可能也存在梯度消失等问题;

  1. Truncated BPTT是什么:

    1. 将时间轴方向上过长的网络在合适的位置进行截断,从而创建多个小型网络,然后对截出来的小型网络执行误差反向传播法;
    2. 如下图所示,我们每10个单词进行一次截断;
    3. 像这样,只要将反向传播的连接截断,就不需要再考虑块范围以外的数据了,因此可以以各个块为单位(和其他块没有关联)完成误差反向传播法。

    在这里插入图片描述

  2. 反向传播被分成好多个部分,但是**正向传播是没有被截断的**;即上图中 h 9 \boldsymbol{h}_{9} h9依然会进入到下一个RNN层与 x 10 \boldsymbol{x}_{10} x10一起得到 h 10 \boldsymbol{h}_{10} h10

4.5 Truncated BPTT的mini-batch学习

4.5.1不考虑mini-batch

  1. 目前来说,我们可以先总结如下:
    1. RNN中,一个batch里面每条数据都是一个句子;每个batch输入每个句子的某个块的数据;下一个batch再输入这些句子下一个块的数据。
    2. 每个batch中,都使用每条句子的当前块的数据进行正向传播,然后反向传播计算梯度;
    3. 一般的神经网络是:一个batch就是把多个句子的全部数据输入进去;下一个batch就是另外一些句子了;
  1. 在之前的word2vec的网络结构中,一个句子可以形成多个<上下文单词,目标词>对,我们将其输入到神经网络层中,计算中间结果;例如CBOW模型,我们可以用一个mini-batch将多个<上下文单词,目标词>对送入网络,但我们不需要去考虑每个<上下文单词,目标词>对谁在前,谁在后;

  2. 但是RNN网络中,使用Truncated BPTT来进行模型学习时,根据截断的大小,一个句子会被相应的分成几块;那么这个句子的几个块需要按顺序输入到网络中,比如:

    1. 先输入第一个块的数据 ( x 0 , x 1 , . . . , x 9 ) (\boldsymbol{x}_0,\boldsymbol{x}_1,...,\boldsymbol{x}_9) (x0,x1,...,x9),进行正向传播和反向传播,如下图所示:

      在这里插入图片描述

    2. 然后输入下一个块的数据 ( x 10 , x 11 , . . . , x 19 ) (\boldsymbol{x}_{10},\boldsymbol{x}_{11},...,\boldsymbol{x}_{19}) (x10,x11,...,x19),此时正向传播的计算需要前一个块最后的隐藏状态 h 9 \boldsymbol{h}_{9} h9;即正向传播是连续没有截断的;然后反向传播的时候依然是在这个块内进行,不接收前面的块的梯度,也不将梯度传递到下一个块;如下图所示:

      在这里插入图片描述

    3. 依此类推,这个过程的学习顺序就是下图的样子:

      1. 每次都是一个块的数据进行前向计算,以及反向传播;
      2. 然后再来一个块的数据;
      3. 重复上述过程;
      4. 由此可知,RNN中的块是复用的,即每一组数据都按顺序输入到同一个块中;

      在这里插入图片描述

4.5.2考虑mini-batch

示例为:对长度为1000的时序数据,以时间长度10为单位进行截断。此时, 如何将批大小设为 2 进行学习呢

  1. 由于批处理大小为2,因此相当于一个批次可以同时处理两个句子对应的一个块的数据;因此我们可以把长度为1000的时序数据分成两个“句子”,每个“句子”的长度为500

  2. 时间长度为10,因此第一个batch我们只能处理 ( x 0 , x 1 , . . . , x 9 ) (\boldsymbol{x}_0,\boldsymbol{x}_1,...,\boldsymbol{x}_9) (x0,x1,...,x9) ( x 500 , x 501 , . . . , x 509 ) (\boldsymbol{x}_{500},\boldsymbol{x}_{501},...,\boldsymbol{x}_{509}) (x500,x501,...,x509),然后第二个batch处理处理 ( x 10 , x 11 , . . . , x 19 ) (\boldsymbol{x}_{10},\boldsymbol{x}_{11},...,\boldsymbol{x}_{19}) (x10,x11,...,x19) ( x 510 , x 511 , . . . , x 519 ) (\boldsymbol{x}_{510},\boldsymbol{x}_{511},...,\boldsymbol{x}_{519}) (x510,x511,...,x519)​;如下图所示;以此类推;

    在这里插入图片描述

  • 16
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值