RNN 反向传播公式推导(非矩阵式)

RNN 反向传播公式推导(非矩阵式)

因为模式识别非要用Latex来编辑公式,所以逼着我写一次博客。嗯,说不定这是一个很好的开始。因为笔者的水平有限,所以如果有不慎有疏漏,烦请不吝赐教。

参考的博客是:
循环神经网络(RNN)模型与前向反向传播算法 - 刘建平Pinard - 博客园
Markdown中数学公式整理 - Zhakel日常 - CSDN博客

关于RNN的基础知识和反向传播的定义就不再赘述,这不是本篇博客所要讲的重点。如果你感觉自己对RNN有一定了解而且至少已经知道三层神经网络反向传播怎么推导了之后,再来看这个比较合适。

RNN模型的可视化

在这里插入图片描述

(好像图有点丑)

参数解释:
  • 前一个RNN块的隐藏层: h ( t − 1 ) h^{(t-1)} h(t1),维度为H(在图中表示为H个节点)选取 h p ( t − 1 ) h_p^{(t-1)} hp(t1)作为研究节点。
  • 输入向量(输入层): x ( t ) x^{(t)} x(t),维度为L,选取 x i ( t ) x_i^{(t)} xi(t)为研究节点。
  • 隐藏层: h ( t ) h^{(t)} h(t),维度为H,选取 h j ( t ) h_j^{(t)} hj(t)为研究节点。
  • 未激活的隐藏层: z ( t ) z^{(t)} z(t),维度为H,选取 z j ( t ) z_j^{(t)} zj(t)为研究节点。这里主要是为了后面的推导方便,在图中没有标出。
  • 输出向量(输出层): O ( t ) O^{(t)} O(t),维度为C,选取 O k ( t ) O_k^{(t)} Ok(t)为研究节点。
  • h ( t − 1 ) h^{(t-1)} h(t1) h ( t ) h^{(t)} h(t)的矩阵记为 W W W, 选取 W j p W_{jp} Wjp 为研究权重,表示从 h p ( t − 1 ) h_p^{(t-1)} hp(t1)指向 h j ( t ) h_j^{(t)} hj(t)的连接权重。
  • x ( t ) x^{(t)} x(t) h ( t ) h^{(t)} h(t)的矩阵记为 U U U, 选取 U i p U_{ip} Uip 为研究权重,表示从 x i ( t ) x_i^{(t)} xi(t)指向 h j ( t ) h_j^{(t)} hj(t)的连接权重。
  • h ( t ) h^{(t)} h(t) O ( t ) O^{(t)} O(t)的矩阵记为 V V V, 选取 V k j V_{kj} Vkj 为研究权重,表示从 h j ( t ) h_j^{(t)} hj(t)指向 O k ( t ) O_k^{(t)} Ok(t)的连接权重。
  • b为到隐藏层的偏置(bias), b j b_j bj表示bias到 h j ( t ) h_j^{(t)} hj(t)的权重.
  • c为到输出层的偏置, c k c_k ck表示bias到 O k ( t ) O_k^{(t)} Ok(t)的权重.
  • y ^ ( t ) \hat{y}^{(t)} y^(t) 为预测向量, y ( t ) y^{(t)} y(t)为目标向量(正确值), E ( ω ) E(\omega) E(ω)表示误差函数(参数太多简写为 ω \omega ω).
  • t表示是第几个RNN块,或者是是序列的第几步。总的步长(steps)为 τ \tau τ.

需要注意的是,这里的 W W W U U U V V V b b b c c c 的权重在所有RNN块中都是共享的,所以反向传播的时候需要利用整体的误差来更新。

RNN的前向传播

