循环神经网络(Recurrent Neural Network,简称RNN)是一种特殊的神经网络,它能够处理序列数据,通过将前一时间步的输出作为当前时间步的输入,从而在模型中引入了“记忆”机制。这种结构使得RNN特别适合于自然语言处理(NLP)等需要考虑前后文信息的任务。不同于传统神经网络中输入和输出相互独立,RNN能够捕捉到序列中的时间依赖性,例如在预测句子中的下一个词时,需要记住前一个词是什么。RNN通过隐藏层来捕捉句子的信息,理论上可以处理任意长度的序列,但实际上受限于只能回顾有限的几步。
在RNN的图解表示中,x_t
表示时间t的输入,s_t
表示时间t的隐藏状态,而O_t
表示时间t的输出。“展开”意味着将网络为整个序列写出,例如,如果一个序列有4个词,那么网络将被展开成一个4层的神经网络。可以将s_t
视为网络的“记忆”,因为它捕捉了所有先前步骤的信息。与传统神经网络在每一层使用不同的参数不同,RNN在所有层之间共享相同的参数,这表明正在用不同的输入执行相同的任务,从而减少了需要学习的参数总数。参数集(U, V, W)
用于对它们各自的输入应用线性变换。参数U
将输入x_t
转换为状态s_t
,参数W
将前一个状态s_t-1
转换为当前状态s_t
,而参数V
将计算出的内部状态s_t
映射到输出O_t
。
计算当前状态的公式为:h_t = f(h_t-1, x_t)
,其中h_t
是当前状态,h_t-1
是前一个状态,x_t
是当前输入。应用激活函数(例如tanh)后的方程为:h_t = tanh(whh * h_t-1 + wxh * x_t)
,其中whh
是循环神经元的权重,wxh
是输入神经元的权重。计算完最终状态后,可以产生输出。输出状态可以计算为:O_t = Why * h_t
,其中O_t
是输出状态,Why
是输出层的权重,h_t
是当前状态。
在RNN的反向传播中,为了训练RNN,需要一个损失函数。通常使用交叉熵损失,它经常与softmax配对使用,可以计算为:L = -ln(p_c)
,其中p_c
是RNN对正确类别(正或负)的预测概率。例如,如果一个正文本被RNN预测为95%的正,则损失为:L = -ln(0.95) = 0.051
。计算损失后,将使用梯度下降来训练RNN以最小化损失。反向传播的步骤包括:首先使用当前和实际输出计算交叉熵误差,然后对于网络中的每个时间步,计算相对于每个参数权重的梯度下降,一旦所有时间步的权重相同,可以将所有时间步的梯度合并在一起,然后更新循环神经元和密集层的权重。
在训练深度网络时,梯度会通过时间回溯到初始层。来自更深层的梯度会根据链式法则经历多次矩阵乘法,当它们接近早期层时,如果它们有小值(<1),它们会指数级缩小直至消失,这称为梯度消失问题,使得模型学习变得困难。而如果它们有大值(>1),那么它们最终会爆炸并破坏模型,这就是梯度爆炸问题。