⬆︎
×

深度学习基础(6):循环神经网络 RNN

《动手学深度学习》笔记——循环神经网络 RNN

1 序列模型

实际中很多数据是有时序结构的,常称之为序列数据

【例1】电影的评价随时间变化而变化

  • 拿奖后评分上升,直到奖项被忘记
  • 看了很多好电影后,人们的期望变高
  • 季节性:贺岁片、暑期档
  • 导演、演员的负面报道导致评分变低

【例2】音乐、语言、文本和视频等都是连续的

  • 标题“狗咬人”远没有“人咬狗” 那么令人惊讶
  • 大地震发生后,很可能会有几次较小的余震
  • 人的互动是连续的,从网上吵架可以看出
  • 预测明天的股价要比填补昨天遗失的服,更床

时序模型中,当前数据跟之前观察到的数据相关

1.1 统计工具

在时间t上观察到x_t,则可得T不独立的随机变量组成的时序序列

(x_1,\cdots,x_t) \sim p(\mathbf{x} )

根据条件概率公式

p(a,b)=p(a)p(b|a)=p(b)p(a|b)

可展开得以下两种统计序列模型

p(\mathbf{x})=p(x_1)p(x_2|x_1)p(x_3|x_1,x_2)\cdots p(x_T|x_1,\cdots,x_{T-1})

统计模型1

或反过来

p(\mathbf{x})=p(x_T)p(x_{T-1}|x_T)p(x_{T-2}|x_{T-1},x_T)\cdots p(x_1|x_2,\cdots,x_T)

统计工具2

1.2 建模方案

1.2.1 自回归模型

对见过的数据建模,称为自回归模型(autoregressive models)。自回归模型使用自身过去数据来预测未来。

对以下条件概率建模

p(\mathbf{x})=p(x_1)p(x_2|x_1)p(x_3|x_1,x_2)\cdots p(x_T|x_1,\cdots,x_{T-1})

统计模型1

可得

p(x_t|x_1,\cdots,x_{t-1})=p(x_t|f(x_1,\cdots,x_{t-1}))

1.2.2 马尔科夫模型

马尔科夫模型(Markov Model)假设当前仅跟最近少数数据相关,从而简化模型。

对于上述序列模型,假设当前数据只跟\tau个过去数据点相关,即

马尔科夫假设

p(x_t|x_1,\cdots,x_{t-1})=p(x_t|x_{t-\tau},\cdots,x_{t-1})=p(x_t|f(x_{t-\tau},\cdots,x_{t-1}))

由此使得模型变量个数始终不变,继而可以训练神经网络,例如在过去数据上训练一个MLP模型。

1.2.2 潜变量模型

潜变量模型引入了潜变量来概括过去信息(历史信息)

对于上述序列模型,潜变量可表示

h_t=f(x_1,\cdots,x_{t-1})

则有

x_t=p(x_t|h_t)

潜变量模型

由上图易知,每一个h_{t}取决去前一个h_{t-1}x_{t-1},而x_t则取决于该h_t和前一个x_{t-1}。每一段输出只跟1或2个变量相关。


2 语言模型

2.1 基本概念

给定文本序列x_1,\cdots,x_T,语言模型的目标是估计联合概率p(x_1,\cdots,x_T)

应用:
(1)做预训练模型(e.g. BERT、GPT)
(2)生成本文,给定前面几个词,不断地使用x_t\sim p(x_t|x_1,\cdots,x_{t-1})来生成后续文本
(3)判断多个序列中哪个更常见(e.g. "to recognize a speech" 和 "to wreck a nice beach")

2.2 使用计数来建模

假设序列长度为2,预测

p(x,x')=p(x)p(x'|x)=\frac{n(x)}{n} \frac{n(x,x')}{n(x)}

其中n为总词数,n(x),n(x,x')为单个单词和连续单词对的出现次数。

很容易拓展到长为3的情况:

p(x,x',x'')=p(x)p(x'|x)p(x''|x,x')=\frac{n(x)}{n} \frac{n(x,x')}{n(x)}\frac{n(x,x',x'')}{n(x,x')}

2.3 N元语法

当序列很长时,由于文本量不够大,很可能n(x_1,\cdots,x_T)≤1。可使用马尔科夫假设缓解这个问题。使用统计方法时常采用N元语法

一元语法(\tau=1):

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_2)}{n}\frac{n(x_2)}{n}

二元语法(\tau=2):

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)}

三元语法(\tau=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)

3 循环神经网络(RNN)

3.1 基本网络模型

循环神经网络的输出取决于当下输入和前一时间的隐变量。

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

RNN

更新隐藏状态:

\mathbf{h}_t=\phi(\mathbf{W}_{hh}h_{t-1}+\mathbf{W}_{hx}\mathbf{x}_{t-1}+\mathbf{b}_h)

输出:

