《动手学深度学习》笔记——循环神经网络 RNN
Hyplus目录
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})
或反过来
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)
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})
可得
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 基本网络模型
循环神经网络的输出取决于当下输入和前一时间的隐变量。
应用到语言模型中时,循环神经网络根据当前词预测下一次时刻词。
更新隐藏状态:
\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的应用
4 现代循环神经网络
更多有关时间序列预测的RNN网络,详见时间序列预测模型。
4.1 长短期记忆网络(LSTM)
LSTM(Long Short-Term Memory,长短期记忆网络)是一种改进的递归神经网络架构,专为处理和预测时间序列中的长期依赖问题而设计。相比传统RNN,LSTM在建模复杂的、非线性的时间序列数据方面更具优势。其核心创新在于引入了三个关键的“门”结构:输入门、遗忘门和输出门。这些门控机制使得LSTM能够有选择性地接收、保留或遗忘信息,从而有效地缓解了梯度消失或梯度爆炸带来的训练困难。通过精细控制信息的流动,LSTM可以在保留关键历史信息的同时,剔除无关内容,实现对序列数据中长期与短期依赖关系的灵活建模。
LSTM通过精细的门控机制,有效管理信息的流入、保留与输出,在面对长时间依赖的问题时,显著提升了模型的稳定性和学习能力,克服了传统RNN在长序列建模中的性能瓶颈。
三种门控机制:
- 遗忘门(Forget Gate)利用
\text{Sigmoid}
激活函数来判断是否保留前一个时刻的记忆内容(C_{t-1}
),其输出在0到1之间,表示遗忘与保留的比例。 - 输入门负责将新的信息写入当前记忆单元,由两个部分组成:
\text{Sigmoid}
函数确定哪些信息应被更新。\text{tanh}
函数生成候选记忆(\tilde{C}_{t}
),用于添加到记忆中。记忆单元的状态通过遗忘门和输入门的共同作用进行更新,从而实现信息的有序传递和过滤。
- 输出门依据当前的记忆状态,通过
\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的参数更少,并进行了梯度流动优化,更易直观控制。
两种门控机制:
- 重置⻔(Reset Gate)用于控制“可能还想记住”的过去状态的数量。
- 更新门(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条评论