1、首先将 h ( t − 1 ) h^{(t-1)} h(t1)层和 x ( t ) x^{(t)} x(t)层映射到 z ( t ) z^{(t)} z(t)中, z ( t ) z^{(t)} z(t)的第j个节点 z j ( t ) z_j^{(t)} zj(t)的映射关系如下:
z j ( t ) = ∑ i = 1 L U j i x i ( t ) + ∑ p = 1 H W j p x p ( t − 1 ) + b j ∗ 1 z_j^{(t)} = \sum_{i=1}^{L}{U_{ji}x_i^{(t)}} + \sum_{p=1}^{H}{W_{jp}x_p^{(t-1)} + b_j*1} zj(t)=i=1LUjixi(t)+p=1HWjpxp(t1)+bj1

  • 如图中的第一层的三个黑色箭头所示,其中黑色的箭头指求和中的项,所有的灰色箭头共同组成求和;每一个节点都如此连接与计算。

2、利用tanh激活函数激活 z ( t ) z^{(t)} z(t)层所有节点为 h ( t ) h^{(t)} h(t)层,即:
h j ( t ) = σ ( z j ( t ) ) = t a n h ( z j ( t ) ) ∀ j ∈ ( 1 , H ) h_j^{(t)} = \sigma(z_j^{(t)}) = tanh(z_j^{(t)})\quad \forall j\in(1,H) hj(t)=σ(zj(t))=tanh(zj(t))j(1,H)

3、类似于MLP,将 h ( t ) h^{(t)} h(t)层映射到 O ( t ) O^{(t)} O(t)
O k ( t ) = ∑ j = 1 H V k j h j ( t ) + c k ∗ 1 O_k^{(t)} = \sum_{j=1}^{H}{V_{kj}h_j^{(t)}} + c_k*1 Ok(t)=j=1HVkjhj(t)+ck1

  • 这里的公式与MLP中的相同,不再赘述,类似于图中第二层的黑色箭头和灰色箭头。

4、利用 O ( t ) O^{(t)} O(t)得出预测值并写出误差函数:
y ^ k ( t ) = σ ( O k ( t ) ) = s o f t m a x ( O k ( t ) ) ∀ k ∈ ( 1 , C ) \hat{y}_k^{(t)} = \sigma(O_k^{(t)}) = softmax(O_k^{(t)})\quad \forall k\in(1,C) y^k(t)=σ(Ok(t))=softmax(Ok(t))k(1,C)

  • 利用softmax函数得出预测结果,输出向量的维度为C
    E ( ω ) = − ∑ k = 1 C y k ( t ) l n ( y ^ k ( t ) ) E(\omega) = -\sum_{k=1}^C{y_k^{(t)} ln(\hat{y}_k^{(t)})} E(ω)=k=1Cyk(t)ln(y^k(t))
  • 至此,完成前向传播的推导以及误差函数.

RNN的反向传播

1、反向传播至 O ( t ) O^{(t)} O(t)

  • 因为这里的误差函数使用交叉熵、而输出层的激活函数使用的是softmax。所以,误差函数对 O k ( t ) O_k^{(t)} Ok(t)的偏导为:
    ∂ E ( ω ) ∂ O k ( t ) = y ^ k ( t ) ∑ k = 1 C y k ( t ) − y k ( t ) \frac{\partial E(\omega)}{\partial O_k^{(t)}} = \hat{y}_k^{(t)} \sum_{k=1}^C{y_k^{(t)}} - y_k^{(t)} Ok(t)E(ω)=y^k(t)k=1Cyk(t)yk(t)
  • 这个结论来自于另一篇博客,详情见:简单易懂的softmax交叉熵损失函数求导 - Allenlzcoder的博客 - CSDN博客
  • 在上文提到的第一篇博客中推导的公式并不是这样的,这是因为他的假设中这是一个分类问题,所以目标向量的各分量之和应该为1,这里我们也做此假设,简化为:
    ∂ E ( ω ) ∂ O k ( t ) = y ^ k ( t ) − y k ( t ) \frac{\partial E(\omega)}{\partial O_k^{(t)}} = \hat{y}_k^{(t)} - y_k^{(t)} Ok(t)E(ω)=y^k(t)yk(t)

