RNN与其反向传播算法——BPTT(Backward Propogation Through Time)的详细推导

前言

  • 一点感悟: 前几天简单看了下王者荣耀觉悟AI的论文,发现除了强化学习以外,也用到了熟悉的LSTM。之后我又想起了知乎上的一个问题:“Transformer会彻底取代RNN吗?”。我想,在觉悟AI这类严格依赖于时间(比如:每读一帧,就要立即进行相应的决策) 的情境中,就根本没法用Transformer这类基于self-attention的模型。因为self-attention的独特性使其必须在一开始就知道所有时间位置的信息,Transformer在NLP上的成功,我觉得还是因为自然语言并不算是严格依赖于时间的。因为我们在数据中看到的句子都是完整的一句话,这就方便了self-attention直接对每个位置进行建模。
  • 所以,Transformer是不可能彻底取代RNN的。当然这只是我的一点思考,还有其他重要的原因:比如Transformer、Bert这种基于self-attention结构的预训练模型都需要海量的训练数据。在数据量不足的情景,只会带来巨大的偏差,但相同的数据在RNN甚至LSTM上已经可以达到足够好的效果。
  • 所以,RNN及其变种是永恒的经典,有必要认真学习。遂推导了一下RNN的反向传播算法(BPTT),记录在此。

1 RNN模型结构及符号定义

1.1 模型结构

假设有一个时间序列 t = 1 , 2 , . . . , L t=1,2,...,L t=1,2,...,L,在每一时刻 t t t我们有:

z ( t ) = U x ( t ) + W h ( t − 1 ) + b h ( t ) = f ( z ( t ) ) s ( t ) = V h ( t ) + c y ( t ) = g ( s ( t ) ) \begin{aligned} \bm{z^{(t)}}&=\bm{Ux^{(t)}}+\bm{Wh^{(t-1)}}+\bm{b}\\ \bm{h^{(t)}}&=f(\bm{z^{(t)}})\\ \bm{s^{(t)}}&=\bm{Vh^{(t)}}+\bm{c}\\ \bm{y^{(t)}}&=g(\bm{s^{(t)}}) \end{aligned} z(t)h(t)s(t)y(t)=Ux(t)+Wh(t1)+b=f(z(t))=Vh(t)+c=g(s(t))

这就是RNN的结构。可以看到,每一时刻 t t t隐含状态 h ( t ) \bm{h^{(t)}} h(t) 都是由当前时刻的输入 x ( t ) \bm{x^{(t)}} x(t)上一时刻的隐含状态 h ( t − 1 ) \bm{h^{(t-1)}} h(t1) 共同得到的。下面是详细的符号定义:

1.2 符号定义

符号 含义 维度
x ( t ) \bm{x^{(t)}} x(t) t t t时刻的输入 ( K × 1 ) (K\times 1) (K×1)
z ( t ) \bm{z^{(t)}} z(t) t t t时刻隐层的带权输入 ( N × 1 ) (N\times 1) (N×1)
h ( t ) \bm{h^{(t)}} h(t) t t t时刻的隐含状态 ( N × 1 ) (N\times 1) (N×1)
s ( t ) \bm{s^{(t)}} s(t) t t t时刻输出层的带权输入 ( M × 1 ) (M \times 1) (M×1)
y ( t ) \bm{y^{(t)}} y(t) t t t时刻的输出 ( M × 1 ) (M\times 1) (M×1)
E ( t ) E^{(t)} E(t) t t t时刻的损失 标量
U \bm{U} U 隐层对输入的参数,整个模型共享 ( N × K ) (N\times K) (N×K)
W \bm{W} W 隐层对状态的参数,整个模型共享 ( N × N ) (N\times N) (N×N)
V \bm{V} V 输出层参数,整个模型共享 ( M × N ) (M\times N) (M×N)
b \bm{b} b 隐层的偏置,整个模型共享 ( N × 1 ) (N\times 1) (N×1)
c \bm{c} c 输出层偏置,整个模型共享 ( M × 1 ) (M\times 1) (M×1)
g ( ) g() g() 输出层激活函数 \
f ( ) f() f() 隐层的激活函数 \

