李沐 X 动手学深度学习--第八章 循环神经网络

发布于:2024-12-23 ⋅ 阅读:(15) ⋅ 点赞:(0)
  • 循环神经网络处理的数据类型:序列信息,eg: 视频中的图像帧,对话中的音频信号,网站上的浏览行为
  • ps:许多使用循环网络的例子都是基于文本数据,故而我们在本章重点介绍语言模型

序列模型

统计工具

以上图近30年的富时100指数,其中,用x_{t}表示价格,即在时间步(time step)t \epsilonZ^{+}时,观察到的价格x_{t}(ps:t对于上图的这种序列通常是离散的,并且t在整数或者整数的子集上变化。

  • 一个交易员想在t日的股市中表现良好,所以通过以下途径预测x_{t}
  • 需要有效估计上式的原因:输入x_{t-1},...,x_{1}本身因t而异=》输入数据的数量,这个数字会随着我们遇到的数据量的增加而增加
  • 有效估计上式的2种方法:
  1. 自回归模型(autoregressive models):假设现实中相当长的序列x_{t-1},...,x_{1}是没必要的,则我们只需要满足某个长度为\tau的时间跨度(即观测x_{t-1},...,x_{t-\tau })(这种情况下,参数的数量保持不变(至少在t>\tau时,是这样的)对自己执行回归
  2. 隐变量自回归模型(latent autoregressive models)h_{t}:对过去观测的总结,(eg:如果我们要分析一个股票价格的时间序列,每天的股票价格是我们可以观测到的观测值。而在隐变量自回归模型中,ht可能代表影响股票价格的潜在因素,如市场情绪、经济指标等,这些因素并不直接体现在股票价格中,但它们可以通过模型学习得到,并用于预测未来的股价走势。因此,尽管我们不能直接观测到ht,但它是模型理解和预测股价变化的一个重要组成部分。),我们保留一些对过去观测的总结h_{t},并更新预测\hat{x}_{t} 和总结h_{t},这样就产生了基于\hat{x}_{t}=P(x_{t}|h_{t})估计x_{t},以及公式h_{t}=g(h_{t-1}x_{t-1})更新的模型。ps:h_{t}从未被观测到

  • 上面2个模型生成训练数据的方法:使用历史观测,预测下一个未来观测,整个序列的估计值将通过以下方式获得:

  • 自回归模型的近似法序列模型---马尔可夫模型:
  • 形如x_{t-1},...,x_{t-\tau }的序列估计x_{t}只要这种近似是精确的,该序列就满足马尔可夫条件(Markov condition)。如果\tau=1,则是一个一阶马尔可夫模型(first-order Markov model),P(x)如下:

如果x_{t}仅是离散值,使用动态规划,沿着马尔科夫链计算结果,eg:计算P(x_{t+1},x_{t-1}):

这样,我们就只用考虑在过去观察一个非常短的历史:P(x_{t+1},x_{t-1})=P(x_{t+1}x_{t})

  • 具体代码如下: 

 

 由上述图表可知,单步预测效果不错,时间步超过600+4(n_train + tau)的预测结果看起来也是可信的,但是如果数据观察序列的时间步只到604,则需要一步一步地向前迈进:(以上述代码为例)

此处的小知识:k步预测(k-step-ahead-prediction):通常,对于直到x_{t}的观测序列,其在时间步t+k处的预测输出\hat{x}_{t+k}。 eg:观察到x_{604},它的k步预测是\hat{x}_{604+k}  即必须使用我们自己的预测,而不是原始数据来进行多步预测

上图的例子,预测显然不理想:经过几个预测步骤后,预测结果很快衰减到一个常数:由于错误的累积:误差会随着步骤的递增而累积, 误差可能相当快地偏离真实的观测结果。eg:未来24小时的天气预报往往还算准确,但超过这一点,精度就会迅速下降。

  • 碎知识: 
  • 内插法:在现有观测值之间进行估计
  • 外推法:对超过已知观测范围进行预测
  • 内推法和外推法在实践上难度差别很大,对于手头上的序列数据,在训练时要始终尊重序列的时间顺序,最好不要基于未来的数据进行训练
  • 序列模型的估计统计工具是:自回归模型;隐变量自回归模型
  • 随着我们对预测时间k值的增加,会造成误差的快速累积和预测质量的极速下降

文本预处理 

  • 解析文本的常见预处理步骤:
  1. 将文本作为字符串加载到内存中
  2. 将字符串拆分为词元(eg:单词和字符)
  3. 建立一个词表,将拆分的词元映射到数字索引
  4. 将文本转换为数字索引序列,方便模型操作
  • 具体代码如下:

 

语言模型和数据集 

学习语言模型

  • 学习语言模型:对一个文档,甚至一个词元序列进行建模
  • 学习语言模型须知的一些小概念:
  • 基本概率规则如下:

  • 举例说明语言模型参数:eg:包含4个单词的一个文本序列的概率是:

这些概率本质语言模型的参数 

  • 现在学习模型遇到的一个问题:有些连续单词对出现频率低,所以估计这类单词正确的概率很困难。对于一些不常见的单词组合,就更难了。而且,许多合理的单词组合是存在的,但是数据集里没有,那么估计它们出现的正确概率就更难了。如果数据集很小/单词非常罕见,这类单词出现一次的机会可能都没有
  • 解决上面这个问题的常见策略:Laplace smoothing(拉普拉斯平滑)(某种形式的):eg:以下这种形式的Laplace smoothing:

 其中\epsilon _{1}\epsilon _{2}\epsilon _{3}超参数,\epsilon _{1}为例:=0,不应用平滑;接近正无穷大,\hat{P}(x)接近均匀概率分布1/m

然而,这样的模型很容易变得无效原因如下:首先,我们需要存储所有的计数;其次,这完全忽略了单词的意思。例如,“猫”(cat)和“猫科动物”(feline)可能出现在相关的上下文中,但是想根据上下文调整这类模型其实是相当困难的。最后,长单词序列大部分是没出现过的,因此一个模型如果只是简单地统计先前“看到”的单词序列频率,那么模型面对这种问题肯定是表现不佳的。

马尔可夫模型与n元语法 

如果,则序列上的分布满足一阶马尔可夫性质:阶数越高,对应的依赖关系就越长:

  • 通常,涉及一个、两个和三个变量的概率公式分别被称为一元语法(unigram)、二元语法(bigram)和三元语法(trigram)模型。下面,我们将学习如何去设计更好的型。 
  • 具体代码如下:

 读取长序列数据

  • 序列的本质:连续的
  • 处理序列的方法:将任意长的序列,用相同时间步数划分成子序列
  • 下面是不同的偏移量(指示初始位置)划分的不同子序列:
  • 上图的不同偏移量的划分,其效果都一样的好,但不能单一的选择某个偏移量,因为单一偏移量会导致训练网络的,所有可能的子序列的覆盖范围就是有限的
  • 我们采用随机偏移量划分序列以获得覆盖性(coverage)和随机性(randomness) 
  • 不同划分策略:
  • 随机采样(random sampling):每个样本都是从原始长序列上任意捕获的子序列(故而,在迭代过程中,相邻的,随机的,小批量的子序列不一定在原始序列上相邻);标签是移位了一个词元的原始序列;
  • 随机采样的具体代码:

  •  顺序分区:2个相邻的小批量中的子序列在原始序列上也是相邻的,在基于小批量的迭代过程中保留了拆分的子序列的顺序
  • 顺序分区具体代码如下:

小结:

  • 语言模型是自然语言处理的关键
  • n元语法通过截断相关性,为处理长序列提供了一种实用的模型
  • 长序列存在一个问题:它们很少出现/从不出现
  • 奇普夫定律支配着单词的分布,也适用于n元语法
  • 通过拉普拉斯平滑法可以处理结构丰富而频率不足的低频词词组 

循环神经网络 

  • 使用隐变量模型的原因:1.在n元语法模型中,单词x_{t}在时间步t的条件概率仅取决于前面n-1个单词,我们想将时间步t-(n-1)之前的单词可能产生的影响合并到x_{t}上;2.使用隐变量模型更节省存储空间
  • 隐变量模型公式:

h_{t-1}:隐状态(hidden state)(隐藏变量)(hidden variable) :存储到时间步t-1的序列信息

  • 计算隐状态的方法

x_{t}:当前输入  h_{t-1} :先前隐状态     隐变量模型不是近似值

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

有隐状态的循环神经网络

前提假设,变量含义:

  • 在时间步t处的小批量输入X_{t} \epsilon\mathbb{R}^{n\cdot d} 的每一行对应于来自该序列的时间步t处的一个样本
  • H_{t}\epsilon\mathbb{R}^{n\cdot h}:时间步t的隐藏变量
  • W_{hh}\epsilon\mathbb{R}^{h\cdot h}:权重参数,描述如何在当前时间步中使用前一个时间步的隐藏变量

在任意时间步t,隐状态的计算过程:

1.当前时间步隐藏变量计算

  • 当前时间步隐藏变量计算公式:(当前时间步隐藏变量由当前时间步的输入与前一个时间步的隐藏变量一起计算得出)

  • 由上式可知:这些变量捕获并保留了序列直到其当前时间步的历史信息(eg:当前时间步神经网络的状态或记忆)(所以这样的隐藏变量被称为隐状态(hidden state))
  • 上述公式中的变量(参数)之间的乘法相当于矩阵乘法
  • 上述公式的计算是循环的(recurrent)(因为每次计算当前的隐藏变量都是上述公式)(所以基于上述公式(循环计算)的隐状态神经网络被命名为循环神经网络(recurrent neural network)
  • 循环层(recurrent layer):在循环神经网络中执行上述公式计算的层 

2.循环神经网络输出层的计算

  • 循环神经网络输出层的计算公式:

  • W_{hq} \epsilon \mathbb{R}^{h\cdot q}:输出层的权重
  • b_{q} \epsilon \mathbb{R}^{1\times q }:输出层的偏置
  • 循环神经网络即使在不同的时间步,也是使用这些模型参数,所以,循环神经网络的参数开销不会随着时间步的增加而增加

下图是循环神经网络在3个相邻时间步的计算逻辑:

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

  • 基于循环神经网络的字符级语言模型中文本词元化为字符(而不是单词)
  • 训练过程的输出:1,对每个时间步的输出层的输出进行softmax操作;2,当前时间步的输出由前面所有的文本序列确定;3,当前时间步的损失取决于下一个字符的概率分布;4,下一个字符前面的特征序列(文本序列)和当前时间步的标签生成的
  • 计算模型输出和标签之间的误差计算方法交叉熵损失计算模型 
  • 实践中,批量大小为n > 1,每个词元由一个d维向量表示,则在时间步t输入X_{t}是一个n x d 矩阵

困惑度(Perplexity)

  • 困惑度评估模型

  • 上述公式意思是:下一个词元的实际选择数的调和平均数 
  • 在最好的情况下,模型总是完美地估计标签词元的概率为1。在这种情况下,模型的困惑度为1。
  • 在最坏的情况下,模型总是预测标签词元的概率为0。在这种情况下,困惑度是正无穷大。
  • 在基线上,该模型的预测是词表的所有可用词元的均匀分布;困惑度等于词表中唯一词元的数量;如果我们没有任何压缩的情况下存储序列,这是我们能做的最好编码方式,这个方式提供了一个上限,任何模型都必须超越这个上限。

循环神经网络的从零开始实现

RNN的简明实现 

通过时间反向传播 

  •  通过时间反向传播是RNN中反向传播技术的一个特定应用。
  • 通过时间反向传播基本思想:
  1. 将RNN的计算图一次展开一个时间步,获得模型变量和参数之间的依赖关系;
  2. 基于链式法则,应用反向传播计算和存储梯度。

RNN的梯度分析

RNN工作原理的简化模型

基本符号含义:

  • h_{t}:时间步t的隐状态
  • x_{t}:输入表示
  • o_{t}:输出表示
  • w_{h}:隐藏层的权重
  • w_{o}:输出层的权重
  • 每个时间步的隐状态和输出可以写为:

  • f:隐藏层的变换
  • g:输出层的变换
  • o_{t}:所有T个时间步内评估输出
  • y_{t}:所有T个时间步评估输出对应的标签

前向传播

  • 前向传播思路:
  1. 一次一个时间步的遍历三元组
  2. 通过一个目标函数在所有T个时间步内评估输出和对应的标签之间的差异。具体公式如下:

反向传播 

计算目标函数关于参数的梯度,按照链式法则,具体公式如下:

上述公式中的第三项中的\partial h_{t} / \partial w_{h} 既依赖h_{t-1}又依赖w_{h}h_{t-1}的计算也依赖于w_{h}。由此,使用链式法则得出第三项的具体表达式如下:

递推到整个Net的第三项具体公式如下:

  • 虽然得出整个Net的第三项表达式,但是当t很大时,这个链就会变得很长,成为了在计算上不可行的表达式。故而我们采用了截断求和计算。(因为蝴蝶效应:初始条件的很小变化就会导致结果发生不成比例的变化)

截断求和

截断时间步

  • 根据实践,在\tau步后截断第三项的求和计算,会带来真实梯度的近似,导致模型侧重于短期影响;将估计值偏向更简单和更稳定的模型

随机截断

  • 序列\xi _{t}:P(\xi _{t}=0)=1-\pi _{t} 且P(\xi _{t}=\pi _{t}^{-1})=\pi _{t}E[\xi _{t}]=1
  • \pi _{t} :一个与时间步 T 相关的概率值;用于控制序列 \xi _{t} 的截断(即停止反向传播);0<=\pi _{t}<=1。
  • z_{t}:是序列\xi _{t}的随机变量;E[z_{t}]=\partial h_{t} / \partial w_{h}
  • 前提假设:用随机变量z_{t} 替换 ,在预期中是正确的;会截断序列;通过使用序列\xi _{t}来实现,使用序列替代上面第三项表达式中的\partial h_{t} / \partial w_{h} , 得到新的第三项具体表达式:

  • 终止这个T时间步的条件\xi _{t}=0(这个导致了不同长度序列的加权和,其中长序列很少出现,可适当加大权重)

比较随机截断,常规截断,完整计算如下:

 经实践证明,虽然随机截断在理论上具有吸引力,但很可能是由于多种因素在实践中并不比常规截断更好。