2、求出 c c c , V V V 的各项的梯度:
由上面的前向传播公式:
O k ( t ) = ∑ j = 1 H V k j h j ( t ) + c k ∗ 1 O_k^{(t)} = \sum_{j=1}^{H}{V_{kj}h_j^{(t)}} + c_k*1 Ok(t)=j=1HVkjhj(t)+ck1
可得:
∂ E ( ω ) ∂ V k j = ∂ E ( ω ) ∂ O k ( t )    ∂ O k ( t ) ∂ V k j = ( y ^ k ( t ) − y k ( t ) ) h j ( t ) \frac{\partial E(\omega)}{\partial V_{kj}} = \frac{\partial E(\omega)}{\partial O_k^{(t)}}\;\frac{\partial O_k^{(t)}} {\partial V_{kj}} = (\hat{y}_k^{(t)} - y_k^{(t)})h_j^{(t)} VkjE(ω)=Ok(t)E(ω)VkjOk(t)=(y^k(t)yk(t))hj(t)

∂ E ( ω ) ∂ c k = ∂ E ( ω ) ∂ O k ( t )    ∂ O k ( t ) ∂ c k = ( y ^ k ( t ) − y k ( t ) ) ∗ 1 \frac{\partial E(\omega)}{\partial c_k} = \frac{\partial E(\omega)}{\partial O_k^{(t)}}\;\frac{\partial O_k^{(t)}} {\partial c_k} = (\hat{y}_k^{(t)} - y_k^{(t)})*1 ckE(ω)=Ok(t)E(ω)ckOk(t)=(y^k(t)yk(t))1
但是这样是不完整的,上面说过, c c c , V V V是所有块所共用的权重矩阵,所以需要用所有的 O ( t ) O^{(t)} O(t)进行反向推导。所以,正确的应该为:

∂ E ( ω ) ∂ V k j = ∑ t = 1 τ ∂ E ( ω ) ∂ O k ( t )    ∂ O k ( t ) ∂ V k j = ∑ t = 1 τ ( y ^ k ( t ) − y k ( t ) ) h j ( t ) \frac{\partial E(\omega)}{\partial V_{kj}} = \sum_{t=1}^{\tau}\frac{\partial E(\omega)}{\partial O_k^{(t)}}\;\frac{\partial O_k^{(t)}} {\partial V_{kj}} = \sum_{t=1}^{\tau}(\hat{y}_k^{(t)} - y_k^{(t)})h_j^{(t)} VkjE(ω)=t=1τOk(t)E(ω)VkjOk(t)=t=1τ(y^k(t)yk(t))hj(t)

∂ E ( ω ) ∂ c k = ∑ t = 1 τ ∂ E ( ω ) ∂ O k ( t )    ∂ O k ( t ) ∂ c k = ∑ t = 1 τ ( y ^ k ( t ) − y k ( t ) ) ∗ 1 \frac{\partial E(\omega)}{\partial c_k} = \sum_{t=1}^{\tau}\frac{\partial E(\omega)}{\partial O_k^{(t)}}\;\frac{\partial O_k^{(t)}} {\partial c_k} = \sum_{t=1}^{\tau}(\hat{y}_k^{(t)} - y_k^{(t)})*1 ckE(ω)=t=1τOk(t)E(ω)ckOk(t)=t=1τ(y^k(t)yk(t))1

3、反向传播得出每一层的误差 δ \delta δ
首先定义未激活时的隐藏层的误差 δ j ( t ) \delta_j^{(t)} δj(t)

δ j ( t ) : = ∂ E ( ω ) ∂ z j ( t ) \delta_j^{(t)} := \frac{\partial E(\omega)}{\partial z_j^{(t)}} δj(t):=zj(t)E(ω)

需要注意的是这里的误差来源有两部分:

  • 在第t块作为隐藏层 h ( t ) h^{(t)} h(t) O ( t ) O^{(t)} O(t)处传播来的误差
  • 在第t+1块作为 前一个RNN块的隐藏层 h ( t ) h^{(t)} h(t) h ( t + 1 ) h^{(t+1)} h(t+1)处传来的误差

