一、RNN
1、RNN网络结构
(1)
x
t
\displaystyle x_{t}
xt 是时间
t
t
t处的输入
(2)
s
t
\displaystyle s_{t}
st是时间
t
t
t处的记忆,
s
t
=
f
(
U
x
t
+
W
s
t
−
1
)
\displaystyle s_{t\ } \ =\ f( Ux_{t} +Ws_{t-1})
st = f(Uxt+Wst−1),
f
f
f是一个非线性变换函数,可以是tanh\relu\sigmoid等,一般使用tanh。
(3)
h
t
\displaystyle h_{t\ }
ht 是时间t的输出,比如预测下一个词的话,可能是softmax输出的属于每个候选词的概率,
h
t
=
s
o
f
t
m
a
x
(
V
s
t
)
\displaystyle h_{t\ } = softmax(Vs_{t})
ht =softmax(Vst)。eg:
V
s
t
Vs_{t}
Vst输出(1,5,6)–>softmax–>(
e
1
e
1
+
e
5
+
e
6
\displaystyle \frac{e^{1}}{e^{1} +e^{5} +e^{6}}
e1+e5+e6e1,
e
5
e
1
+
e
5
+
e
6
\displaystyle \frac{e^{5}}{e^{1} +e^{5} +e^{6}}
e1+e5+e6e5,
e
6
e
1
+
e
5
+
e
6
\displaystyle \frac{e^{6}}{e^{1} +e^{5} +e^{6}}
e1+e5+e6e6)。如果有N个词,则
x
t
\displaystyle x_{t}
xt 是一个N维向量,那么输出的N个概率,哪个大,就预测为哪个词。
2、RNN网络结构解析:
(1)可以把隐状态(记忆细胞)
s
t
\displaystyle s_{t}
st视为“记忆体”,捕捉了之前时间点上的信息。
(2)输出
h
t
\displaystyle h_{t\ }
ht 由当前时间
x
t
\displaystyle x_{t}
xt 及之前的“记忆”
s
t
−
1
\displaystyle s_{t-1}
st−1共同计算得到。
(3)
s
t
\displaystyle s_{t}
st不能捕捉和保留之前所有信息随着时间间隔不断增大时,RNN会丧失学习到连接如此远的信息的能力。如:
- “the clouds are in the sky”最后的词,我们并不再需要其他的信息,因为很显然下一个词应该是sky。在这样的场景中,相关的信息和预测的词位置之间的间隔是非常小的,RNN可以学会使用先前的信息。
- 对于更加复杂的场景,预测“I grew up in France…I speak fluent French”最后的词。当前的信息建议下一个词可能是一种语言的名字,但是如果我们需要弄清楚是什么语言,我们是需要先前提到的离当前位置很远的France的上下文的。这说明相关信息和当前预测位置之间的间隔就肯定变得相当的大。
(4)不用于CNN,RNN整个神经网络里共享一组参数(U,V,W),极大减小了需要训练和评估的参数量。
(5)每个输出 x t \displaystyle x_{t} xt 对应的输出 h t \displaystyle h_{t\ } ht ,在有些任务里是不存在的。如文本情感分析,只需要最后的output判断分类即可。
3、双向RNN
对于完形填空等任务,当前的输出不只依赖于之前的序列元素,还可能依赖于之后的序列元素。直观理解,是2个反向的RNN叠加。
s ⃗ t = f ( W ⃗ x t + V ⃗ s ⃗ t − 1 + b ⃗ ) \displaystyle \vec{s}_{t} =\ f\left(\vec{W} x_{t} +\vec{V}\vec{s}_{t-1} +\vec{b}\right) st= f(Wxt+Vst−1+b)
s ← t = f ( W ← x t + V ← s ← t − 1 + b ← ) \displaystyle \overleftarrow{s}_{t} \ =\ f\left(\overleftarrow{W} x_{t} +\overleftarrow{V}\overleftarrow{s}_{t-1} +\overleftarrow{b}\right) st = f(Wxt+Vst−1+b)
h t = g ( U [ s ⃗ t ; s ← t ] + c ) \displaystyle h_{t} =\ g\left( U\left[\vec{s}_{t} ;\overleftarrow{s}_{t}\right] +c\right) ht= g(U[st;st]+c)
4、深层RNN
和双向RNN区别是在每一步/每个时间点都设置多层结构。某一时刻,经过多个隐层,最终输出预测值h。
s i → t = f ( W i → s t i − 1 → + V ⃗ s t + 1 i → + b i → ) \displaystyle \overrightarrow{s^{i}}_{t} \ =\ f\left(\overrightarrow{W^{i}}\overrightarrow{s^{i-1}_{t}} +\vec{V}\overrightarrow{s^{i}_{t+1}} +\overrightarrow{b^{i}}\right) sit = f(Wisti−1+Vst+1i+bi)
s i ← t = f ( W ← i s i − 1 ← t + V ← i s i ← t + 1 + b i ← ) \displaystyle \overleftarrow{s^{i}}_{t} \ =\ f\left(\overleftarrow{W}\overleftarrow{^{i} s^{i-1}}_{t} +\overleftarrow{V}\overleftarrow{^{i} s^{i}}_{t+1} +\overleftarrow{b^{i}}\right) sit = f(Wisi−1t+Visit+1+bi)
h t = g ( U [ h ⃗ t L ; h ← t L ] + c ) \displaystyle h_{t} =\ g\left( U\left[\vec{h}^{L}_{t} ;\overleftarrow{h}^{L}_{t}\right] +c\right) ht= g(U[htL;htL]+c)
eg: s 3 → t = f ( W 3 → s t 2 → + V ⃗ s t + 1 3 → + b 3 → ) \displaystyle \overrightarrow{s^{3}}_{t} \ =\ f\left(\overrightarrow{W^{3}}\overrightarrow{s^{2}_{t}} +\vec{V}\overrightarrow{s^{3}_{t+1}} +\overrightarrow{b^{3}}\right) s3t = f(W3st2+Vst+13+b3)
5、RNN与BPTT算法
(1)采用交叉熵损失函数,求参数W的最优解。
E
t
(
y
t
,
y
^
t
)
=
−
y
t
l
o
g
y
^
t
\displaystyle E_{t}\left( y_{t} ,\hat{y}_{t}\right) =-y_{t} log\hat{y}_{t}
Et(yt,y^t)=−ytlogy^t。对每个时间点的交叉熵相加,损失函数如下:
E
(
y
,
y
^
)
=
∑
t
E
t
(
y
t
,
y
^
t
)
=
−
∑
t
y
t
l
o
g
y
^
t
\displaystyle E\left( y,\hat{y}\right) =\sum _{t} E_{t}\left( y_{t} ,\hat{y}_{t}\right) =-\sum _{t} y_{t} log\hat{y}_{t}
E(y,y^)=t∑Et(yt,y^t)=−t∑ytlogy^t
(2)损失函数对参数W求导:
∂
E
∂
W
=
∑
t
∂
E
t
∂
W
\displaystyle \frac{\partial E}{\partial W} \ =\ \sum _{t}\frac{\partial E_{t}}{\partial W}
∂W∂E = t∑∂W∂Et
∂
E
3
∂
W
=
∑
t
∂
E
3
∂
y
^
3
∂
y
^
3
∂
s
3
∂
s
3
∂
W
3
\displaystyle \frac{\partial E_{3}}{\partial W} \ =\ \sum _{t}\frac{\partial E_{3}}{\partial \hat{y}_{3}}\frac{\partial \hat{y}_{3}}{\partial s_{3}}\frac{\partial s_{3}}{\partial W_{3}}
∂W∂E3 = t∑∂y^3∂E3∂s3∂y^3∂W3∂s3,但
s
3
=
t
a
n
h
(
U
x
t
+
W
s
2
)
\displaystyle s_{3} =tanh( Ux_{t} +Ws_{2})
s3=tanh(Uxt+Ws2),
s
2
=
t
a
n
h
(
U
x
t
+
W
s
1
)
\displaystyle s_{2} =tanh( Ux_{t} +Ws_{1})
s2=tanh(Uxt+Ws1),
s
1
=
t
a
n
h
(
U
x
t
+
W
s
0
)
\displaystyle s_{1} =tanh( Ux_{t} +Ws_{0})
s1=tanh(Uxt+Ws0)…
复合函数求导(链式法则):
∂
E
3
∂
W
=
∑
k
=
0
3
∂
E
3
∂
y
^
3
∂
y
^
3
∂
s
3
∂
s
3
∂
s
2
∂
s
2
∂
s
1
∂
s
1
∂
s
0
∂
s
0
∂
W
\displaystyle \frac{\partial E_{3}}{\partial W} \ =\ \sum ^{3}_{k=0}\frac{\partial E_{3}}{\partial \hat{y}_{3}}\frac{\partial \hat{y}_{3}}{\partial s_{3}}\frac{\partial s_{3}}{\partial s_{2}}\frac{\partial s_{2}}{\partial s_{1}}\frac{\partial s_{1}}{\partial s_{0}}\frac{\partial s_{0}}{\partial W}
∂W∂E3 = k=0∑3∂y^3∂E3∂s3∂y^3∂s2∂s3∂s1∂s2∂s0∂s1∂W∂s0
6、RNN的缺点:
梯度弥散与梯度消失问题。记忆更新的方式,导致最后求偏导时,出现连乘的形式。连乘可能导致梯度弥散或消失。是的RNN存在长期以来问题。因此引入了LSTM(可以解决梯度消失,但仍然无法解决梯度弥散问题)。
二、LSTM
在标准的RNN中,这个重复的模块只有一个非常简单的结构,例如一个tanh层。LSTM是RNN的一种,对RNN记忆细胞进行改造,使得该记的信息会一直传递,不该记的信息被门截断。激活函数 Tanh 作用在于帮助调节流经网络的值,使得数值始终限制在 -1 和 1 之间。LSTM同样是这样的结构,但是重复的模块拥有一个不同的结构。具体来说,RNN是重复单一的神经网络层,LSTM中的重复模块则包含四个交互的层,三个Sigmoid 和一个tanh层,并以一种非常特殊的方式进行交互。
RNN LSTM
tanh(x)sigmoid(x)
1、LSTM结构图:
下图中,σ表示的Sigmoid 激活函数与 tanh 函数类似,不同之处在于 sigmoid 是把值压缩到0~1 之间而不是 -1~1 之间。这样的设置有助于更新或忘记信息。因记忆能力有限,记住重要的,忘记无关紧要的。
2、LSTM解析:
(1)遗忘门:
sigmoid函数得到的结果作为衰减系数。决定上一时刻的记忆,按多少的概率衰减,得到要上一时刻需要保留的记忆。公式含义,t-1时刻的输出
h
t
−
1
h_{t-1}
ht−1与t时刻的输入
x
t
x_{t}
xt做矩阵拼接,做线性变换,经过sigmoid函数压缩到(0,1)之间。这个输出概率,将决定t-1时刻的记忆
c
t
−
1
c_{t-1}
ct−1有哪些信息被丢弃。
f
t
=
σ
(
W
f
⋅
[
h
t
−
1
,
x
t
]
+
b
f
)
\displaystyle f_{t} =\sigma ( W_{f} \cdot [ h_{t-1} ,x_{t}] +b_{f})
ft=σ(Wf⋅[ht−1,xt]+bf)
(2)输入门:
sigmoid函数决定要更新哪些内容;tanh创建一个新的候选项
C
~
t
\displaystyle \tilde{C}_{t}
C~t,将t-1时刻的输出
h
t
−
1
h_{t-1}
ht−1与t时刻的输入,压缩到(-1,1)之间,得到此时的全部信息。sigmoid函数得到的概率与tanh得到的内容相乘,得到t时刻需要被记忆下来的内容。
i
t
=
σ
(
W
f
⋅
[
h
t
−
1
,
x
t
]
+
b
i
)
\displaystyle i_{t} =\sigma ( W_{f} \cdot [ h_{t-1} ,x_{t}] +b_{i})
it=σ(Wf⋅[ht−1,xt]+bi)
C
~
t
=
tanh
(
W
C
⋅
[
h
t
−
1
,
x
t
]
+
b
C
)
\displaystyle \tilde{C}_{t} =\tanh ( W_{C} \cdot [ h_{t-1} ,x_{t}] +b_{C})
C~t=tanh(WC⋅[ht−1,xt]+bC)
(3)记忆细胞:
更新
C
t
−
1
\displaystyle{C}_{t-1}
Ct−1为
C
~
t
\displaystyle \tilde{C}_{t}
C~t。将t-1时刻状态
C
t
−
1
\displaystyle{C}_{t-1}
Ct−1与
f
t
\displaystyle f_{t}
ft相乘,丢掉不需要记忆的信息。加上
i
t
\displaystyle i_{t}
it*
C
~
t
\displaystyle \tilde{C}_{t}
C~t,更新t时刻需要记忆的信息。
C
t
=
f
t
∗
C
t
−
1
+
i
t
∗
C
t
~
\displaystyle C_{t} =f_{t} *C_{t-1} +i_{t} *\widetilde{C_{t}}
Ct=ft∗Ct−1+it∗Ct
(4)输出门:
基于“细胞状态”得到的输出。
- 首先t-1时刻的输出 h t − 1 h_{t-1} ht−1与t时刻的输入做矩阵拼接,做线性变换,经过sigmoid层来确定细胞状态的哪个部分将输出。
- 接着用tanh处理细胞状态(得到一个在-1和1之间的值),再将它和sigmoid门的输出相乘,输出我们确定输出的部分。
o t = σ ( W o ⋅ [ h t − 1 , x t ] + b o ) \displaystyle o_{t} =\sigma ( W_{o} \cdot [ h_{t-1} ,x_{t}] +b_{o}) ot=σ(Wo⋅[ht−1,xt]+bo)
h t = o t ∗ t a n h ( C t ) \displaystyle h_{t} =o_{t} \ *\ tanh( C_{t}) ht=ot ∗ tanh(Ct)
三、GRU
1、将忘记门和输入门合成了一个单一的更新门
2、同时还混合了细胞状态和隐状态
3、参数少了,比标准LSTM简单
更新门:
z
t
\displaystyle z_{t}
zt决定输出时记忆和忘记的概率。
z
t
=
σ
(
W
z
⋅
[
h
t
−
1
,
x
t
]
)
\displaystyle z_{t} =\sigma ( W_{z} \cdot [ h_{t-1} ,x_{t}])
zt=σ(Wz⋅[ht−1,xt])
r
t
\displaystyle r_{t}
rt的目的是从新看到的信息中抽取所有该时刻需要的信息。
r
t
=
σ
(
W
r
⋅
[
h
t
−
1
,
x
t
]
)
\displaystyle r_{t} =\sigma ( W_{r} \cdot [ h_{t-1} ,x_{t}])
rt=σ(Wr⋅[ht−1,xt])
h
t
~
\displaystyle \widetilde{h_{t}}
ht
表示该时刻所有有用和无用的输出。
h
t
~
=
t
a
n
h
(
W
⋅
[
r
t
∗
h
t
−
1
,
x
t
]
)
\displaystyle \widetilde{h_{t}} =tanh( W\cdot [ r_{t} \ *\ h_{t-1} ,x_{t}])
ht
=tanh(W⋅[rt ∗ ht−1,xt])
输出门:
h
t
\displaystyle h_{t}
ht忘记上一时刻输出的没用信息,增加这一时刻输出中的有用信息。忘记多少加多少。
h
t
=
(
1
−
z
t
)
∗
h
t
−
1
+
z
t
∗
h
t
\displaystyle h_{t} =( 1-z_{t}) \ *h_{t-1} +\ z_{t} \ *h_{t}
ht=(1−zt) ∗ht−1+ zt ∗ht
四、案例(待补充)
参考文献:
1、如何从RNN起步,一步一步通俗理解LSTM:https://blog.csdn.net/v_JULY_v/article/details/89894058
2、七月在线:循环神经网络与自然语言处理