赞
踩
为什么需要RNN?这里以Hung-yi Lee给出的例子为例
当TaiPei前的单词不同时,TaiPei所表示的含义是不同的。如果用一般的neural network来训练,是实现不了这个任务的,因为在一般的feed forward网络中,相同的input会得到相同的output。因此,我们需要一种能够处理序列信息的神经网络,而RNN(Recurrent Neural Network)能够很好的解决这一问题。
RNN和结构和一般的neural network很像,但是多了一个memory的部分,如图
每个neuron再进行计算时,不仅会考虑当前的输入 x i x_{i} xi,还会考虑储存在memory中的信息。而memroy中的信息来自于每次neuron计算完之后的结果,这个结果是不同的,这也就使得对于相同的input,RNN的output不一定是相同的,因此RNN能够处理序列信息。把RNN展开后如下图所示
RNN实际上是把同一个network执行了多次
上面所说的是单向的RNN,即只考虑 x t x_{t} xt之前的信息 x 1 − x t − 1 x_{1}-x_{t-1} x1−xt−1。而双向RNN是同时训练两个network,一个正向一个反向,共同作用得到一个output,这样能够考虑到前后两部分的信息关联
Vanilla RNN的参数有两个:
W
x
h
W_{xh}
Wxh和
W
h
h
W_{hh}
Whh,这一点和HMM模型有点像。在计算每一个时间步的隐状态
h
h
h时,公式如下
h
t
=
f
(
W
x
h
x
t
+
W
h
h
h
t
−
1
)
h_{t}=f(W_{xh}x_t+W_{hh}h_{t-1})
ht=f(Wxhxt+Whhht−1)
这里的激活函数 f f f通常使用 t a n h tanh tanh。
RNN是一个深度神经网络,这里的深度体现在时间序列上,也就是横向的深。那么在训练的时候,我们仍然采用Back Propagation
,但是区别在于这里的反向传播是基于时间来做的,因此也被叫做BPTT。我们举个例子来看一下RNN中梯度的求解。
假设我们想求最终的Loss对
h
1
h_1
h1的gradient,那么
∂
L
∂
h
1
=
∂
L
∂
O
∗
∂
O
∂
h
n
∗
∂
h
n
∂
h
n
−
1
.
.
.
.
.
.
∂
h
2
∂
h
1
\frac{\partial{L}}{\partial{h_1}}=\frac{\partial{L}}{\partial{O}}*\frac{\partial{O}}{\partial{h_n}}*\frac{\partial{h_n}}{\partial{h_{n-1}}}......\frac{\partial{h_2}}{\partial{h_1}}
∂h1∂L=∂O∂L∗∂hn∂O∗∂hn−1∂hn......∂h1∂h2
= ∂ L ∂ O ∗ ∂ O ∂ h n ∗ ∏ i = 2 n ∂ h t ∂ h t − 1 =\frac{\partial{L}}{\partial{O}}*\frac{\partial{O}}{\partial{h_n}}*\prod_{i=2}^{n}\frac{\partial{h_t}}{\partial{h_{t-1}}} =∂O∂L∗∂hn∂O∗i=2∏n∂ht−1∂ht
我们又知道
h
t
=
f
(
W
x
h
x
t
+
W
h
h
h
t
−
1
)
h_{t}=f(W_{xh}x_t+W_{hh}h_{t-1})
ht=f(Wxhxt+Whhht−1),因此
∂
h
t
∂
h
t
−
1
=
d
i
a
g
(
f
′
(
W
x
h
x
t
+
W
h
h
h
t
−
1
)
)
∗
W
h
h
\frac{\partial{h_t}}{\partial{h_{t-1}}}=diag(f'(W_{xh}x_t+W_{hh}h_{t-1}))*W_{hh}
∂ht−1∂ht=diag(f′(Wxhxt+Whhht−1))∗Whh。这里的
d
i
a
g
diag
diag的意思是将一个向量变为一个对角矩阵。代入上面的式子,则
=
∂
L
∂
O
∗
∂
O
∂
h
n
∗
∏
i
=
2
n
d
i
a
g
(
f
′
(
W
x
h
x
t
+
W
h
h
h
t
−
1
)
)
∗
W
h
h
=\frac{\partial{L}}{\partial{O}}*\frac{\partial{O}}{\partial{h_n}}*\prod_{i=2}^{n}diag(f'(W_{xh}x_t+W_{hh}h_{t-1}))*W_{hh}
=∂O∂L∗∂hn∂O∗i=2∏ndiag(f′(Wxhxt+Whhht−1))∗Whh
= ∂ L ∂ O ∗ ∂ O ∂ h n ∗ ( W h h ) n − 1 ∗ ∏ i = 2 n d i a g ( f ′ ( W x h x t + W h h h t − 1 ) ) =\frac{\partial{L}}{\partial{O}}*\frac{\partial{O}}{\partial{h_n}}*(W_{hh})^{n-1}*\prod_{i=2}^{n}diag(f'(W_{xh}x_t+W_{hh}h_{t-1})) =∂O∂L∗∂hn∂O∗(Whh)n−1∗i=2∏ndiag(f′(Wxhxt+Whhht−1))
根据上面的式子我们不难发现,RNN模型的梯度是一个很多元素连乘的形式(求对 W x h W_{xh} Wxh和对 W h h W_{hh} Whh的梯度同理),因此如果有很多项都是小于1,那么就会出现梯度弥散问题;如果出现较多比较大的值,那么就会出现梯度爆炸问题。
在RNN的训练过程中,每次遇到一个input,memory中的数据都会重置并更新,这就导致RNN无法处理依赖信息间隔较大的情况。
LSTM由三个gate构成,分别是:input gate、forget gate、output gate,门控系统一般用sigmoid做activation function来实现对门开关的控制
上图非常直观地说明了LSTM的运行机理,我们再做一些文字说明。
LSTM的输入是当前的词向量 x t x_t xt和上一时刻的隐状态 h t − 1 h_{t-1} ht−1,接着将这两个输入concat,与四个参数矩阵相乘得到四个状态,分别为 z , z i , z f , z o z,z^i,z^f,z^o z,zi,zf,zo。 z i , z f , z o z^i,z^f,z^o zi,zf,zo都用sigmoid函数进行激活,代表输入门控信号、遗忘门控信号、输出门控信号。
LSTM内部主要有三个阶段:
忘记阶段:这个阶段主要是对上一个节点传进来的输入进行选择性忘记。简单来说就是会 “忘记不重要的,记住重要的”。具体来说是通过计算得到的 z f z^{f} zf来作为忘记门控,来控制上一个状态的 c t − 1 c^{t-1} ct−1哪些需要留哪些需要忘。
选择记忆阶段:这个阶段将这个阶段的输入有选择性地进行“记忆”。主要是会对输入 x t x^{t} xt进行选择记忆。哪些重要则着重记录下来,哪些不重要,则少记一些。当前的输入内容由前面计算得到的 z z z表示。而选择的门控信号则是由 z i z^{i} zi来进行控制。将上面两步得到的结果相加,即可得到传输给下一个状态的 c t c^{t} ct。
输出阶段:这个阶段将决定哪些将会被当成当前状态的输出。主要是通过 z o z^{o} zo来进行控制的。
c t = z f ⊗ c t − 1 + z i ⊗ z c^t=z^f\otimes{c^{t-1}}+z^i\otimes{z} ct=zf⊗ct−1+zi⊗z
h t = z o ⊗ t a n h ( c t − 1 ) h^t=z^o\otimes{tanh(c^{t-1})} ht=zo⊗tanh(ct−1)
RNN的另外一种变体是GRU,GRU比LSTM的结构简单一些,有两个门控:重置门 r r r和更新门 z z z,GRU需要两个输入,得到一个输出,与基本的RNN很相似。
GRU的流程如下:
1、通过重置门控获取到重置后的数据 h t ′ = h t − 1 ⨀ r h_{t}'=h_{t-1}\bigodot{r} ht′=ht−1⨀r,再将 h t − 1 h_{t-1} ht−1和 x t x_{t} xt进行拼接并使用tanh激活得到 h ′ h^{'} h′,这里的 h ′ h^{'} h′主要包含的是当前的输入信息 x t x_{t} xt
2、更新门控的计算公式为 h t = ( 1 − z ) ⨀ h t − 1 + z ⨀ h ′ h_{t} = (1-z)\bigodot{h_{t-1}}+z\bigodot{h^{'}} ht=(1−z)⨀ht−1+z⨀h′,更新门控同时做到了遗忘和记忆两个工作, ( 1 − z ) (1-z) (1−z)这一项就是选择性遗忘部分的之前的信息, z z z这一项就是记忆当前输入的信息。总的来说,这一步的操作就是忘记传递下来的 h t − 1 h_{t-1} ht−1中的某些维度信息,并加入当前节点输入的某些维度信息
GRU和LSTM的效果很接近,但训练的代价小得多
这里问题是最经典的RNN解决的问题,即输入序列与输出序列等长
这里问题的例子也有很多,比如文本分类、文本情感预测等。在这类问题中,我们只需要取最后一个隐状态,经过一个全连接层,再使用softmax得到我们的输出。
即输入不是一个序列,输出是一个序列。对于这类问题,可以把x作为一个全局共享的输入,再得到每一个时间步的输出。经典的应用场景是image caption,也就是根据输入图片输出一段文字。
输入序列长度和输出序列长度不等,这类问题也叫做Seq2Seq问题,它和attention的结合放在attention系列总结
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。