所以我们需要先研究第 τ \tau τ块,因为最后一块没有来自后一层的误差。在第 τ \tau τ块有:
δ j ( τ ) = ∂ E ( ω ) ∂ z j ( τ ) = ∑ k = 1 C ∂ E ( ω ) ∂ O k ( τ )    ∂ O k ( τ ) ∂ h j ( τ )    ∂ h j ( τ ) ∂ z j ( τ ) = ∑ k = 1 C ( y ^ k ( τ ) − y k ( τ ) ) V k j \delta_j^{(\tau)} = \frac{\partial E(\omega)}{\partial z_j^{(\tau)}} = \sum_{k=1}^C\frac{\partial E(\omega)}{\partial O_k^{(\tau)}}\;\frac{\partial O_k^{(\tau)}} {\partial h_j^{(\tau)}}\;\frac{\partial h_j^{(\tau)}} {\partial z_j^{(\tau)}} =\sum_{k=1}^C(\hat{y}_k^{(\tau)} - y_k^{(\tau)})V_{kj} δj(τ)=zj(τ)E(ω)=k=1COk(τ)E(ω)hj(τ)Ok(τ)zj(τ)hj(τ)=k=1C(y^k(τ)yk(τ))Vkj

现在研究第t块的误差:

δ j ( t ) = ∂ E ( ω ) ∂ z j ( t ) = ∑ k = 1 C ∂ E ( ω ) ∂ O k ( t )    ∂ O k ( t ) ∂ h j ( t )    ∂ h j ( t ) ∂ z j ( t )    +    ∑ j = 1 H ∂ E ( ω ) ∂ z k ( t + 1 )    ∂ z k ( t + 1 ) ∂ h j ( t ) ∂ h j ( t ) ∂ z j ( t ) = ∑ k = 1 C ( y ^ k ( τ ) − y k ( τ ) ) V k j    +    ∑ j = 1 H δ j ( t + 1 ) W j p σ , ( ) \delta_j^{(t)} = \frac{\partial E(\omega)}{\partial z_j^{(t)}} = \sum_{k=1}^C\frac{\partial E(\omega)}{\partial O_k^{(t)}}\;\frac{\partial O_k^{(t)}} {\partial h_j^{(t)}}\;\frac{\partial h_j^{(t)}} {\partial z_j^{(t)}} \;+\; \sum_{j=1}^H\frac{\partial E(\omega)}{\partial z_k^{(t+1)}}\;\frac{\partial z_k^{(t+1)}} {\partial h_j^{(t)}}\frac{\partial h_j^{(t)}} {\partial z_j^{(t)}}=\sum_{k=1}^C(\hat{y}_k^{(\tau)} - y_k^{(\tau)})V_{kj}\;+\; \sum_{j=1}^H \delta_j^{(t+1)}W_{jp}\sigma^,() δj(t)=zj(t)E(ω)=k=1COk(t)E(ω)hj(t)Ok(t)zj(t)hj(t)+j=1Hzk(t+1)E(ω)hj(t)zk(t+1)zj(t)hj(t)=k=1C(y^k(τ)yk(τ))Vkj+j=1Hδj(t+1)Wjpσ,()

其中 σ , ( ) \sigma^,() σ,()表示激活函数tanh的导数

4、求出 b b b , U U U, W W W 的各项的梯度
- δ j ( t ) \delta_j^{(t)} δj(t)求出来后,剩余各项的梯度就比较容易求了,记得需要利用所有块求取梯度

  • 前向传播公式为:
    z j ( t ) = ∑ i = 1 L U j i x i ( t ) + ∑ p = 1 H W j p x p ( t − 1 ) + b j ∗ 1 z_j^{(t)} = \sum_{i=1}^{L}{U_{ji}x_i^{(t)}} + \sum_{p=1}^{H}{W_{jp}x_p^{(t-1)} + b_j*1} zj(t)=i=1LUjixi(t)+p=1HWjpxp(t1)+bj1

  • 相应的反向传播为:
    ∂ E ( ω ) ∂ W j p = ∑ t = 1 τ ∂ E ( ω ) ∂ z j ( t )    ∂ z j ( t ) ∂ W j p = ∑ t = 1 τ δ j ( t ) h p ( t − 1 ) \frac{\partial E(\omega)}{\partial W_{jp}} = \sum_{t=1}^{\tau}\frac{\partial E(\omega)}{\partial z_j^{(t)}}\;\frac{\partial z_j^{(t)}} {\partial W_{jp}} = \sum_{t=1}^{\tau}\delta_j^{(t)}h_p^{(t-1)} WjpE(ω)=t=1τzj(t)E(ω)Wjpzj(t)=t=1τδj(t)hp(t1)

    ∂ E ( ω ) ∂ U j i = ∑ t = 1 τ ∂ E ( ω ) ∂ z j ( t )    ∂ z j ( t ) ∂ U j i = ∑ t = 1 τ δ j ( t ) x i ( t ) \frac{\partial E(\omega)}{\partial U_{ji}} = \sum_{t=1}^{\tau}\frac{\partial E(\omega)}{\partial z_j^{(t)}}\;\frac{\partial z_j^{(t)}} {\partial U_{ji}} = \sum_{t=1}^{\tau}\delta_j^{(t)}x_i^{(t)} UjiE(ω)=t=1τzj(t)E(ω)Ujizj(t)=t=1τδj(t)xi(t)

