1011 循环神经网络 RNN

时间:2022-10-12 20:54:57

循环神经网络(RNN)

  • recurrent neural networks,RNNs
  • 对于序列模型的神经网络

回顾

潜变量自回归模型

使用潜变量 ht 总结过去的信息

1011 循环神经网络 RNN

  • n 元语法模型中,单词 xt 在时间步 t 的条件概率仅取决于前面 n-1 个单词
  • xt 是和 ht 与 x(t-1) 相关的
  • t 时刻的潜变量 ht 是和 h(t-1) 和 x(t-1) 相关的

隐藏层和隐状态的区别:

  • 隐藏层是在从输入到输出的路径上(以观测角度来理解)的隐藏的层
  • 隐状态是在给定步骤所做的任何事情(以技术角度来定义)的输入,并且这些状态只能通过先前时间步的数据来计算

循环神经网络是具有隐状态的神经网络

假设有一个观察 x 和一个隐变量 ht ,根据ht就能够生成输出 ot

1011 循环神经网络 RNN

  • t 时刻的输出 ot 是根据 ht 输出的,ht 使用的是 x(t-1) 中的内容
  • 在计算损失的时候,是比较 ot 和 xt 之间的损失
  • xt 是用来更新 ht 使得观察 xt 向后移动
  • 捕获并保留序列直到当前时间步的历史信息(如当前时间步下神经网络的状态或记忆)的隐藏变量被称为隐状态(hidden state)

循环神经网络在三个相邻时间步的计算逻辑

1011 循环神经网络 RNN

  • 首先拼接当前时间步 t 的输入 Xt 和前一时间步 t-1 的隐状态 H(t-1)
  • 然后将拼接的结果送入带有激活函数 Φ 的全连接层
  • 全连接层的输出就是当前时间步 t 的隐状态 Ht

循环神经网络与 MLP(多层感知机)的区别就在于多了一个时间轴,假设没有这个时间关系的话,循环神经网络就会退化成为 MLP

  • 保存了前一个时间步的隐藏状态 h(t-1)
  • 引入了一个新的权重参数 Whh 来描述如何在当前时间步中使用前一个时间步的隐藏变量

RNN P1 - 07:05循环神经网络是如何更新的

  • 假设 ht 是一个隐藏状态,Φ 是激活函数。Whx 是 MLP 隐层的权重,x(t-1) 是 t-1 时刻的输入,bh 是对应的偏移量
  • ht 不仅和 x 相关,还和前一时刻的 h 相关
  • 输出是由隐藏状态乘上权重再加上一个偏移量得到的

所以,

1、循环神经网络就是在 MLP 的基础上加了一项 Whh*h(t-1) 使得它能够于前一时刻的 h(t-1) 产生关联,假设忽略掉时间轴的情况下,本身和 MLP 是没有任何区别的

2、循环神经网络并没有对 x 进行建模,所有 x 之间的时序信息都存储在潜变量 h 当中

  • 实际上就相当于是将时序信息存储在了 Whh 中

3、因为在当前时间步中,隐状态使用的定义与前一个时间步中使用的定义相同,因此隐藏变量的计算是循环的,于是基于循环计算的隐状态神经网络被命名为循环神经网络(recurrent neural network),循环神经网络中执行隐藏变量计算的层称为循环层(recurrent layer)

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

基于循环神经网络的字符级语言模型

  • 语言模型的目标是根据过去的的和当前的词元预测下一个词元(因此需要将原始序列移位一个词元作为标签)
  • 为简化训练,这里所使用的是字符级语言模型,将文本词元化为字符而不是单词

训练步骤

输入序列和标签分别是“machine”和“achine”

1011 循环神经网络 RNN

在训练过程中,对每个时间步的输出层的输出进行 softmax 操作,然后利用交叉熵损失计算模型输出和标签之间的误差

  • 以上图中第3个时间步的输出 O3 为例,由于隐藏层中隐状态的循环计算,O3 由文本序列 “m” 、“a” 和 “c” 确定
  • 由于训练数据中输入文本序列的下一个字符是 “h” ,因此第三个时间步的损失将取决于下一个字符的概率分布,而下一个字符是基于特征序列 “m”、“a”、“c” 和这个时间步的标签 “h” 生成的

1011 循环神经网络 RNN

语言模型中,假设当前输入是“你”的话,那么会更新隐变量,然后预测“好”,接下来观测到了“好”,然后更新隐变量,再输出逗号

  • 输出是用来匹配观察的,但是在生成 t 时刻的输出 ot 时,不能够看到 t 时刻的观察 xt ,也就是说当前时刻的输出是用来预测当前时刻的观察,但是输出发生在观察之前

