循环神经网络模型

本文深入探讨了序列模型和语言模型的概念,强调了马尔科夫假设在建模中的应用。接着,详细介绍了循环神经网络(RNN)在语言模型中的运用,解释了困惑度和梯度裁剪的重要性。此外,还对比了门控循环单元(GRU)和长短期记忆网络(LSTM)在处理序列信息时的不同之处,强调了它们在记忆管理和信息选择上的机制。
摘要由CSDN通过智能技术生成

循环神经网络




提示:以下是本篇文章正文内容,下面案例可供参考

一、序列模型

统计工具

  1. 在时间 t t t观察到 x t x_t xt,那么得到 T T T个不独立的随机变量 ( x 1 , x 2 , . . . , x T ) ∽ p ( X ) (x_1,x_2,...,x_T) \backsim p(\bf{X}) (x1,x2,...,xT)p(X)
  2. 使用条件概率展开 p ( a , b ) = p ( a ) p ( b ∣ a ) = p ( b ) p ( a ∣ b ) p(a,b)=p(a)p(b|a)=p(b)p(a|b) p(a,b)=p(a)p(ba)=p(b)p(ab)
    推广到 T T T个随机变量有
    p ( X ) = p(\bf{X})= p(X)= p ( x 1 ) ⋅ p ( x 2 ∣ x 1 ) ⋅ p ( x 3 ∣ x 1 , x 2 ) ⋅ . . . p ( x T ∣ x 1 , . . . x T − 1 ) p(x_1)\cdot p(x_2|x_1)\cdot p(x_3|x_1,x_2)\cdot ...p(x_T|x_1,...x_{T-1}) p(x1)p(x2x1)p(x3x1,x2)...p(xTx1,...xT1)
    在这里插入图片描述
    或者反过来
    p ( X ) = p(\bf{X})= p(X)= p ( x T ) ⋅ p ( x T − 1 ∣ x T ) ⋅ p ( x T − 2 ∣ x T , x T − 1 ) ⋅ . . . p ( x T ∣ x 2 , . . . x T ) p(x_T)\cdot p(x_{T-1}|x_T)\cdot p(x_{T-2}|x_T,x_{T-1})\cdot ...p(x_T|x_2,...x_T) p(xT)p(xT1xT)p(xT2xT,xT1)...p(xTx2,...xT)
    在这里插入图片描述
    反序的意义,例如知道未来的事情退过去的事情,物理上不一定可行是指如果未来的事情依赖于过去的事情而产生,那么就没法反推(这一点我还没有理解,既然未来的事情是作为已知条件,过去有和未来有联系,怎么就无法反推出过去的事情呢?)
  3. 对条件概率建模
    p ( x T ∣ x 1 , . . . x t − 1 ) = p ( x t ∣ h ( x 1 , . . . , x t − 1 ) ) p(x_T|x_1,...x_{t-1}) = p(x_t|h(x_1,...,x_{t-1})) p(xTx1,...xt1)=p(xth(x1,...,xt1))
    给定 t − 1 t-1 t1个数据,求第 t t t个数据,假设用前 t − 1 t-1 t1个数据建立一个函数 h h h, h h h就是一个模型,通过 h t − 1 h_{t-1} ht1 h t h_t ht。通过对前面的数据建模,预测后一个数据,称为自回归模型,核心是求 h h h
  4. 如何求解 f f f
    方案A-马尔科夫假设
    假设当前数据只跟 τ \tau τ个过去数据点相关
    P ( x T ∣ x 1 , . . . x t − 1 ) = P ( x T ∣ x t − τ , . . . x t − 1 ) = P ( x t ∣ h ( x t − τ , . . . , x t − 1 ) ) P(x_T|x_1,...x_{t-1}) =P(x_T|x_{t-\tau},...x_{t-1})= P(x_t|h(x_{t-\tau},...,x_{t-1})) P(xTx1,...xt1)=P(xTxtτ,...xt1)=P(xth(xtτ,...,xt1))
    方案B-潜变量模型
    引入潜变量 h t h_t ht来表示过去的信息 h t = g ( h t − 1 , x t − 1 ) h_t=g(h_{t-1},x_{t-1}) ht=g(ht1,xt1)
    这样 x t ^ = P ( x t ∣ h t , x t − 1 ) \hat{x_t}=P(x_t|h_t,x_{t-1}) xt^=P(xtht,xt1)
    在这里插入图片描述

