转载请注明出处:https://thinkgamer.blog.csdn.net/article/details/100600661
博主微博:http://weibo.com/234654758
Github:https://github.com/thinkgamer
公众号:搜索与推荐Wiki
引言
常见的五种神经网络系列第三种,主要介绍循环神经网络,由于循环神经网络包含的内容过多,分为上中下三篇进行介绍,本文主要是循环神经网络(上)篇,主要介绍以下内容:
- 循环神经网络概述
- 如何给神经网络增加记忆能力
- 延时神经网络
- 有外部输入的非线性自回归模型
- 循环神经网络
- 一般的循环神经网络
- 单向循环神经网络
- 双向循环神经网络
- 深度循环神经网络
- 循环神经网络应用到机器学习任务
该系列的其他文章:
- 常见的五种神经网络(1)-前馈神经网络
- 常见的五种神经网络(2)-卷积神经网络
- 常见的五种神经网络(3)-循环神经网络(上篇)
- 常见的五种神经网络(3)-循环神经网络(中篇)
- 常见的五种神经网络(3)-循环神经网络(下篇)
- 常见的五种神经网络(4)-深度信念网络
- 常见的五种神经网络(5)-生成对抗网络
概述
在前馈神经网络中,信息在神经元之间的传递是单向,网络的输出只依赖于当前的输入,这样限制虽然使网络变得容易学习,但是却减弱了网络的表达能力。在很多现实任务中,网络的输出不仅和当前的输入有关,也和过去一段时间的输出相关,比如一个有限状态自动机不仅和当前的输入有关,也和当前的状态(上一步的输出)有关。如下图(图-1)
有限状态自动机称为FSM(finite state machine)或者FSA(finite state automaton)
此外,前馈神经网络难以处理时序数据,比如视频,语音,文本等。因为时序数据的长度是不固定的,而前馈神经网络要求输入和输出的维度是固定的。因此当处理这种复杂的时序数据时,就需要一种表达能力能强的模型。
循环神经网络(Recurrent Neural Network,RNN) 是一类具有短期记忆能力的神经网络,在循环神经网络中,神经元不仅可以接受其他神经元的信息,还可以接受自身的信息,形成一个环路结构。RNN的参数学习可以通过随时间反向传播算法进行学习(下文会具体介绍),随时间反向传播算法按照时间的逆序将错误信息一步步的向前传递,当输入序列时间较长时,会存在梯度消失和梯度爆炸问题(也叫长期依赖问题),为了解决这个问题,人们对RNN进行了许多改进,其中最有效的是引入门控制,比如长短期记忆网络(LSTM)和门控循环单元网络(GRU),将在(下)篇进行介绍。
如何给网络增加记忆能力
上边提到前馈神经网络是一个静态网络,不能处理时序数据,那么可以通过以下三种方法给网络增加记忆能力:
- 延时神经网络
- 有外部输入的非线性自回归模型
- 循环神经网络
延时神经网络
一种简单的利用利用历史信息的方法是建立一个额外的延时单元,用来存储网络的历史信息(比如输入,输出,隐状态等),这其中比较有代表性的就是延时神经网络(TDNN,Time Delay Neural Network)。
延时神经网络是在前馈神经网络的非输出层都添加一个延时器,记录最近几次神经元的输出,在第t个时刻,第(l+1)层的神经元和第(l)层神经元的最近p次输出有关,即(公式-1):
h
t
l
+
1
=
f
(
h
t
l
,
h
t
−
1
l
,
.
.
.
.
,
h
t
−
p
+
1
l
)
h_t^{l+1} = f(h_t^l,h_{t-1}^l,....,h_{t-p+1}^l)
htl+1=f(htl,ht−1l,....,ht−p+1l)
通过延时器,前馈神经网络就具有了短期记忆的能力。
有外部输入的非线性自回归模型
自回归模型(Autoregressive Model) 是统计学中常用一类时间序列模型,用一个变量
y
t
y_t
yt 的历史信息来预测自己(公式-2)。
y
t
=
w
0
+
∑
i
=
1
p
w
p
∗
y
t
−
i
+
ε
t
y_t = w_0 + \sum_{i=1}^{p}w_p * y_{t-i} + \varepsilon_t
yt=w0+i=1∑pwp∗yt−i+εt
其中p为超参数,
w
p
w_p
wp 为参数,
ε
t
~
N
(
0
,
σ
2
)
\varepsilon_t~N(0,\sigma ^2)
εt~N(0,σ2) 为第t个时刻的噪声,方差
σ
2
\sigma^2
σ2和时间t无关。
有外部输入的非线性自回归模型(Nonlinear Autoregressive Model)是自回归模型的扩展,在每个时刻t都有一个外部输入
x
t
x_t
xt,产出一个输出
y
t
y_t
yt,NART通过一个延时器来记录最近几次的外部输入和输出,第t个时刻的输出
y
t
y_t
yt为(公式-3):
y
t
=
f
(
x
t
,
x
t
−
1
,
.
.
,
x
t
−
p
,
y
t
−
1
,
y
t
−
2
,
.
.
.
.
,
y
t
−
q
)
y_t = f(x_t, x_{t-1},..,x_{t-p}, y_{t-1},y_{t-2},....,y_{t-q})
yt=f(xt,xt−1,..,xt−p,yt−1,yt−2,....,yt−q)
其中f(.)为非线性函数,可以是前馈神经网络,p和q为超参数。
循环神经网络
给定一个输入序列,
x
1
:
T
=
(
x
1
,
x
2
,
.
.
.
,
x
T
)
x_{1:T}=( x_1, x_2, ... , x_T )
x1:T=(x1,x2,...,xT) 循环神经网络通过以下公式(公式-4)更新带反馈边的隐藏层的活性值
h
t
h_t
ht:
h
t
=
(
h
t
−
1
,
x
t
)
h_t = (h_{t-1}, x_t)
ht=(ht−1,xt)
循环神经网络示例如下(图-2):
一般的循环神经网络
在(图-2)中展示了一个简单的循环神经网络,其整个结构分为3层:输入层,隐藏层和输出层。其中t时刻,隐藏层的状态 h t h_t ht不仅与输入 x t x_t xt有关,还与上一个时刻的隐藏层状态 h t − 1 h_{t-1} ht−1有关。
由于隐藏层多了一个自身到自身的输入,因此该层被称为循环层,(图-2)所示的为一个简单循环神经网络。循环神经网络还有多种类型,基于循环的方向划分为:
- 单向循环神经网络
- 双向循环神经网络
基于循环的深度分为:
- 循环神经网络
- 深度循环神经网络
单向循环神经网络
(图-2)所示即为一个单向的循环神经网络,对其展开后的效果图如下(图-3):
上图可以理解为网络的输入通过时间往后传递,当前隐藏层的输出
h
t
h_t
ht取决于当前层的输入
x
t
x_t
xt和上一层的输出
h
t
−
1
h_{t-1}
ht−1,因此当前隐藏层的输出信息包含了之前时刻的信息,表达出对之前信息的记忆能力。单向循环神经网络表达如下(公式-5):
o
t
=
g
(
V
∗
h
t
)
h
t
=
f
(
U
∗
x
t
+
W
∗
h
t
−
1
)
o_t = g(V*h_t) \\ h_t = f(U*x_t + W*h_{t-1})
ot=g(V∗ht)ht=f(U∗xt+W∗ht−1)
其中
o
t
o_t
ot为输出层的计算公式,
h
t
h_t
ht为隐藏层的计算公式,g(.) 和 f(.)为激活函数。值得说明的是在循环神经网络中U,V,W权重矩阵值每次循环都是一份,因此循环神经网络的每次循环步骤中,这些参数都是共享的,这也是循 环神经网络 的结构特征之一。
双向循环神经网络
在日常的信息推断中,当前信息不仅仅依赖之前的内容,也有可能会依赖后续的内容,比如英语的完形天空。这时候单向的循环神经网络就不能很好的处理,就需要 ** 双向循环神经网络(Bi-directional Recurrent Neural Network)** 。
其主要思想是训练一个分别向前和分别向后的循环神经网络,表示完整的上下文信息,两个循环 网络对应同一个输出层,因此可以理解为两个循环神经网络的叠加,对应的输出结果根据两个神经网络输出状态计算获得,将双向循环神经网络按照时间序列结构展开,如下图所示(图-4):
从上图可以看出,隐藏层需要保留两部分,一部分为由前向后的正向传递
h
t
h_t
ht,一部分为由后向前的反向传递
h
t
′
h'_t
ht′,最新的信息输出
o
t
o_t
ot。双向循环神经网络的表达公式如下(公式-6):
o
t
=
g
(
V
∗
h
t
+
V
′
∗
h
t
′
)
h
t
=
f
(
U
∗
x
t
+
W
∗
h
t
−
1
)
h
t
′
=
f
(
U
′
∗
x
t
+
W
′
∗
h
t
+
1
′
)
o_t = g(V*h_t + V'*h'_t) \\ h_t = f(U*x_t + W*h_{t-1}) \\ h'_t = f(U'*x_t + W'*h'_{t+1})
ot=g(V∗ht+V′∗ht′)ht=f(U∗xt+W∗ht−1)ht′=f(U′∗xt+W′∗ht+1′)
深度循环神经网络
上边介绍的单向训练神经网络和双向循环神经网络都只有一个隐藏层,但是在实际应用中,为了增强表达能力,往往引入多个隐藏层,即深度循环神经网络,如下图所示(图-5):
同样可以得到深度循环神经网络的表达式(公式-7):
o
t
=
g
(
V
(
i
)
∗
h
t
(
i
)
+
V
′
(
i
)
∗
h
t
′
(
i
)
)
h
t
(
i
)
=
f
(
U
(
i
)
∗
h
t
(
i
−
1
)
+
W
(
i
)
∗
h
t
−
1
)
h
t
′
(
i
)
=
f
(
U
′
(
i
)
∗
h
t
′
(
i
−
1
)
+
W
′
(
i
)
∗
h
t
+
1
′
)
.
.
.
h
t
(
1
)
=
f
(
U
(
1
)
∗
h
t
+
W
(
1
)
∗
h
t
−
1
)
h
t
′
(
1
)
=
f
(
U
′
(
1
)
∗
h
t
+
W
′
(
1
)
∗
h
t
+
1
′
)
o_t = g(V^{(i)}*h^{(i)}_t + V'^{(i)}*h'^{(i)}_t) \\ h^{(i)}_t = f(U^{(i)}*h^{(i-1)}_t + W^{(i)}*h_{t-1}) \\ h'^{(i)}_t = f(U'^{(i)}*h'^{(i-1)}_t + W'^{(i)}*h'_{t+1}) \\ ... \\ h^{(1)}_t = f(U^{(1)} * h_t + W^{(1)}*h_{t-1}) \\ h'^{(1)}_t = f(U'^{(1)} * h_t + W'^{(1)}*h'_{t+1}) \\
ot=g(V(i)∗ht(i)+V′(i)∗ht′(i))ht(i)=f(U(i)∗ht(i−1)+W(i)∗ht−1)ht′(i)=f(U′(i)∗ht′(i−1)+W′(i)∗ht+1′)...ht(1)=f(U(1)∗ht+W(1)∗ht−1)ht′(1)=f(U′(1)∗ht+W′(1)∗ht+1′)
从上述公式可以看出,最终的输出依赖两个维 度的计算,横向上内部前后信息的 叠加,即按照时间的计算;纵向上是每一时刻的输入信息在 逐层之间的传递,即按照 空间结构的计算。
循环神经网络应用到机器学习任务
循环神经网络可以应用到很多不同类型的机器学习任务,根据这些任务的特点,可以分为以下几种模式:
- 序列到类别模式
- 同步的序列到序列模式
- 异步的序列到序列模式
序列到类别模式
主要应用在序列数据的分类问题,其输入为序列,输出为类别。比如在文本分类中,输入为单词序列,输出为文本的类别。
假设一个样本
x
1
:
T
=
(
x
1
,
x
2
,
.
.
.
,
x
T
)
x_{1:T}=(x_1, x_2, ... , x_T)
x1:T=(x1,x2,...,xT)为一个长度为T的序列,输出为类别
y
∈
(
1
,
.
.
.
,
C
)
y \in (1, ..., C)
y∈(1,...,C),可以将样本x按不同的时刻输入到循环神经网络中,并得到不同时刻的隐含状态
h
t
h_t
ht,可以将
h
t
h_t
ht 看作是整个序列的最终表示,并输入给分类器 g(.) 进行分类,如下所示(公式-8):
y
^
=
g
(
h
T
)
\hat{y} = g(h_T)
y^=g(hT)
其中g(.) 为简单的线性分类器(比如LR)或者复杂的分类器(前馈神经网络)。
除了将最后时刻的状态作为序列表示之外,我们还可以对整个序列的状态进行平均,并用整个状态的最终平均作为整个序列的表示(公式-9):
y
^
=
g
(
1
T
∑
t
=
1
T
h
t
)
\hat{y} = g( \frac{1}{T} \sum_{t=1}^{T} h_t )
y^=g(T1t=1∑Tht)
公式-8 和公式-9 分别对应下图(图-6)的(a)和(b):
同步的序列到序列模式
主要用于序列标注(Sequence Labeling)任务,即每一时刻都有输入和输出,输入序列和输出序列的长度相同。比如词性标注(Part-of-Speech Tagging)中,每一个单词都需要标注其对应的词性标签。
假设一个样本
x
1
:
T
=
(
x
1
,
x
2
,
.
.
.
,
x
T
)
x_{1:T}=(x_1, x_2, ... , x_T)
x1:T=(x1,x2,...,xT)为一个长度为T的序列,输出为序列
y
1
:
T
=
(
y
1
,
y
2
,
.
.
.
,
y
T
)
y_{1:T}=(y_1, y_2, ... , y_T)
y1:T=(y1,y2,...,yT),可以将样本x按不同的时刻输入到循环神经网络中,并得到不同时刻的隐含状态
h
t
h_t
ht,每个时刻的
h
t
h_t
ht 代表了当前时刻和历史的信息,并输入给分类器 g(.) 进行分类,得到当前的标签
y
^
t
\hat{y}_t
y^t,如下所示(公式-8):
y
^
=
g
(
h
T
)
,
∀
t
∈
[
1
,
T
]
\hat{y} = g(h_T), \forall_t \in [1,T]
y^=g(hT),∀t∈[1,T]
异步的序列到序列模式
异步的序列到序列模式也成为编码器-解码器,输入序列和输出序列不需要有严格的对应关系,也不需要保持相同的长度,比如在机器翻译中,输入为源语音的单词序列,输出为目标语言的单词序列。
假设输入为一个长度为T的序列 x 1 : T = ( x 1 , x 2 , . . . , x T ) x_{1:T}=(x_1, x_2, ... , x_T) x1:T=(x1,x2,...,xT),输出为长度为M的序列 y 1 : M = ( x 1 , x 2 , . . . , x M ) y_{1:M}=(x_1, x_2, ... , x_M) y1:M=(x1,x2,...,xM),经常通过先编码后解码的形式实现。
先将样本x按不同时刻输入到一个循环神经网络(编码器)中,并得到其编码
h
T
h_T
hT,然后再使用另外一个循环神经网络(解码器)中,得到输出序列
y
^
1
:
M
\hat {y}_{1:M}
y^1:M。为了建立输出序列之间的依赖关系,在解码器中通常使用非线性的自回归模型。如下所示(公式-9):
h
t
=
f
1
(
h
t
−
1
,
x
t
)
,
∀
t
∈
[
1
,
T
]
h
T
+
t
=
f
2
(
h
T
+
t
−
1
,
x
t
)
,
∀
t
∈
[
1
,
M
]
y
^
t
=
g
(
h
T
+
t
)
,
∀
t
∈
[
1
,
M
]
h_t = f_1(h_{t-1},x_t), \forall_t \in [1,T] \\ h_{T+t} = f_2(h_{T+t-1},x_t), \forall_t \in [1,M] \\ \hat{y} _t = g(h_{T+t}), \forall_t \in [1,M]
ht=f1(ht−1,xt),∀t∈[1,T]hT+t=f2(hT+t−1,xt),∀t∈[1,M]y^t=g(hT+t),∀t∈[1,M]
其中
f
1
(
.
)
f_1(.)
f1(.),
f
2
(
.
)
f_2(.)
f2(.)分别为用作编码器和解码器的循环神经网络,g(.)为分类器,
y
^
t
\hat{y}_t
y^t 为输出预测
y
^
t
\hat{y}_t
y^t的表示。
至此,循环神经网络(上)篇已经介绍完了,在(中)篇和下篇中会展开介绍更多的内容,欢迎关注。