困惑度(perplexity)

语言模型实际上就是一个分类模型,假设字典大小是 m 的话,语言模型实际上就是 m 类的分类问题,每次预测下一个词的时候,实际上就是在预测下一个词的类别

衡量分类问题的好坏可以用交叉熵,因此,衡量一个语言模型的好坏可以用平均交叉熵

1011 循环神经网络 RNN

  • n:序列长度,长为 n 的序列就相当于是做 n 次预测,也就是做了 n 次分类,因此衡量一个语言模型的好坏可以在交叉熵的基础上取平均
  • p:语言模型的预测概率,由语言模型给出
  • xt:真实词,在时间步 t 从该序列中观察到的实际词元

由于历史原因 NLP 使用困惑度 exp(π) 来衡量,平均每次可能的选项,也就是对上面的平均交叉熵做指数运算

  • 为什么做指数运算?好处是做完指数运算之后结果会变大,数值变大之后就能够很容易看出来改进所带来的好处

困惑度的最好的理解是“下一个词元的实际选择数的调和平均数”,也可以认为是下一个词的候选数量,这样在直观上更容易理解

  • 在最好的情况下,模型总是完美地估计标签词元的概率为1。 在这种情况下,模型的困惑度为1
  • 在最坏的情况下,模型总是预测标签词元的概率为0。 在这种情况下,困惑度是正无穷大,表示根本预测不出下一个词到底是什么
  • 在基线上,该模型的预测是词表的所有可用词元上的均匀分布。 在这种情况下,困惑度等于词表中唯一词元的数量。 事实上,如果在没有任何压缩的情况下存储序列, 这将是我们能做的最好的编码方式。 因此,这种方式提供了一个重要的上限, 而任何实际模型都必须超越这个上限

梯度裁剪

迭代中计算这 T 个时间步上的梯度,在反向传播过程中产生长度为 O(T) 的矩阵乘法链,导致数值不稳定

  • 一连串的矩阵相乘的话会导致结果要么很小,要么很大:如果结果很小的话可能会导致训练不动;如果结果很大的话,可能会发生梯度爆炸导致结果出错

梯度裁剪能够有效预防梯度爆炸

  • 如果梯度长度超过 θ ,那么拖影回长度 θ1011 循环神经网络 RNN

  • g:所有层上的梯度全部放在向量 g 当中
  • 假设 g 的长度 L 太长导致超过了 θ ,那么就需要将长度 L 降回到 θ ,也就是说只要是 g 的长度是正常的就不做任何操作,如果 g 的长度超出了给定的范围,就将其裁剪回给定的范围中,这样就能够有效地避免梯度爆炸

更多应用

一对一

  • 也就是最简单的 MLP :给定一个样本,然后输出一个标签

一对多

  • 文本生成:给定一个词,然后生成一个一个的词

多对一

  • 文本分类:给定一个序列,在最后的时刻输出,得到具体的分类

多对多

  • 问答、机器翻译:给定一个序列,先不输出,然后在序列输入完毕之后输出答案
  • Tag 生成:给定一个序列,然后输出每个词的 Tag ,比如输入一个句子,然后输出句子中每个词是名词、动词还是形容词等

总结

1、对隐藏状态使用循环计算的神经网络称为循环神经网络(RNN),循环神经网络的输出取决于当下输入和前一时间的隐变量

  • 循环神经网络的隐藏状态可以捕获当前时间步序列的历史信息
  • 隐变量是用来存储历史信息和下一个历史信息的转换规则,所以在拿到过去的输入和当前的隐藏状态就能够预测当前的输出
  • Whh 拥有一定的时序预测目的

2、应用到语言模型中时,循环神经网络根据当前词预测下一次时刻词

  • 根据当前的输入更新当前时刻的隐藏状态就能够预测下一个时刻的输出
  • RNN 是一个隐变量模型,隐变量是一个向量

3、通常使用困惑度来衡量语言模型的好坏

  • 取平均值,然后进行指数操作,就得到了困惑度
  • 困惑度实际上衡量了语言模型对下一个词的预测所选取的候选词数量,这个候选词的数量越少越好

4、为了解决梯度爆炸的问题,RNN 一般是需要进行梯度裁剪的,这也是最简单的方法

5、循环神经网络模型的参数数量不会随着时间步的增加而增加

6、使用循环神经网络可以创建字符级语言模型