赞
踩
前馈神经网络可以看作一个复杂的函数,每次输入都是独立的,即网络的输出只依赖于当前的输入。但是在很多现实任务中,网络的输出不仅和当前时刻的输入相关,也和其过去一段时间的输出相关。比如一个有限状态自动机,其下一个时刻的状态(输出)不仅仅和当前输入相关,也和当前状态(上一个时刻的输出)相关。此外,前馈网络难以处理时序数据,比如视频、语音、文本等。时序数据的长度一般是不固定的,而前馈神经网络要求输入和输出的维数都是固定的,不能任意改变。
循环神经网络是一类具有短期记忆能力的神经网络。在循环神经网络中,神经元不但可以接受其他神经元的信息,也可以接受自身的信息,形成具有环路的网络结构。循环神经网络的参数学习可以通过随时间反向传播算法来学习,即按照时间的逆序将错误信息一步步地往前传递,当输入序列比较长时,会存在梯度爆炸和消失问题,也称为长程依赖问题,为了解决这个问题,人们对循环神经网络进行了很多的改进,其中最有效的改进方式引入门控机制(Gating Mechanism)。
循环神经网络可以很容易地扩展到两种更广义的记忆网络模型:递归神经网络和图网络。
词性标注问题可以看作一个分类问题:为每个单词进行分类,分类标记为词性类别。倘若使用前馈神经网络解决这个分类问题,
但是同一个词在不同的语义下的词性不同,需要考虑前后上下文来做消歧(有限上下文VS无限上下文),循环神经网络引入“记忆功能”,将隐藏层的值存储起来,存储值可以用于作为一个输入。
下图是最简单的循环神经网络:在每一个时间步
t
t
t,由一个循环神经元接收输入
x
t
x_{t}
xt和它自己前一个时间步的输出
h
t
−
1
h_{t-1}
ht−1,将输出一方面发送回自己,一方面传给输出神经元。
{
a
t
=
w
x
x
t
+
w
h
h
t
−
1
+
b
h
h
t
=
g
(
a
t
)
s
t
=
w
o
h
t
+
b
o
o
t
=
o
(
s
t
)
其中, g , o g,o g,o分别为隐藏层和输出层的激活函数,均为标量函数。
BPTT算法的主要思想是通过类似前馈神经网络的错误反向传播算法来计算梯度,将循环神经网络看作一个展开的多层前馈网络,其中“每一层”对应循环神经网络中的“每个时刻”。这样,循环神经网络就可以按照前馈网络中的反向传播算法计算参数梯度。另外,由于在“展开”的前馈网络中,所有层的参数是共享的,因此参数的真实梯度是所有“展开层”的参数梯度之和。
给定长度为
T
T
T的训练样本
(
x
,
y
)
(x,y)
(x,y),设
L
L
L为可微分的损失函数,定义时刻
t
t
t的损失函数为
L
t
=
L
(
y
t
,
o
t
)
L_t=\mathcal{L}(y_t,o_t)
Lt=L(yt,ot)
考虑整个序列的损失函数为每个时刻损失函数的累加和,
L
=
∑
t
=
1
T
L
t
L=\sum_{t=1}^TL_t
L=t=1∑TLt
整个序列的损失函数
L
L
L关于任一参数
w
w
w的梯度为每个时刻损失
L
t
L_t
Lt对参数
w
w
w的梯度,
∂
L
∂
w
=
∑
t
=
1
T
∂
L
t
∂
w
\frac{\partial L}{\partial w}=\sum_{t=1}^T\frac{\partial L_t}{\partial w}
∂w∂L=t=1∑T∂w∂Lt
知识准备:
维度声明:
变量 | 维度 | 变量 | 维度 |
---|---|---|---|
x t x_t xt | n x × 1 n_x\times1 nx×1 | w x w_x wx | n h × n x n_h\times n_x nh×nx |
h t , a t h_t,a_t ht,at | n h × 1 n_h\times1 nh×1 | w h w_h wh | n h × n h n_h\times n_h nh×nh |
o t , s t o_t,s_t ot,st | n o × 1 n_o\times1 no×1 | w o w_o wo | n o × n h n_o\times n_h no×nh |
L t L_t Lt | 1 × 1 1\times1 1×1 | b h b_h bh | n h × 1 n_h\times1 nh×1 |
b o b_o bo | n o × 1 n_o\times1 no×1 |
1. 任意时刻 t t t的损失函数 L t L_t Lt对参数 w o , b o w_o,b_o wo,bo的偏导: w o / b o → s t → o t → L t w_o/b_o\rightarrow s_t\rightarrow o_t \rightarrow L_t wo/bo→st→ot→Lt
∂ L t ∂ b o = ( ∂ o t ∂ s t ∂ s t ∂ b o ) T ∂ L t ∂ o t = d i a g ( o ′ ( s t ) ) ∂ L t ∂ o t \frac{\partial L_t}{\partial b_o}=(\frac{\partial o_t}{\partial s_t}\frac{\partial s_t}{\partial b_o})^T\frac{\partial L_t}{\partial o_t}=diag(o'(s_t))\frac{\partial L_t}{\partial o_t} ∂bo∂Lt=(∂st∂ot∂bo∂st)T∂ot∂Lt=diag(o′(st))∂ot∂Lt
其中,
o
′
(
s
t
)
o'(s_t)
o′(st)是标量函数分别作用于向量
s
t
s_t
st的每一维得到的向量,
d
i
a
g
(
o
′
(
s
t
)
)
diag(o'(s_t))
diag(o′(st))是以向量为
o
′
(
s
t
)
o'(s_t)
o′(st)为对角线元素的矩阵。记
w
o
,
i
j
w_{o,ij}
wo,ij为
w
o
w_o
wo的第
i
i
i行第
j
j
j列元素,
∂
L
t
∂
w
o
,
i
j
=
(
∂
o
t
∂
s
t
∂
s
t
∂
w
o
,
i
j
)
T
∂
L
t
∂
o
t
=
(
h
t
,
j
)
i
T
d
i
a
g
(
o
′
(
s
t
)
)
∂
L
t
∂
o
t
\frac{\partial L_t}{\partial w_{o,ij}}=(\frac{\partial o_t}{\partial s_t}\frac{\partial s_t}{\partial w_{o,ij}})^T\frac{\partial L_t}{\partial o_t}=(h_{t,j})_i^Tdiag(o'(s_t))\frac{\partial L_t}{\partial o_t}
∂wo,ij∂Lt=(∂st∂ot∂wo,ij∂st)T∂ot∂Lt=(ht,j)iTdiag(o′(st))∂ot∂Lt
其中
(
h
t
,
j
)
i
(h_{t,j})_i
(ht,j)i为第
i
i
i行为
h
t
h_t
ht的第
j
j
j个元素
h
t
,
j
h_{t,j}
ht,j,其余元素为0的
n
o
×
1
n_o\times1
no×1向量。写成矩阵形式,
∂
L
t
∂
w
o
=
d
i
a
g
(
o
′
(
s
t
)
)
∂
L
t
∂
o
t
h
t
T
\frac{\partial L_t}{\partial w_{o}}=diag(o'(s_t))\frac{\partial L_t}{\partial o_t}h_t^T
∂wo∂Lt=diag(o′(st))∂ot∂LthtT
2. 任意时刻
t
t
t的损失函数
L
t
L_t
Lt对参数
w
h
w_h
wh的偏导
因为参数
w
h
w_h
wh和隐藏层在每一个时刻
k
(
1
≤
k
≤
t
)
k(1\leq k\leq t)
k(1≤k≤t)的净输入
a
k
=
w
x
x
k
+
w
h
h
k
−
1
+
b
h
a_k=w_{x}x_k+w_{h}h_{k-1}+b_h
ak=wxxk+whhk−1+bh有关,可写
L
t
(
a
1
(
w
h
)
,
a
2
(
w
h
)
,
.
.
.
,
a
t
(
w
h
)
)
L_t(a_1(w_h),a_2(w_h),...,a_t(w_h))
Lt(a1(wh),a2(wh),...,at(wh)),由多元复合函数求导的链式法则,第
t
t
t时刻的损失函数
L
t
L_t
Lt关于参数
w
h
,
i
j
w_{h,ij}
wh,ij的梯度为,
∂
L
t
∂
w
h
,
i
j
=
∑
k
=
1
t
(
∂
a
k
∂
w
h
,
i
j
)
T
∂
L
t
∂
a
k
=
∑
k
=
1
t
(
h
k
−
1
,
j
)
i
T
∂
L
t
∂
a
k
=
∑
k
=
1
t
h
k
−
1
,
j
(
δ
t
,
k
)
i
\frac{\partial L_t}{\partial w_{h,ij}}=\sum_{k=1}^t(\frac{\partial a_k}{\partial w_{h,ij}})^T\frac{\partial L_t}{\partial a_k}=\sum_{k=1}^t(h_{k-1,j})_i^T\frac{\partial L_t}{\partial a_k}=\sum_{k=1}^th_{k-1,j}(\delta_{t,k})_i
∂wh,ij∂Lt=k=1∑t(∂wh,ij∂ak)T∂ak∂Lt=k=1∑t(hk−1,j)iT∂ak∂Lt=k=1∑thk−1,j(δt,k)i
其中,误差项
δ
t
,
k
=
∂
L
t
∂
a
k
\delta_{t,k}=\frac{\partial L_t}{\partial a_k}
δt,k=∂ak∂Lt,由
a
k
→
h
k
→
a
k
+
1
→
L
t
a_k\rightarrow h_k\rightarrow a_{k+1} \rightarrow L_t
ak→hk→ak+1→Lt
δ
t
,
k
=
∂
L
t
∂
a
k
=
(
∂
a
k
+
1
∂
h
k
∂
h
k
∂
a
k
)
T
∂
L
t
∂
a
k
+
1
=
d
i
a
g
(
g
′
(
a
k
)
)
w
h
T
δ
t
,
k
+
1
\delta_{t,k}=\frac{\partial L_t}{\partial a_k}=(\frac{\partial a_{k+1}}{\partial h_k}\frac{\partial h_k}{\partial a_k})^T\frac{\partial L_t}{\partial a_{k+1}}=diag(g'(a_k))w_h^T\delta_{t,k+1}
δt,k=∂ak∂Lt=(∂hk∂ak+1∂ak∂hk)T∂ak+1∂Lt=diag(g′(ak))whTδt,k+1
写成矩阵形式,
∂
L
t
∂
w
h
=
∑
k
=
1
t
∂
L
t
∂
a
k
∂
a
k
∂
w
h
=
∑
k
=
1
t
δ
t
,
k
h
k
−
1
T
\frac{\partial L_t}{\partial w_h}=\sum_{k=1}^t\frac{\partial L_t}{\partial a_k}\frac{\partial a_k}{\partial w_h}=\sum_{k=1}^t\delta_{t,k}h_{k-1}^T
∂wh∂Lt=k=1∑t∂ak∂Lt∂wh∂ak=k=1∑tδt,khk−1T
3. 任意时刻 t t t的损失函数 L t L_t Lt对参数 w x , b h w_x,b_h wx,bh的偏导
∂ L t ∂ w x = ∑ k = 1 t ∂ L t ∂ a k ∂ a k ∂ w x = ∑ k = 1 t δ t , k x k T \frac{\partial L_t}{\partial w_x}=\sum_{k=1}^t\frac{\partial L_t}{\partial a_k}\frac{\partial a_k}{\partial w_x}=\sum_{k=1}^t\delta_{t,k}x_k^T ∂wx∂Lt=k=1∑t∂ak∂Lt∂wx∂ak=k=1∑tδt,kxkT
∂ L t ∂ b h = ∑ k = 1 t δ t , k \frac{\partial L_t}{\partial b_h}=\sum_{k=1}^t\delta_{t,k} ∂bh∂Lt=k=1∑tδt,k
在BPTT算法中,
δ
t
,
k
=
d
i
a
g
(
g
′
(
a
k
)
)
w
h
T
δ
t
,
k
+
1
=
∏
τ
=
k
t
−
1
(
d
i
a
g
(
g
′
(
a
τ
)
)
w
h
T
)
δ
t
,
t
\delta_{t,k}=diag(g'(a_k))w_h^T\delta_{t,k+1}=\prod_{\tau=k}^{t-1}\left(diag(g'(a_\tau))w_h^T\right)\delta_{t,t}
δt,k=diag(g′(ak))whTδt,k+1=τ=k∏t−1(diag(g′(aτ))whT)δt,t
由于循环神经网络经常使用Logistic函数或Tanh函数作为非线性激活函数,其导数值都小于1。
梯度消失/爆炸指的是梯度
∂
L
t
∂
a
k
\frac{\partial L_t}{\partial a_k}
∂ak∂Lt消失/爆炸,即使选择一个合适的激活函数,梯度
∂
L
t
∂
h
k
\frac{\partial L_t}{\partial h_k}
∂hk∂Lt也可能会出现梯度消失/爆炸,因为是一个连乘积。RNN 中总的梯度是不会消失的,RNN 所谓梯度消失的真正含义是,梯度被近距离梯度主导,导致模型难以学到远距离的依赖关系。(LSTM如何解决梯度消失问题)
注:使用ReLU代替Sigmoid函数的效果通常比较差(A Simple Way to Initialize Recurrent Networks of Rectified Linear Units)
虽然简单循环网络理论上可以建立长时间间隔的状态之间的依赖关系,但是由于梯度爆炸或消失问题,实际上只能学习到短期的依赖关系。这样,如果时刻 t t t 的输出 y t y_t yt依赖于时刻 k k k的输入 x k x_k xk,当间隔 t − k t-k t−k 比较大时,简单神经网络很难建模这种长距离的依赖关系,称为长程依赖问题(Long-Term DependenciesProblem)。
改进梯度爆炸或梯度消失
为了避免梯度爆炸或消失问题,一种最直接的方式就是选取合适的参数,尽量使得
d
i
a
g
(
g
′
(
a
τ
)
)
w
h
T
≈
1
diag(g'(a_\tau))w_h^T\approx1
diag(g′(aτ))whT≈1,这种方式需要足够的人工调参经验,限制了模型的广泛应用。比较有效的方式是通过改进模型或优化方法来缓解循环网络的梯度爆炸和梯度消失问题。
当前信息可能不只与前一时刻信息相关,还与下一时刻信息相关。
为了改善循环神经网络的长程依赖问题,一种非常好的解决方案是引入门控机制来控制信息的累积速度:有选择地加入新的信息,并有选择的遗忘之前累积的信息。
长短期记忆网络是循环神经网络的一个变体,可以在一定程度上缓解循环神经网络的梯度爆炸或消失问题。
LSTM循环神经元
1. 门控机制
在数字电路中,门(gate)为一个二值变量
{
0
,
1
}
\{0, 1\}
{0,1},0 代表关闭状态,不许任何信息通过;1 代表开放状态,允许所有信息通过。LSTM 网络引入门控机制来控制信息传递的路径:
LSTM 网络中的“门”是一种“软”门,取值在
(
0
,
1
)
(0, 1)
(0,1) 之间,表示以一定的比例允许信息通过。
{
i
t
=
σ
(
W
i
x
t
+
U
i
h
t
−
1
+
b
i
)
f
t
=
σ
(
W
f
x
t
+
U
f
h
t
−
1
+
b
f
)
o
t
=
σ
(
W
o
x
t
+
U
o
h
t
−
1
+
b
o
)
2. 新的内部状态
LSTM引入一个新的内部状态
c
t
c_t
ct专门进行线性的循环信息传递,同时非线性地输出信息给隐藏层的外部状态
h
t
h_t
ht。
{
c
~
t
=
t
a
n
h
(
W
c
x
t
+
U
c
h
t
−
1
+
b
c
)
c
t
=
f
t
⊙
c
t
−
1
+
i
t
⊙
c
~
t
h
t
=
o
t
⊙
t
a
n
h
(
c
t
)
其中 c ~ t \tilde{c}_t c~t是通过非线性函数得到的候选状态。
1. 无遗忘门的LSTM 网络
最早提出的LSTM 网络是没有遗忘门的,其内部状态的更新为,
c
t
=
c
t
−
1
+
i
t
⊙
c
~
t
c_t= c_{t-1}+i_t\odot\tilde{c}_t
ct=ct−1+it⊙c~t
记忆单元 c c c没有门控限制,会不断增大.当输入序列的长度非常大时,记忆单元的容量会饱和,大大降低LSTM 模型的性能。
2. peephole连接
三个门不但依赖于输入
x
t
x_t
xt和上一时刻的隐状态
h
t
−
1
h_{t-1}
ht−1,也依赖于上一个时刻的记忆单元
c
t
−
1
c_{t-1}
ct−1,即
{
i
t
=
σ
(
W
i
x
t
+
U
i
h
t
−
1
+
V
i
c
t
−
1
+
b
i
)
f
t
=
σ
(
W
f
x
t
+
U
f
h
t
−
1
+
V
f
c
t
−
1
+
b
f
)
o
t
=
σ
(
W
o
x
t
+
U
o
h
t
−
1
+
V
o
c
t
−
1
+
b
o
)
其中
V
i
,
V
f
,
V
o
V_i,V_f,V_o
Vi,Vf,Vo为对角矩阵。
3. 耦合输入门和遗忘门
LSTM 网络中的输入门和遗忘门有些互补关系,因此同时用两个门比较冗余.为了减少LSTM 网络的计算复杂度,将这两门合并为一个门.令
f
t
=
1
−
i
t
f_t = 1 − i_t
ft=1−it,内部状态的更新方式为
c
t
=
(
1
−
i
t
)
⊙
c
t
−
1
+
i
t
⊙
c
~
t
c_t=(1-i_t)\odot c_{t-1}+i_t\odot \tilde{c}_t
ct=(1−it)⊙ct−1+it⊙c~t
LSTM在一定程度上缓解梯度消失问题
前面介绍RNN时有说明,RNN的梯度消失问题中的梯度是指损失函数
L
t
L_t
Lt关于“记忆”
h
h
h 的梯度。类似地,在LSTM中,我们考虑损失函数
L
t
L_t
Lt关于长短期记忆
c
c
c 的梯度,在路径
c
1
→
c
2
→
.
.
.
→
c
t
=
f
t
⊙
c
t
−
1
+
i
t
⊙
c
~
t
c_{1}\rightarrow c_2\rightarrow ...\rightarrow c_t=f_t\odot c_{t-1}+i_t\odot\tilde{c}_t
c1→c2→...→ct=ft⊙ct−1+it⊙c~t,有
δ
k
=
∂
L
t
∂
c
k
=
(
∂
c
k
+
1
∂
c
k
)
T
∂
L
t
∂
c
k
+
1
=
(
f
k
+
i
k
⊙
∂
c
~
k
+
1
∂
c
k
)
T
δ
k
+
1
=
∏
τ
=
k
t
−
1
(
f
τ
+
i
τ
⊙
∂
c
~
τ
+
1
∂
c
τ
)
T
δ
t
\delta_k=\frac{\partial L_t}{\partial c_k}=(\frac{\partial c_{k+1}}{\partial c_k})^T\frac{\partial L_t}{\partial c_{k+1}}=(f_k+i_k\odot \frac{\partial \tilde{c}_{k+1}}{\partial c_k})^T\delta_{k+1}=\prod_{\tau=k}^{t-1}(f_\tau+i_\tau\odot \frac{\partial \tilde{c}_{\tau+1}}{\partial c_\tau})^T\delta_{t}
δk=∂ck∂Lt=(∂ck∂ck+1)T∂ck+1∂Lt=(fk+ik⊙∂ck∂c~k+1)Tδk+1=τ=k∏t−1(fτ+iτ⊙∂cτ∂c~τ+1)Tδt
当 i τ ⊙ ∂ c ~ τ + 1 ∂ c τ i_\tau\odot \frac{\partial \tilde{c}_{\tau+1}}{\partial c_\tau} iτ⊙∂cτ∂c~τ+1很小时,如果 f t = 1 f_t=1 ft=1,门控保留记忆,连乘的项在1附近的,可以保证在一个很长的时间内不会出现梯度消失,如果 f t = 0 f_t=0 ft=0,门控清除记忆,这一项也会为0;但当 i τ ⊙ ∂ c ~ τ + 1 ∂ c τ i_\tau\odot \frac{\partial \tilde{c}_{\tau+1}}{\partial c_\tau} iτ⊙∂cτ∂c~τ+1很大时,不可避免出现梯度爆炸问题。
通俗地讲,RNN中,每个记忆单元 h t − 1 h_{t-1} ht−1都会乘上一个 W W W和激活函数的导数,这种连乘使得记忆衰减的很快,而LSTM是通过记忆和当前输入"相加",使得之前的记忆会继续存在而不是受到乘法的影响而部分“消失”,因此不会衰减。(理解RNN梯度消失和弥散以及LSTM为什么能解决)
LSTM如何解决梯度消失问题
当我们在谈论 Deep Learning:RNN 其常见架构
GRU网络是一种比LSTM网络更加简单的循环神经网络。GRU同样引入门控机制来控制信息更新的方式,不同的是,GRU没有引入额外的记忆单元,
{
z
t
=
σ
(
W
z
x
t
+
U
z
h
t
−
1
+
b
z
)
r
t
=
σ
(
W
r
x
t
+
U
r
h
t
−
1
+
b
r
)
{
h
~
t
=
g
(
x
t
,
h
t
−
1
;
θ
)
=
t
a
n
h
(
W
h
x
t
+
U
h
(
r
t
⊙
h
t
−
1
)
+
b
h
)
h
t
=
z
t
⊙
h
t
−
1
+
(
1
−
z
t
)
⊙
h
~
t
当 z t = 0 , r t = 1 z_t=0,r_t=1 zt=0,rt=1 时,GRU 网络退化为简单循环网络;若 z t = 0 , r t = 0 z_t=0,r_t=0 zt=0,rt=0 时,当前状态 h t h_t ht 只和当前输入 x t x_t xt 相关,和历史状态 h t − 1 h_{t-1} ht−1 无关.当 z t = 1 z_t=1 zt=1 时,当前状态 h t = h t − 1 h_t=h_{t-1} ht=ht−1 等于上一时刻状态 h t − 1 h_{t-1} ht−1,和当前输入 x t x_t xt 无关。
李宏毅2020机器学习深度学习
【深度学习】循环神经网络和LSTM
《神经网络与深度学习》
《深度学习》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。