RNN 反向传播公式推导(非矩阵式)
因为模式识别非要用Latex来编辑公式,所以逼着我写一次博客。嗯,说不定这是一个很好的开始。因为笔者的水平有限,所以如果有不慎有疏漏,烦请不吝赐教。
参考的博客是:
循环神经网络(RNN)模型与前向反向传播算法 - 刘建平Pinard - 博客园
Markdown中数学公式整理 - Zhakel日常 - CSDN博客
关于RNN的基础知识和反向传播的定义就不再赘述,这不是本篇博客所要讲的重点。如果你感觉自己对RNN有一定了解而且至少已经知道三层神经网络反向传播怎么推导了之后,再来看这个比较合适。
RNN模型的可视化
(好像图有点丑)
参数解释:
- 前一个RNN块的隐藏层: h ( t − 1 ) h^{(t-1)} h(t−1),维度为H(在图中表示为H个节点)选取 h p ( t − 1 ) h_p^{(t-1)} hp(t−1)作为研究节点。
- 输入向量(输入层): 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(t−1)到 h ( t ) h^{(t)} h(t)的矩阵记为 W W W, 选取 W j p W_{jp} Wjp 为研究权重,表示从 h p ( t − 1 ) h_p^{(t-1)} hp(t−1)指向 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(t−1)层和
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=1∑LUjixi(t)+p=1∑HWjpxp(t−1)+bj∗1
- 如图中的第一层的三个黑色箭头所示,其中黑色的箭头指求和中的项,所有的灰色箭头共同组成求和;每一个节点都如此连接与计算。
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=1∑HVkjhj(t)+ck∗1
- 这里的公式与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=1∑Cyk(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=1∑Cyk(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=1∑HVkjhj(t)+ck∗1
可得:
∂
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)}
∂Vkj∂E(ω)=∂Ok(t)∂E(ω)∂Vkj∂Ok(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
∂ck∂E(ω)=∂Ok(t)∂E(ω)∂ck∂Ok(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)} ∂Vkj∂E(ω)=t=1∑τ∂Ok(t)∂E(ω)∂Vkj∂Ok(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 ∂ck∂E(ω)=t=1∑τ∂Ok(t)∂E(ω)∂ck∂Ok(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=1∑C∂Ok(τ)∂E(ω)∂hj(τ)∂Ok(τ)∂zj(τ)∂hj(τ)=k=1∑C(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=1∑C∂Ok(t)∂E(ω)∂hj(t)∂Ok(t)∂zj(t)∂hj(t)+j=1∑H∂zk(t+1)∂E(ω)∂hj(t)∂zk(t+1)∂zj(t)∂hj(t)=k=1∑C(y^k(τ)−yk(τ))Vkj+j=1∑Hδ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=1∑LUjixi(t)+p=1∑HWjpxp(t−1)+bj∗1 -
相应的反向传播为:
∂ 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)} ∂Wjp∂E(ω)=t=1∑τ∂zj(t)∂E(ω)∂Wjp∂zj(t)=t=1∑τδj(t)hp(t−1)∂ 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)} ∂Uji∂E(ω)=t=1∑τ∂zj(t)∂E(ω)∂Uji∂zj(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 ∂bj∂E(ω)=t=1∑τ∂zj(t)∂E(ω)∂bj∂zj(t)=t=1∑τδj(t)∗1
至此,RNN的反向传播公式推导完毕。