\mathbf{o}_t=\phi(\mathbf{W}_{ho}\mathbf{h}_t+\mathbf{b}_o)

可见,RNN是靠\mathbf{W}_{hh}来存储时序信息,去掉其所在项即将RNN退化成MLP。

3.2 困惑度(Perplexity)

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

\pi=\frac1n \sum\limits_{i=1}^n-\log p(x_t|x_{t-1},\cdots)

其中p为语言模型的预测概率,x_t为真实词。

由于历史原因,NLP使用困惑度\exp(\pi)来衡量,表示平均每次可能选项(1表示完美,\infin为最差情况)。

3.3 梯度剪裁

迭代中计算着T个时间步上的梯度,在反向传播过程中产生长度为O(T)的矩阵乘法链,导致数值不稳定。梯度剪裁能有效预防梯度爆炸。

如果梯度长度超过\theta,则拖影回长度\theta,即

\mathbf{g}\leftarrow \min(1,\frac{\theta}{\left \| \mathbf{g} \right \| })\mathbf{g}

3.4 各种RNN的应用

RNNs


4 现代循环神经网络

更多有关时间序列预测的RNN网络,详见时间序列预测模型

4.1 长短期记忆网络(LSTM)

LSTM(Long Short-Term Memory,长短期记忆网络)是一种改进的递归神经网络架构,专为处理和预测时间序列中的长期依赖问题而设计。相比传统RNN,LSTM在建模复杂的、非线性的时间序列数据方面更具优势。其核心创新在于引入了三个关键的“门”结构:输入门、遗忘门和输出门。这些门控机制使得LSTM能够有选择性地接收、保留或遗忘信息,从而有效地缓解了梯度消失或梯度爆炸带来的训练困难。通过精细控制信息的流动,LSTM可以在保留关键历史信息的同时,剔除无关内容,实现对序列数据中长期与短期依赖关系的灵活建模。

LSTM通过精细的门控机制,有效管理信息的流入、保留与输出,在面对长时间依赖的问题时,显著提升了模型的稳定性和学习能力,克服了传统RNN在长序列建模中的性能瓶颈。

lstm

三种门控机制:

  1. 遗忘门(Forget Gate)利用\text{Sigmoid}激活函数来判断是否保留前一个时刻的记忆内容(C_{t-1}),其输出在0到1之间,表示遗忘与保留的比例。
  2. 输入门负责将新的信息写入当前记忆单元,由两个部分组成:
    • \text{Sigmoid}函数确定哪些信息应被更新。
    • \text{tanh}函数生成候选记忆(\tilde{C}_{t}),用于添加到记忆中。记忆单元的状态通过遗忘门和输入门的共同作用进行更新,从而实现信息的有序传递和过滤。
  3. 输出门依据当前的记忆状态,通过\text{Sigmoid}\text{tanh}的组合,决定哪些部分的记忆将被传递至下一层或下一个时间步。

设有h个隐藏单元,批量大小为n,输入数为d,则输入为\mathbf{X}_t \in \mathbb{R}^{n\times h},前一时间步的隐状态为\mathbf{H}_{t-1} \in \mathbb{R}^{n\times h}。时间步t的门定义如下:遗忘门为\mathbf{F}_t \in \mathbb{R}^{n\times h},输入门为\mathbf{I}_t \in \mathbb{R}^{n\times h},,输出门为\mathbf{O}_t \in \mathbb{R}^{n\times h}。计算方式如下:

\mathbf{F}_t = \sigma(\mathbf{X}_t\mathbf{W}_{xf}+\mathbf{H}_{t-1}\mathbf{W}_{hf}+\mathbf{b}_f)\\
\mathbf{I}_t = \sigma(\mathbf{X}_t\mathbf{W}_{xi}+\mathbf{H}_{t-1}\mathbf{W}_{hi}+\mathbf{b}_i)\\
\mathbf{O}_t = \sigma(\mathbf{X}_t\mathbf{W}_{xo}+\mathbf{H}_{t-1}\mathbf{W}_{ho}+\mathbf{b}_o)

其中\mathbf{W}_{xf},\mathbf{W}_{xi},\mathbf{W}_{xo}\in \mathbb{R}^{d\times h}\mathbf{W}_{hf},\mathbf{W}_{hi},\mathbf{W}_{ho}\in \mathbb{R}^{h\times h}为权重参数,\mathbf{b}_f,\mathbf{b}_i,\mathbf{b}_o\in \mathbb{R}^{1\times h}为偏置参数。

候选记忆元(Candidate Memory Cell)\tilde{\mathbf{C}}_{t} \in \mathbb{R}^{d\times h}的计算方式与上述门类似,使用\tanh作为激活函数,值域为(-1,1),在时间步t处的计算式如下:

\tilde{\mathbf{C}}_{t}=\tanh(\mathbf{X}_t\mathbf{W}_{xc}+\mathbf{H}_{t-1}\mathbf{W}_{hc}+\mathbf{b}_c)