二、语言模型

1.语言模型简介

  • 给定文本序列 x 1 , . . . , x T x_1,...,x_T x1,...,xT, 语言模型的目标是估计联合概率 p ( x 1 , . . . x T ) p(x_1,...x_T) p(x1,...xT)
  • 它的作用包括:做预训练模型(egBERT,GPT-3);生成文本,给定前面几个词,不断的使用 x t ∽ p ( x t ∣ x 1 , . . . , x t − 1 ) x_t \backsim p(x_t|x_1,...,x_{t-1}) xtp(xtx1,...,xt1) ; 判断多个序列中那个更常见,e.g “to recognize speech” vs “to wreck a nice beach”

2.使用计数来建模

  • 假设序列长度为2,我们预测 p ( x , x ′ ) = p ( x ) p ( x ′ ∣ x ) = n ( x ) n n ( x , x ′ ) n ( x ) p(x, x^\prime) = p(x)p(x^\prime|x) = \frac{n(x)}{n}\frac{n(x,x^\prime)}{n(x)} p(x,x)=p(x)p(xx)=nn(x)n(x)n(x,x)
  • 这里n是总词数, n ( x ) , n ( x , x ′ ) n(x),n(x,x^\prime) n(x),n(x,x)是单个单词和连续单词对的出现次数
  • 很容易扩展到3的情况 p ( x , x ′ , x ′ ′ ) = p ( x ) p ( x ′ ∣ x ) p ( ′ ′ ∣ x , x ′ ) = n ( x ) n n ( x , x ′ ) n ( x ) n ( x , x ′ , x ′ ′ ) n ( x , x ′ ) p(x, x^\prime,x^{\prime\prime}) = p(x)p(x^\prime|x)p(^{\prime\prime}|x,x^\prime)=\frac{n(x)}{n}\frac{n(x,x^\prime)}{n(x)}\frac{n(x,x^\prime,x^{\prime\prime})}{n(x,x^\prime)} p(x,x,x)=p(x)p(xx)p(x,x)=nn(x)n(x)n(x,x)n(x,x)n(x,x,x)
  • 注意,这里的序列 ( x , x ′ ) (x_,x^{\prime}) (x,x)是一个有序的元组

