Skip to content

RNN 循环神经网络 ​

Recurrent Neural Network ​

是一种用于处理序列数据的神经网络架构。与传统神经网络不同,RNN 具有记忆功能,能够捕捉序列中的时间依赖关系。

RNN 的核心在于循环结构,这里以最简单的 Elman RNN 为例说明。对于一个序列输入{x1,x2,...,xT} ,在每个时间步 t,RNN 会学习到一个隐藏状态 ht。

ht=f(Whht−1+Uxt+b)

其中:

  • ht 是当前时刻的隐藏状态
  • ht−1 是前一时刻的隐藏状态,由xt和ht−1共同决定
  • xt 是当前时刻的输入
  • Wh 和 U 是权重矩阵
  • b 是偏置项
  • f 是激活函数(通常为 tanh)

结构 ​

RNN

  • ot是时刻的输出,例如我们希望预测一个句子的下一个单词,则输出希望是我们字典中所有词的概率组成的向量ot=softmax(Vht)

TIP

传统的神经网络在每一层采用不同的参数,而 RNN 在所有步中采用共同的参数(U,V,W),这表示我们在每一步执行相同的任务,仅仅是输入不同而已。这样会缩减需要学习的参数数量

RNN 的优缺点 ​

优点 ​

  • 处理序列数据:RNN 能够处理任意长度的序列数据
  • 记忆能力:RNN 能够记住之前的信息,从而捕捉时间依赖关系

缺点 ​

  • 梯度消失/爆炸问题:RNN 在训练过程中容易出现梯度消失或爆炸的问题,导致难以训练长序列
  • 计算效率低:RNN 的计算是逐步进行的,无法并行化处理

前向传播 ​

  1. 隐藏状态:(f通常为 tanh)

    ht=f(Whht−1+Uxt+b)
  2. 输出:

    ot=Vht+c
  3. 预测输出:(σ通常为 softmax)

    y^t=σ(ot)

反向传播 ​

推导 ​

对任意t时刻:

∂Lt∂U=∂Lt∂ot⋅∂ot∂ht⋅∂ht∂U=∂Lt∂ot⋅∂ot∂ht⋅∂ht∂ht−1⋅∂ht−1∂U=⋯=∑k=1t∂Lt∂ot∂ot∂ht(∏j=k−1t∂hj∂hj−1)∂hk∂U

假设损失函数为交叉熵损失:

∂Lt∂ot=y^t−yt

交叉熵损失

Lt=−∑iyt,ilog⁡y^t,iy^t,i=eot,i∑jeot,i∂y^t,i∂ot,k=y^t,i(δik−y^t,k)

其中,δik 为 kronecker delta 函数

δij={1如果 i=j0如果 i≠j

有:

∂Lt∂ot,k=−∑iyt,i∂log⁡y^t,i∂ot,k=−∑iyt,i1y^t,i⋅y^t,i(δik−y^t,k)=−∑iyt,i(δik−y^t,k)

由于∑iyt,i=1:

∂Lt∂ot,k=−(yt,k−y^t,k∑iyt,i)=yt,k−yt,k

所以:

∂Lt∂ot=y^t−yt

设:ak=Whhk−1+Uxk+b

∂Lt∂at=∂Lt∂ht∂ht∂at=∂Lt∂ht⊙f′(at)

例子

若h(t)=tanh⁡(at)

假设:

∂Lt∂ht=[δ1δ2]at=[a1a2]

则:

∂Lt∂at=[δ1(1−tanh2⁡(a1))δ2(1−tanh2⁡(a2))]
∂at∂U=xt⊤

定义序列索引 t 位置的隐藏状态的梯度为:

δt=∂Lt∂ht

定义最后的序列索引位置为 τ:

δτ=∂L∂hτ=V⊤(∂Lt∂ot)=V⊤(y^τ−yτ)

时间 t 对 U 的梯度贡献为:

∂L∂U|t=δt⊙f′(at)⋅xt⊤

U 的总梯度为:

∂L∂U=∑t=1τδt⊙f′(at)⋅xt⊤

同样的,W 的总梯度为:

∂L∂W=∑t=1τδt⊙f′(at)⋅ht−1⊤

V 的总梯度为:

∂L∂V=∑t=1τ(y^t−yt)ht⊤

b 的总梯度为:

∂L∂b=∑t=1τδt⊙f′(at)

例子

若h(t)=tanh⁡(at)

∂ht∂at=diag(1−ht2)∂Lt∂at=δt⋅diag(1−ht2)∂L∂U=∑t=1τδt⋅diag(1−ht2)⋅xt⊤(∂L∂U=∑t=1τδt⊙(1−ht2)⋅xt⊤)