RNN(Recurrent Neural Network)
RNN(Recurrent Neural Network)
传统的神经网络无法获取时序信息,然而时序信息在自然语言处理任务中非常重要。
例如对于这一句话 “我吃了一个苹果”,“苹果” 的词性和意思,在这里取决于前面词的信息,如果没有 “我吃了一个” 这些词,“苹果” 也可以翻译为乔布斯搞出来的那个被咬了一口的苹果。
也就是说,RNN 的出现,让处理时序信息变为可能。
RNN 的基本单元结构如下图所示:
上图左边部分称作 RNN 的一个 timestep,在这个 timestep 中可以看到,在 tt 时刻,输入变量 xtxt,通过 RNN 的一个基础模块 A,输出变量 htht,而 tt 时刻的信息,将会传递到下一个时刻 t+1t+1。
如果把模块按照时序展开,则会如上图右边部分所示,由此可以看到 RNN 为多个基础模块 A 的互连,每一个模块都会把当前信息传递给下一个模块。
RNN 解决了时序依赖问题,但这里的时序一般指的是短距离的,首先我们先介绍下短距离依赖和长距离依赖的区别:
短距离依赖:对于这个填空题 “我想看一场篮球____”,我们很容易就判断出 “篮球” 后面跟的是 “比赛”,这种短距离依赖问题非常适合 RNN。
长距离依赖:对于这个填空题 “我出生在中国的瓷都景德镇,小学和中学离家都很近,……,我的母语是____”,对于短距离依赖,“我的母语是” 后面可以紧跟着 “汉语”、“英语”、“法语”,但是如果我们想精确答案,则必须回到上文中很长距离之前的表述 “我出生在中国的瓷都景德镇”,进而判断答案为 “汉语”,而 RNN 是很难学习到这些信息的。
RNN(Recurrent Neural Network,循环神经网络)是一种用于处理序列数据的神经网络。与传统的神经网络不同,RNN具有内部状态(记忆),能够处理输入信息的序列,这使得它们非常适合处理语言处理、时间序列分析、语音识别等任务。以下是RNN的一些关键特点:
RNN的结构:
循环单元:RNN的核心是循环单元,它能够在序列的不同时间点共享参数。循环单元可以保存之前的信息,并将其与当前的输入一起使用来影响输出。
隐藏状态:在RNN中,隐藏状态(或称为内部状态)扮演着“记忆”的角色,它包含了关于之前看到的数据的信息。
输入和输出:RNN的输入是序列数据,输出可以是序列的每个时间点的预测,也可以是整个序列的最终预测。
RNN的工作原理:
信息传递:在每个时间步,RNN接收当前时间步的输入和一个隐藏状态(初始时通常是零向量)。
更新隐藏状态:基于当前的输入和前一个时间步的隐藏状态,RNN更新当前的隐藏状态。
生成输出:基于当前的隐藏状态,RNN生成当前时间步的输出。
重复过程:这个过程在序列的每个时间步重复进行。
RNN的挑战:
梯度消失和梯度爆炸:在长序列中,RNN容易遇到梯度消失或梯度爆炸的问题,这使得模型难以训练。
难以捕捉长距离依赖:简单RNN难以捕捉序列中的长距离依赖关系,这也是LSTM和GRU被提出的原因。
RNN 梯度消失的原因
RNN(循环神经网络)中的梯度消失问题主要是由于其在反向传播过程中处理长序列时的数学特性所导致的。以下是导致梯度消失的几个关键原因:
1. 连乘效应(Vanishing Gradient Problem)
在RNN中,隐藏状态 htht 是基于前一个隐藏状态 ht−1ht−1 和当前输入 xtxt 计算的。这个过程可以用以下公式表示:
ht=f(Wh⋅ht−1+Wx⋅xt+b)ht=f(Wh⋅ht−1+Wx⋅xt+b)
其中 ff 是激活函数,WhWh 和 WxWx 是权重矩阵,bb 是偏置项。
在反向传播过程中,梯度需要通过时间回溯,这意味着梯度会被连乘。如果激活函数的导数小于1(例如,对于Sigmoid或Tanh函数),那么随着时间步的增加,梯度会呈指数级减小。这就是所谓的连乘效应。
2. 激活函数的选择
常用的激活函数,如Sigmoid或Tanh,其导数的最大值都小于1。在反向传播时,如果链式法则中的多个这样的导数相乘,结果会迅速趋近于0。
例如,对于Sigmoid函数 σ(x)=11+e−xσ(x)=1+e−x1,其导数 σ′(x)=σ(x)(1−σ(x))σ′(x)=σ(x)(1−σ(x)) 的最大值为1/4。因此,随着时间步的增加,梯度会变得越来越小。
3. 长序列
在处理长序列时,RNN需要记住很久以前的信息,这要求梯度能够在很多时间步之间传播。然而,由于上述的连乘效应,梯度在传播过程中会迅速减小,导致模型难以学习到长距离的依赖关系。
4. 参数共享
RNN中的参数在所有时间步之间是共享的。这种参数共享虽然减少了模型的参数数量,但也意味着同样的权重会被用于每个时间步的梯度计算,这可能会加剧梯度消失的问题。
解决方案
为了解决梯度消失问题,研究者提出了以下几种方法:
LSTM(Long Short-Term Memory)和GRU(Gated Recurrent Unit):这些特殊的RNN架构通过引入门控机制来维持长期的梯度流,从而缓解梯度消失问题。
残差连接:在RNN单元中添加残差连接可以帮助梯度直接流过多个时间步。
梯度裁剪(Gradient Clipping):通过限制梯度的最大值来防止梯度爆炸,这也有助于缓解梯度消失问题。
更复杂的网络结构:例如Transformer,它使用自注意力机制来处理序列数据,避免了传统RNN的梯度消失问题。