∂ E ( ω ) ∂ b j = ∑ t = 1 τ ∂ E ( ω ) ∂ z j ( t )    ∂ z j ( t ) ∂ b j = ∑ t = 1 τ δ j ( t ) ∗ 1 \frac{\partial E(\omega)}{\partial b_j} = \sum_{t=1}^{\tau}\frac{\partial E(\omega)}{\partial z_j^{(t)}}\;\frac{\partial z_j^{(t)}} {\partial b_j} = \sum_{t=1}^{\tau}\delta_j^{(t)}*1 bjE(ω)=t=1τzj(t)E(ω)bjzj(t)=t=1τδj(t)1

至此,RNN的反向传播公式推导完毕。

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
RNN(循环神经网络)是一种能够处理序列数据的神经网络模型。它通过自循环的方式将前一时刻的隐藏状态信息传递给下一时刻,以此来建模序列中的时序关系。 RNN反向传播算法主要包含以下几个步骤: 1. 初始化:首先,我们需要初始化模型的参数,包括权重和偏置。这些参数会在反向传播过程中根据损失函数来进行调整。 2. 前向传播:在反向传播之前,我们需要先进行一次前向传播。假设我们有一个包含T个时刻的序列数据,每个时刻的输入是一个D维的向量,隐藏状态的维度为H。对于每个时刻t,我们先计算当前时刻的隐藏状态,根据当前时刻的输入数据和前一时刻的隐藏状态: ht = activation(Wx * Xt + Wh * ht-1 + b) 其中,Wx和Wh分别是输入与隐藏状态之间的权重矩阵,b是偏置项,activation是激活函数。 3. 计算损失函数:根据预测结果和真实结果计算损失函数,常见的损失函数包括均方差误差和交叉熵等。损失函数衡量了模型的预测与真实结果之间的差距。 4. 反向传播:在RNN中,由于隐藏状态之间存在时序关系,我们需要考虑到每个时刻的梯度对前一时刻的梯度的影响。首先,我们计算当前时刻的梯度: dht = dout + dht+1 其中,dout是损失函数对当前时刻的输出的导数。然后,我们利用当前时刻的梯度来计算当前时刻的权重矩阵和偏置项的梯度: dWx += Xt * dht dWh += ht-1 * dht db += dht 接下来,我们计算对前一时刻隐藏状态的梯度: dht-1 = Wh * dht 最后,我们利用当前时刻的梯度和前一时刻的梯度来计算损失函数对输入的导数: dXt = Wx * dht + dXt+1 这样就完成了一个时刻的反向传播。重复以上步骤,可以依次计算每个时刻的梯度,从而完成整个反向传播的过程。 5. 更新参数:最后,利用计算得到的梯度信息更新模型的参数。采用梯度下降法,通过调整参数,使得损失函数尽可能地减小。 总结起来,RNN反向传播算法通过自循环的方式将梯度从当前时刻传递到前一时刻,并利用当前时刻和前一时刻的梯度来计算参数的梯度,然后通过梯度下降法来更新参数,从而优化模型。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值