2.N元语法

  • 当序列很长时,因为文本量不够大,很可能 n ( x 1 , . . . x T ) ≤ 1 n(x_1,...x_T)\le1 n(x1,...xT)1
  • 使用马尔科夫假设可以缓解这个问题
  • 一元语法 p ( x 1 , x 2 , x 3 , x 4 ) = p ( x 1 ) p ( x 2 ) p ( x 3 ) p ( x 4 ) = n ( x 1 ) n n ( x 2 ) n n ( x 3 ) n n ( x 4 ) n p(x_1,x_2,x_3,x_4) = p(x_1)p(x_2)p(x_3)p(x_4)=\frac{n(x_1)}{n}\frac{n(x_2)}{n}\frac{n(x_3)}{n}\frac{n(x_4)}{n} p(x1,x2,x3,x4)=p(x1)p(x2)p(x3)p(x4)=nn(x1)nn(x2)nn(x3)nn(x4)
  • 二元语法 p ( x 1 , x 2 , x 3 , x 4 ) = p ( x 1 ) p ( x 2 ∣ x 1 ) p ( x 3 ∣ x 2 ) p ( x 4 ∣ x 3 ) = n ( x 1 ) n n ( x 1 , x 2 ) n ( x 1 ) n ( x 2 , x 3 ) n ( x 2 ) n ( x 3 , x 4 ) n ( x 3 ) p(x_1,x_2,x_3,x_4) = p(x_1)p(x_2|x_1)p(x_3|x_2)p(x_4|x_3)=\frac{n(x_1)}{n}\frac{n(x_1,x_2)}{n(x_1)}\frac{n(x_2,x_3)}{n(x_2)}\frac{n(x_3,x_4)}{n(x_3)} p(x1,x2,x3,x4)=p(x1)p(x2x1)p(x3x2)p(x4x3)=nn(x1)n(x1)n(x1,x2)n(x2)n(x2,x3)n(x3)n(x3,x4)
  • 三元语法 p ( x 1 , x 2 , x 3 , x 4 ) = p ( x 1 ) p ( x 2 ∣ x 1 ) p ( x 3 ∣ x 1 , x 2 ) p ( x 4 ∣ x 2 , x 3 ) = n ( x 1 ) n n ( x 1 , x 2 ) n ( x 1 ) n ( x 1 , x 2 , x 3 ) n ( x 1 , x 2 ) n ( x 2 , x 3 , x 4 ) n ( x 2 , x 3 p(x_1,x_2,x_3,x_4) = p(x_1)p(x_2|x_1)p(x_3|x_1,x_2)p(x_4|x_2,x_3)=\frac{n(x_1)}{n}\frac{n(x_1,x_2)}{n(x_1)}\frac{n(x_1,x_2,x_3)}{n(x_1,x_2)}\frac{n(x_2,x_3,x_4)}{n(x_2,x_3} p(x1,x2,x3,x4)=p(x1)p(x2x1)p(x3x1,x2)p(x4x2,x3)=nn(x1)n(x1)n(x1,x2)n(x1,x2)n(x1,x2,x3)n(x2,x3n(x2,x3,x4)

三、RNN模型

使用循环神经网络的语言模型

在这里插入图片描述
训练的过程是输入‘你’ 预测 ‘好’,输入‘好’预测 ‘,’,以此类推,然后通过输出与观察值做损失函数来学习权重

循环神经网络

在这里插入图片描述

困惑度(perplexity)

  • 衡量一个语言模型的好坏可以用平均交叉熵

π = 1 t ∑ i = 1 t − l o g p ( x t ∣ x t − 1 ) \pi=\frac{1}{t}\sum_{i=1}^{t}-logp(x_t|x_{t-1}) π=t1i=1tlogp(xtxt1)

  • p p p是语言模型的预测概率, x t x_{t} xt是真实词
  • 历史原因NLP使用困惑度 e x p ( π ) exp(\pi) exp(π)来衡量,1表示完美,无穷大是最差情况

梯度裁剪

  • 迭代 中计算这 T T T个时间步上的梯度,在反向传播过程中产生长度为 O ( T ) O(T) O(T)的矩阵乘法链,导致数值不稳定
  • 梯度裁剪能有效预防梯度爆炸
  • 如果梯度长度超过 θ \theta θ,那么把梯度长度拖回长度 θ \theta θ
    g ⟵ m i n ( 1 , θ ∥ g ∥ ) g g \longleftarrow min(1,\frac{\theta}{\lVert g\rVert})g gmin(1,gθ)g

上面的过程如何在代码上实现?

模型的输入是什么?
假设我们现在有一个训练的数据集“The Time Machine”这篇小说,我们取其中连续的10000个词元(这里一个词元代表一个英文字符)作为训练的数据集,我们先进行文本处理(NLP)

batch_size, num_steps = 32, 35 
train_iter, vocab = d2l.load_data_time_machine(batch_size, num_steps)

其中num_steps 就是上文中的 T T T也就是循环神经网络图中绿色圆圈的个数
得到一个词汇表vocab如下

['<unk>', ' ', 'e', 't', 'a', 'i', 'n', 'o', 's', 'h', 'r', 'd', 'l', 'm', 'u', 'c', 'f', 'w', 'g', 'y', 'p', 'b', 'v', 'k', 'x', 'z', 'j', 'q']

vocab是一个28维的向量,26个英文字母加上一个空格和用来表示其他符号的 ‘< unk >’ 。

很多读者可能不理解batch_size和num_steps。我们下面用一个简单的例子来理解
假设我们有一个用于训练的序列,如果我们每次只输入一个字符,那么是非常浪费时间的,如何能高效的使用训练数据呢?
我们定义num_steps = 5,那么就按照5这个长度将这个序列划分为下面的5块,然后我么将这5块装进一个盒子里。现在我们定义batch_size = 2,那么我就每次从盒子中取两块放在一起,你可以按顺序取,也可以随机取。
在这里插入图片描述
假设我们随机取得“the t”,“e by ”这两块,那么我们就得到了一个2X5的矩阵 X X X
X = [ ‘ t ’ ‘ h ’ ‘ e ’ ‘    ’ ‘ t ’ ‘ e ’ ‘    ’ ‘ b ’ ‘ y ’ ‘    ’ ] X=\left[ \begin{array}{c} ‘t’ & ‘h’ & ‘e’ & ‘\;’ & ‘t’\\ ‘e’ & ‘\;’ & ‘b’ & ‘y’ & ‘\;’\\ \end{array} \right] X=[tehebyt]
如果用 Y Y Y表示训练数据的标签的话,就是取与 X X X的每一个元素在序列中的后一个元素,因为我们是用前一个字符预测下一个字符,得到的 Y Y Y就如下:
Y = [ ‘ h ’ ‘ e ’ ‘    ’ ‘ t ’ ‘ i ’ ‘    ’ ‘ b ’ ‘ y ’ ‘    ’ ‘ h ’ ] Y=\left[ \begin{array}{c} ‘h’ & ‘e’ & ‘\;’ & ‘t’ & ‘i’\\ ‘\;’ & ‘b’ & ‘y’ & ‘\;’ & ‘h’\\ \end{array} \right] Y=[hebytih]

回到我们刚才的代码中的train_iter,其结构如下:

(tensor([[ 3,  9,  2,  ...,  2,  1,  3],
        [15,  4, 14,  ...,  4,  6, 11],
        ...,
        [ 3,  1,  4,  ..., 12,  2, 13],
        [ 9,  2,  1,  ...,  4,  5, 10]]),
        tensor([[ 9,  2,  1,  ...,  1,  3,  5],
        [ 4, 14, 18,  ...,  6, 11, 20],
        ...,
        [ 1,  4,  1,  ...,  2, 13,  1],
        [ 2,  1, 13,  ...,  5, 10,  1]]))

可以看到它是(tensor,tensor)这样的结构,你可能已经发现了,(tensor,tensor) = ( X X X, Y Y Y),他们都是一个32X35的矩阵,矩阵中的每一个元素都是一个英文字母在vocab里面的映射。这就是我们输入RNN模型循环一次的输入数据。现在 我们来计算一下train_iter中有多少个(tensor, tensor),我们有10000个词元,num_steps=35,那么我们得到的分块为10000/35 = 285 ,batch_size = 32, 那么我们最终得到了285/32 = 8个(tensor, tensor)

但是如果使用上面的矩阵作为输入,神经网络是无法学习到好的模式的,我们通常会使用one-hot编码来实现

F.one_hot(torch.tensor([0, 2]), len(vocab))
给定一个序列[0,2] 和 vocab向量,函数会把 0 生成为一个维度大小与vocab相同的向量,
向量中的1代表的是0在vocab中的位置,其他全为0
tensor([[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0],
        [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0]])

模型细节
在这里插入图片描述
每一个时间步包含了n个神经元

四、门控循环单元(GRU)

关注一个序列

  • 不是每一个观察值都同等重要
  • 只记住相关的观察需要:能关注的机制(更新门);能遗忘的机制(重置门)


R t = σ ( X t W x r + H t − 1 W h r + b r ) Z t = σ ( X t W x z + H t − 1 W h z + b r ) R_t = \sigma(X_tW_{xr} + H_{t-1}W_{hr} + b_r)\\ Z_t = \sigma(X_tW_{xz} + H_{t-1}W_{hz} + b_r) Rt=σ(XtWxr+Ht1Whr+br)Zt=σ(XtWxz+Ht1Whz+br)
在这里插入图片描述
候选隐藏状态
H t ~ = t a n h ( X t W x h + ( R t ⨀ H t − 1 ) W h h + b h ) \tilde{H_t} = tanh(X_tW_{xh} + (R_t \bigodot H_{t-1}) W_{hh} + b_h) Ht~=tanh(XtWxh+(RtHt1)Whh+bh)
在这里插入图片描述
隐状态
H t = Z t ⨀ H t − 1 + ( 1 − Z t ) ⨀ H t ~ H_t = Z_t \bigodot H_{t-1} + (1-Z_t) \bigodot \tilde{H_t} Ht=ZtHt1+(1Zt)Ht~
在这里插入图片描述
总结
R t = σ ( X t W x r + H t − 1 W h r + b r ) Z t = σ ( X t W x z + H t − 1 W h z + b r ) H t ~ = t a n h ( X t W x h + ( R t ⨀ H t − 1 ) W h h + b h ) H t = Z t ⨀ H t − 1 + ( 1 − Z t ) ⨀ H t ~ \begin{array}{l} R_t = \sigma(X_tW_{xr} + H_{t-1}W_{hr} + b_r)\\ Z_t = \sigma(X_tW_{xz} + H_{t-1}W_{hz} + b_r)\\ \tilde{H_t} = tanh(X_tW_{xh} + (R_t \bigodot H_{t-1}) W_{hh} + b_h)\\ H_t = Z_t \bigodot H_{t-1} + (1-Z_t) \bigodot \tilde{H_t} \end{array} Rt=σ(XtWxr+Ht1Whr+br)Zt=σ(XtWxz+Ht1Whz+br)Ht~=tanh(XtWxh+(RtHt1)Whh+bh)Ht=ZtHt1+(1Zt)Ht~

五、长期记忆网络(LSTM)

长期记忆网络包含三部分关键的控制门

  • 遗忘门:将值朝0减少
  • 输入门:决定不是忽略掉输入数据
  • 输出门:决定是不是使用隐状态


I t = σ ( X t W x i + H t − 1 W h i + b i ) F t = σ ( X t W x f + H t − 1 W h f + b f ) O t = σ ( X t W x o + H t − 1 W h o + b o ) I_t = \sigma(X_tW_{xi} + H_{t-1}W_{hi} + b_i)\\ F_t = \sigma(X_tW_{xf} + H_{t-1}W_{hf} + b_f)\\ O_t = \sigma(X_tW_{xo} + H_{t-1}W_{ho} + b_o)\\ It=σ(XtWxi+Ht1Whi+bi)Ft=σ(XtWxf+Ht1Whf+bf)Ot=σ(XtWxo+Ht1Who+bo)
在这里插入图片描述
候选记忆单元

C t ~ = t a n h ( X t W x c + H t − 1 W h c + b c ) \tilde{C_t} = tanh(X_tW_{xc} + H_{t-1}W_{hc} + b_c) Ct~=tanh(XtWxc+Ht1Whc+bc)
在这里插入图片描述
记忆单元
C t = F t ⨀ C t − 1 + I t ⨀ C t ~ C_t = F_t \bigodot C_{t-1} + I_t \bigodot \tilde{C_t} Ct=FtCt1+ItCt~
在这里插入图片描述
隐状态
H t = O t ⨀ t a n h ( C t ) H_t = O_t \bigodot tanh(C_t) Ht=Ottanh(Ct)
在这里插入图片描述
总结
I t = σ ( X t W x i + H t − 1 W h i + b i ) F t = σ ( X t W x f + H t − 1 W h f + b f ) O t = σ ( X t W x o + H t − 1 W h o + b o ) C t ~ = t a n h ( X t W x c + H t − 1 W h c + b c ) C t = F t ⨀ C t − 1 + I t ⨀ C t ~ H t = O t ⨀ t a n h ( C t ) \begin{array}{l} I_t = \sigma(X_tW_{xi} + H_{t-1}W_{hi} + b_i) \\ F_t = \sigma(X_tW_{xf} + H_{t-1}W_{hf} + b_f) \\ O_t = \sigma(X_tW_{xo} + H_{t-1}W_{ho} + b_o) \\ \tilde{C_t} = tanh(X_tW_{xc} + H_{t-1}W_{hc} + b_c) \\ C_t = F_t \bigodot C_{t-1} + I_t \bigodot \tilde{C_t} \\ H_t = O_t \bigodot tanh(C_t) \end{array} It=σ(XtWxi+Ht1Whi+bi)Ft=σ(XtWxf+Ht1Whf+bf)Ot=σ(XtWxo+Ht1Who+bo)Ct~=tanh(XtWxc+Ht1Whc+bc)Ct=FtCt1+ItCt~Ht=Ottanh(Ct)
LSTM与RNN的区别就是RNN试图记住前面所有的内容来预测后一个内容,而LSTM因为引入了一个记忆单元即 C C C,通过记忆单元使得LSTM有能力自由选择每个时间步里面记忆的内容。
假设现在有一个场景:期末考试周,我们在每一个时间步要考一门课程。假设我们到了第 t t t步,现在要靠线性代数,那么我们的输入就是 X t X_t Xt 就是我们复习的线性代数的内容,中间的过程就是我们复习过程中形成的记忆,考完线性代数后我们就会形成一个线代的记忆 C t C_t Ct和状态 H t H_t Ht , 假设 C t − 1 C_{t-1} Ct1 H t − 1 H_{t-1} Ht1是我们考完高等数学之后的记忆和状态。

首先是遗忘门 F t F_t Ft:我们现在复习的是线性代数,那么我们就要尽可能的将 C t − 1 C_{t-1} Ct1高数中和线性代数无关的那一部分的内容遗忘掉,好腾出空间来记忆线性代数的内容,那么如何做到这一点呢?我们得到的 F t F_t Ft是一个n维的向量(n的大小与你的记忆单元的维度相同),每一个维度的值都是0到1之间 F t F_t Ft=[0,0.1,0.15,0.98,…,0.23] , 我们做运算 F t ⨀ C t − 1 F_t\bigodot C_{t-1} FtCt1 ,即将两个向量对应元素相乘,达到的效果就是我们把高数中与现代无关的部分尽量忘掉,而与现代相关的部分保留下来。
然后是更新门 I t I_t It C t ~ \tilde{C_t} Ct~是通过输入学习到的新的记忆,但是这个记忆并不是都有用。例如我们在复习线性代数的时候,我们学习的知识可能包含与考点无关的内容,对我们的考试没有帮助。我们就通过 I t I_t It来过滤,通过做计算 I t ⨀ C t ~ I_t\bigodot \tilde{C_t} ItCt~。然后我们将高数中有用的知识和当下与考点相关的内容结合起来,就形成了新的记忆 C t = F t ⨀ C t − 1 + I t ⨀ C t ~ C_t=F_t\bigodot C_{t-1} + I_t\bigodot \tilde{C_t} Ct=FtCt1+ItCt~
最后是输出门 O t O_t Ot:当我们带着 C t C_t Ct去考试的时候,我们首先做一个 t a n h ( C t ) tanh(C_t) tanh(Ct)的操作,即将我们记忆的内容转化为我们答题的能力,但是我们考试的内容并不是包含了我们记忆的所有知识,那么我们需要做计算 O t ⨀ t a n h ( C t ) O_t\bigodot tanh(C_t) Ottanh(Ct)用到部分的知识来答题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值