2 沿时间的反向传播算法

2.1 总体分析

首先快速总览一下RNN的全部流程。

  1. 首先令模型的隐含状态 h ( 0 ) = 0 \bm{h^{(0)}=0} h(0)=0
  2. 每一时刻 t \bm{t} t输入 x ( t ) \bm{x^{(t)}} x(t) 都是一个向量(比如:在NLP中,可以使用词向量),在经过模型后会得到这一时刻的状态 h ( t ) \bm{h^{(t)}} h(t)输出 y ( t ) \bm{y^{(t)}} y(t)
  3. 在NLP中, y ( t ) \bm{y^{(t)}} y(t)是由 s ( t ) \bm{s^{(t)}} s(t)经过 g g g (通常为Softmax) 激活得到的,搭配Cross Entropy Loss (比如:在词表中挑选下一个单词,这是一个多分类问题) ,就能计算出此刻的损失 E ( t ) E^{(t)} E(t)
  4. 计算出 E ( t ) E^{(t)} E(t)后,并不能立即对模型参数进行更新。需要沿着时间 t t t不断给出输入,计算出所有时刻的损失。模型总损失为 E = ∑ t E ( t ) E=\sum_tE^{(t)} E=tE(t)
  5. 我们需要根据总损失 E E E计算所有参数的梯度 ∂ E ∂ U , ∂ E ∂ W , ∂ E ∂ V , ∂ E ∂ b , ∂ E ∂ c \frac{\partial E}{\partial \bm{U}},\frac{\partial E}{\partial \bm{W}},\frac{\partial E}{\partial \bm{V}},\frac{\partial E}{\partial \bm{b}},\frac{\partial E}{\partial \bm{c}} UE,WE,VE,bE,cE,再使用基于梯度的优化方法进行参数更新。

这就是一轮完整的流程,本文要讨论的就是:如何计算RNN模型参数的梯度。

2.2 求 ∂ E ∂ V \frac{\partial E}{\partial \bm{V}} VE

∂ E ∂ V = ∑ t ∂ E ( t ) ∂ V \frac{\partial E}{\partial \bm{V}}=\sum_t\frac{\partial E^{(t)}}{\partial \bm{V}} VE=tVE(t)

由公式 s ( t ) = V h ( t ) + c \bm{s^{(t)}}=\bm{Vh^{(t)}}+\bm{c} s(t)=Vh(t)+c y ( t ) = g ( s ( t ) ) \bm{y^{(t)}}=g(\bm{s^{(t)}}) y(t)=g(s(t)),很容易有:

∂ E ( t ) ∂ V i j = ∂ E ( t ) ∂ s i ( t ) ∂ s i ( t ) ∂ V i j = ∂ E ( t ) ∂ y i ( t ) ∂ y i ( t ) ∂ s i ( t ) ∂ s i ( t ) ∂ V i j = ∂ E ( t ) ∂ y i ( t ) g ′ ( s i ( t ) ) h j ( t ) (a) \begin{aligned} \frac{\partial E^{(t)}}{\partial V_{ij}}&=\frac{\partial E^{(t)}}{\partial s_i^{(t)}}\frac{\partial s_i^{(t)}}{\partial V_{ij}}\tag{a}\\ &=\frac{\partial E^{(t)}}{\partial y_i^{(t)}}\frac{\partial y_i^{(t)}}{\partial s_i^{(t)}}\frac{\partial s_i^{(t)}}{\partial V_{ij}}\\ &=\frac{\partial E^{(t)}}{\partial y_i^{(t)}}g'(s_i^{(t)})h_j^{(t)} \end{aligned} VijE(t)=si(t)E(t)Vijsi(t)=yi(t)E(t)si(t)yi(t)V

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值