转载请注明出处:https://thinkgamer.blog.csdn.net/article/details/100943664
博主微博:http://weibo.com/234654758
Github:https://github.com/thinkgamer
公众号:搜索与推荐Wiki
引言
常见的五种神经网络系列第三篇,主要介绍循环神经网络,由于循环神经网络包含的内容过多,分为上中下三篇进行介绍,本文主要是循环神经网络(下)篇,主要介绍以下内容:
- 长短期记忆网络(LSTM)
- 门控循环单元网络(GRU)
- 递归循环神经网络(RecNN)
- 图网络(GN)
该系列的其他文章:
- 常见的五种神经网络(1)-前馈神经网络
- 常见的五种神经网络(2)-卷积神经网络
- 常见的五种神经网络(3)-循环神经网络(上篇)
- 常见的五种神经网络(3)-循环神经网络(中篇)
- 常见的五种神经网络(3)-循环神经网络(下篇)
- 常见的五种神经网络(4)-深度信念网络
- 常见的五种神经网络(5)-生成对抗网络
LSTM
长短期记忆(Long Short-Term Memory,LSTM)网络是循环神经网络的一个变体,可以有效的解决简单循环神经网络的梯度爆炸和梯度消失问题。
LSTM的改进包含两点:
- 新的内部状态
- 门机制
新的内部状态
LSTM网络引入一个新的内部状态(internal state)
c
t
c_t
ct专门进行线性的循环传递,同时(非线性)输出信息给隐藏层的外部状态
h
t
h_t
ht(公式3-1)。
c
t
=
f
t
⊙
c
t
−
1
+
i
t
⊙
c
t
~
h
t
=
o
t
⊙
t
a
n
h
(
c
t
)
c_t = f_t \odot c_{t-1} + i_t \odot \tilde{c_t} \\ h_t = o_t \odot tanh(c_t)
ct=ft⊙ct−1+it⊙ct~ht=ot⊙tanh(ct)
其中
f
t
f_t
ft,
i
t
i_t
it,
o
t
o_t
ot为三个门来控制信息传递的路径,
⊙
\odot
⊙为向量元素乘积,
c
t
−
1
c_{t-1}
ct−1为上一时刻的记忆单元,
c
t
~
\tilde{c_t}
ct~是通过非线性函数得到的候选状态(公式3-2):
c t ~ = t a n h ( W c x t + U c h t − 1 + b c ) \tilde{c_t} = tanh( W_c x_t + U_c h_{t-1} + b_c ) ct~=tanh(Wcxt+Ucht−1+bc)
在每个时刻t,LSTM网络的内部状态 c t c_t ct记录了到当前时刻为止的历史信息。
门机制
LSTM网络引入门机制来控制信息的传递, f t , i t , o t f_t,i_t,o_t ft,it,ot分别为遗忘门,输入门,输出门。电路中门是0或1,表示关闭和开启,LSTM网络中的门是一种软门,取值在(0,1),表示以一定比例的信息通过,其三个门的作用分别为:
- f t f_t ft:控制上一个时刻的内部状态 c t − 1 c_{t-1} ct−1需要遗忘多少信息
- i t i_t it:控制当前时刻的候选状态 c t ~ \tilde{c_t} ct~有多少信息需要保存
- o t o_t ot:控制当前时刻的状态 c t c_t ct有多少信息需要输出为 h t h_t ht
三个门的计算如下(公式3-3):
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
)
i_t=\sigma (W_i x_t+U_i h_{t-1} + b_i) \\ f_t=\sigma (W_f x_t+U_f h_{t-1}+ b_f ) \\ o_t=\sigma (W_o x_t+U_o h_{t-1}+b_o)
it=σ(Wixt+Uiht−1+bi)ft=σ(Wfxt+Ufht−1+bf)ot=σ(Woxt+Uoht−1+bo)
其中
σ
\sigma
σ为logsitic函数,其输出区间为(0,1),
x
t
x_t
xt为当前输入,
h
t
−
1
h_{t-1}
ht−1为上一时刻的外部状态。
下图(图3-1)给出了LSTM的循环单元结构,其计算分为三个过程:
- 利用当前时刻的输入 x t x_t xt和上一时刻的外部状态 h t − 1 h_{t-1} ht−1计算出三个门和候选状态 c t ~ \tilde{c_t} ct~
- 结合遗忘门 f t f_t ft和输入门 i t i_t it来更新记忆单元 c t c_t ct
- 结合输出门 o t o_t ot将内部状态信息传递给外部状态 h t h_t ht
通过LSTM循环单元,整个网络可以建立长距离的时序依赖关系,公式3-1~3-3可以简单的描述为(公式3-4):
[
c
t
~
o
t
i
t
f
t
]
=
[
t
a
n
h
σ
σ
σ
]
(
W
[
x
t
h
t
−
1
]
+
b
)
c
t
=
f
t
⊙
c
t
−
1
+
i
t
⊙
c
t
~
h
t
=
o
t
⊙
t
a
n
h
(
c
t
)
\begin{bmatrix} \tilde{c_t}\\ o_t\\ i_t\\ f_t \end{bmatrix} = \begin{bmatrix} tanh\\ \sigma \\ \sigma \\ \sigma \end{bmatrix} (W\begin{bmatrix} x_t\\ h_{t-1} \end{bmatrix} + b) \\ c_t = f_t \odot c_{t-1}+ i_t \odot \tilde{c_t} \\ h_t = o_t \odot tanh(c_t)
⎣⎢⎢⎡ct~otitft⎦⎥⎥⎤=⎣⎢⎢⎡tanhσσσ⎦⎥⎥⎤(W[xtht−1]+b)ct=ft⊙ct−1+it⊙ct~ht=ot⊙tanh(ct)
其中
x
t
x_t
xt为当前时刻的输入,
W
W
W和
b
b
b为网络参数。
循环神经网络中的隐状态h存储了历史信息,可以看作是一种记忆(Memeory)。在简单循环网络中,隐状态每个时刻都会被重写,因此可以看作一种短期记忆(Short-term Memeory)。在神经网络中,长期记忆(Long-term Memory)可以看作是网格参数,隐含了从训练数据中学到的经验,其更新周期要远远慢于短期记忆。而在LSTM网络中,记忆单元c可以在某个时刻捕捉到某个关键信息,并有能力将该信息保存一段时间,记忆单元c中保存的信息要远远长于隐状态h,但又远远短于长期记忆,因此被成为长短期记忆网络(Long Short-term Memory)。
GRU
门控单元(Gate Recurrent Unit,GRU)网络是一种比LSTM更加简单的循环神经网络。在LSTM中遗忘门和输入门是互补关系,比较冗余,GRU将遗忘门和输入门合并成一个门:更新门。同时GRU也不引入额外的记忆单元,直接在当前的状态 h t h_t ht和上一个时刻的状态 h t − 1 h_{t-1} ht−1之间引入线性依赖关系。
在GRU网络中,当前时刻的候选状态
h
t
~
\tilde{h_t}
ht~为(公式3-5):
h
t
~
=
t
a
n
h
(
W
h
x
h
+
U
h
(
r
t
⊙
h
t
−
1
)
+
b
h
)
\tilde{h_t} = tanh( W_h x_h + U_h(r_t\odot h_{t-1}) + b_h )
ht~=tanh(Whxh+Uh(rt⊙ht−1)+bh)
计算 h t ~ \tilde{h_t} ht~时,选用tanh激活函数是因为其导数有比较大的值域,缓解梯度消失问题。
其中
r
t
∈
[
0
,
1
]
r_t \in [0,1]
rt∈[0,1] 为重置门(reset gate),用来控制候选状态
h
t
~
\tilde {h_t}
ht~的计算是否依赖上一时刻的状态
h
t
−
1
h_{t-1}
ht−1,公式如下(公式3-6):
r
t
=
σ
(
W
r
x
t
+
U
r
h
t
−
1
+
b
r
)
r_t = \sigma ( W_r x_t + U_r h_{t-1} + b_r)
rt=σ(Wrxt+Urht−1+br)
当 r t r_t rt为0 时,候选状态 h t ~ \tilde{h_t} ht~只和当前输入 x t x_t xt有关,和历史状态无关,当 r t r_t rt为1时,候选状态 h t ~ \tilde{h_t} ht~和当前输入 x t x_t xt,历史状态 h t − 1 h_{t-1} ht−1都有关,和简单循环网络一致。
GRU网络隐状态
h
t
h_t
ht的更新方式为(公式3-7):
h
t
=
z
t
⊙
h
t
−
1
+
(
1
−
z
t
)
⊙
h
t
~
h_t = z_t \odot h_{t-1}+ (1-z_t) \odot \tilde {h_t}
ht=zt⊙ht−1+(1−zt)⊙ht~
其中
z
∈
[
0
,
1
]
z \in [0,1]
z∈[0,1]为更新门(update gate),用来控制当前状态需要从历史状态中保留多少信息(不经过非线性变换),以及需要从候选状态中获取多少信息。
z
t
z_t
zt公式如下(公式3-8):
z
t
=
σ
(
W
z
x
t
+
U
z
h
t
−
1
+
b
z
)
z_t = \sigma (W_z x_t + U_z h_{t-1} + b_z)
zt=σ(Wzxt+Uzht−1+bz)
- 若 z t = 0 z_t=0 zt=0,当前状态 h t h_t ht和历史状态 h t − 1 h_{t-1} ht−1之间为非线性函数。
- 若 z t = 0 , r = 1 z_t=0,r=1 zt=0,r=1,GRU退化为简单循环网络
- 若 z t = 0 , r = 0 z_t=0,r=0 zt=0,r=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,和当前输入 x t x_t xt无关
GRU网络循环单元结构如下(图3-2):
RecNN
如果将循环神经网络按时间展开,每个时刻的隐状态 h t h_t ht看做是一个节点,那么这些节点构成一个链式结构,而链式结构是一种特殊的图结构,很容易将这种消息传递的思想扩展到任意的图结构上。
递归神经网络(Recursive Neurnal Network,RecNN)是循环神经网络在有向无循环图上的控制,递归神经网络一般结构为树状的层次结构,如下图所示(图3-3):
以上图(a)为例,包含3个隐藏层 h 1 , h 2 , h 3 h_1,h_2,h_3 h1,h2,h3,其中 h 1 h_1 h1由两个输入 x 1 , x 2 x_1,x_2 x1,x2计算得到, h 2 h_2 h2由两个输入 x 3 , x 4 x_3,x_4 x3,x4计算得到, h 3 h_3 h3由两个隐藏层 h 1 , h 2 h_1,h_2 h1,h2计算得到。
对于一个节点
h
i
h_i
hi,它可以接受来自子节点集合
π
i
\pi_i
πi中所有节点的消息,并更新自己的状态,如下所示(公式3-9):
h
i
=
f
(
h
π
i
)
h_i = f(h_{\pi_i})
hi=f(hπi)
其中
h
π
i
h_{\pi_i}
hπi表示
π
i
\pi_i
πi集合中所有节点状态的拼接,
f
(
.
)
f(.)
f(.)是一个和节点状态无关的非线性函数,可以为一个单层的前馈神经网络,比如图3-3(a)所表示的递归神经网络可以表示为(公式3-10):
h
1
=
σ
(
W
[
x
1
x
2
]
+
b
)
h
2
=
σ
(
W
[
x
3
x
4
]
+
b
)
h
3
=
σ
(
W
[
h
1
h
2
]
+
b
)
h_1 = \sigma (W \begin{bmatrix} x_1\\ x_2 \end{bmatrix}+ b) \\ h_2 = \sigma (W \begin{bmatrix} x_3\\ x_4 \end{bmatrix}+ b) \\ h_3 = \sigma (W \begin{bmatrix} h_1\\ h_2 \end{bmatrix}+ b)
h1=σ(W[x1x2]+b)h2=σ(W[x3x4]+b)h3=σ(W[h1h2]+b)
其中
σ
\sigma
σ表示非线性激活函数,W和b为可学习的参数,同样输出层y可以为一个分类器,比如(公式3-11):
h
3
=
g
(
W
′
[
h
1
h
2
]
+
b
′
)
h_3 = g (W' \begin{bmatrix} h_1\\ h_2 \end{bmatrix}+ b')
h3=g(W′[h1h2]+b′)
其中
g
(
.
)
g(.)
g(.)为分类器,
W
′
W'
W′和
b
′
b'
b′为分类器的参数。当递归神经网络的结构退化为图3-3(b)时,就等价于简单神经循环网络。
递归神经网络主要用来建模自然语言句子的语义,给定一个句子的语法结构,可以使用递归神经网络来按照句法的组合关系来合成一个句子的语义,句子中每个短语成分可以分成一些子成分,即每个短语的语义可以由它的子成分语义组合而来,进而合成整句的语义。
同样也可以使用门机制来改进递归神经网络中的长距离依赖问题,比如树结构的长短期记忆模型就是将LSTM的思想应用到树结构的网络中,来实现更灵活的组合函数。
GN
在实际应用中,很多数据是图结构的,比如知识图谱,社交网络,分子网络等。而前馈网络和反馈网络很难处理图结构的数据。
**图网络(Graph Network,GN)**是将消息传递的思想扩展到图结构数据上的神经网络。
对于一个图结构
G
(
V
,
ε
)
G(V,\varepsilon )
G(V,ε),其中
V
V
V表示节点结合,
ε
\varepsilon
ε表示边集合。每条边表示两个节点之间的依赖关系,节点之间的连接可以是有向的,也可以是无向的。图中每个节点v都用一组神经元来表示其状态
h
(
v
)
h^{(v)}
h(v) ,初始状态可以为节点v的输入特征
x
(
v
)
x^{(v)}
x(v),每个节点接受相邻节点的信息,来更新自己的状态,如下所示(公式3-12):
m
t
(
v
)
=
∑
u
∈
N
(
v
)
f
(
h
t
−
1
(
v
)
,
h
t
−
1
(
u
)
,
e
(
u
,
v
)
)
h
t
(
v
)
=
g
(
h
t
−
1
(
v
)
,
m
t
(
u
)
)
m^{(v)}_t = \sum_{u \in N(v)} f( h^{(v)}_{t-1},h^{(u)}_{t-1},e^{(u,v)} ) \\ h^{(v)}_t = g(h^{(v)}_{t-1},m^{(u)}_t)
mt(v)=u∈N(v)∑f(ht−1(v),ht−1(u),e(u,v))ht(v)=g(ht−1(v),mt(u))
其中
N
(
v
)
N(v)
N(v)表示节点v的邻居节点,
m
t
(
v
)
m^{(v)}_t
mt(v) 表示在t时刻节点v接受到的信息,
e
(
u
,
v
)
e^{(u,v)}
e(u,v)为边(v,u)上的特征。
公式3-12是一种同步更新方式,所有结构同时接受信息并更新自己的状态,而对于有向图来说,使用异步的更新方式会更有效率,比如循环神经网络或者递归神经网络,在整个图更新T次后,可以通过一个读出函数g(.)来得到整个网络的表示。
至此,循环神经网络(上)(中)(下)篇已经介绍完毕。