其中\mathbf{W}_{xc}\in \mathbb{R}^{d\times h}\mathbf{W}_{hc}\in \mathbb{R}^{h\times h}为权重函数,\mathbf{b}_c\in \mathbb{R}^{1\times h}为偏置参数。

记忆状态\mathbf{C}_t\in \mathbb{R}^{n\times h}根据遗忘门输入门的结果动态更新,其中输入门\mathbf{I}_t控制采用多少来自候选记忆元\tilde{\mathbf{C}}_{t}的新数据,遗忘门\mathbf{F}_t控制保留多少过去的记忆元\mathbf{C}_{t-1}\in \mathbb{R}^{n\times h}的内容。使用按元素乘法,可得:

\mathbf{C}_t=\mathbf{F}_t\odot \mathbf{C}_{t-1}+\mathbf{I}_t\odot \tilde{\mathbf{C}}_{t}

若遗忘门始终为1且输入门始终为0,则过去的记忆元\mathbf{C}_{t-1}将随时间被保存并传递到当前时间步。引入这种设计是为了缓解梯度消失问题,并更好地捕获序列中的长距离依赖关系。

隐状态\mathbf{H}_{t}\in \mathbb{R}^{n\times h}通过输出门和\tanh激活函数生成,确保值始终在(-1,1)内。最终更新公式如下:

\mathbf{H}_{t}=\mathbf{O}_{t}\odot \tanh(\mathbf{C}_{t})

4.2 门控循环单元(GRU)

GRU(Gated Recurrent Unit,门控循环单元)是一种改进的循环神经网络(RNN)结构,通过引入更新门和重置门解决传统RNN的梯度消失问题,有效捕捉长期依赖关系。相比如LSTM,GRU的参数更少,并进行了梯度流动优化,更易直观控制。

GRU

两种门控机制:

  1. 重置⻔(Reset Gate)用于控制“可能还想记住”的过去状态的数量。
  2. 更新门(Update Gate)用于控制新状态中有多少个是旧状态的副本。

设有h个隐藏单元,批量大小为n,输入数为d,则输入为\mathbf{X}_t \in \mathbb{R}^{n\times h},前一时间步的隐状态为\mathbf{H}_{t-1} \in \mathbb{R}^{n\times h}。则重置门\mathbf{R}_{t} \in \mathbb{R}^{n\times h}和更新门\mathbf{Z}_{t} \in \mathbb{R}^{n\times h}的计算方式如下:

\mathbf{R}_{t} = \sigma(\mathbf{X}_{t}\mathbf{W}_{xr}+\mathbf{H}_{t-1}\mathbf{W}_{hr}+\mathbf{b}_{r})\\
\mathbf{Z}_{t} = \sigma(\mathbf{X}_{t}\mathbf{W}_{xz}+\mathbf{H}_{t-1}\mathbf{W}_{hz}+\mathbf{b}_{z})

其中\mathbf{W}_{xr},\mathbf{W}_{xz}\in \mathbb{R}^{d\times h}\mathbf{W}_{hr},\mathbf{W}_{hz}\in \mathbb{R}^{h\times h}为权重参数,\mathbf{b}_r,\mathbf{b}_z\in \mathbb{R}^{1\times h}为偏置参数。注意在求和过程中会触发广播机制。此处使用\text{sigmoid}激活函数将输入值转换到区间(0,1)

候选隐状态(Candidate Hidden State)\tilde{\mathbf{H}}_{t} \in \mathbb{R}^{n\times h}在常规隐状态的基础上与重置⻔\mathbf{R}_{t}集成计算得到,以减少以往状态的影响。计算方式如下:

\tilde{\mathbf{H}}_{t}=\tanh(\mathbf{X}_{t} \mathbf{W}_{xh}+(\mathbf{R}_{t} \odot \mathbf{H}_{t-1} )\mathbf{W}_{hh} +\mathbf{b}_{h} )

其中\mathbf{W}_{xh}\in \mathbb{R}^{d\times h}\mathbf{W}_{hh}\in \mathbb{R}^{h\times h}为权重参数,\mathbf{b}_h\in \mathbb{R}^{1\times h}为偏置参数。此处使用\text{tanh}非线性激活函数将输入值保持在区间(-1,1)中。

隐状态\mathbf{H}_{t}\in \mathbb{R}^{n\times h}在候选隐状态的基础上结合更新门\mathbf{Z}_{t}可得,更新门只需在\mathbf{H}_{t-1}\tilde{\mathbf{H}}_{t}之间进行按元素的凸组合即可。最终更新公式如下:

\mathbf{H}_{t}=\mathbf{Z}_{t}\odot \mathbf{H}_{t-1}+(1-\mathbf{Z}_{t})\odot \tilde{\mathbf{H}}_{t}

《深度学习基础(6):循环神经网络 RNN》有1条评论

发表评论