简介:个人学习分享,如有错误,欢迎批评指正。
一. 核心理念
循环神经网络(Recurrent Neural Network,RNN)是一类专门用于处理序列数据
的神经网络架构。其独特之处在于能够处理输入序列中元素的时序关系
,通过在网络中引入循环连接,使得信息能够在时间步之间传递和积累。
时间序列数据是指在不同时间点上收集到的数据,这类数据反映了某一事物、现象等随时间的变化状态或程度。当然序列数据也可以不是时间,比如文字序列,但总归序列数据有一个特点——后面的数据跟前面的数据有关系
。
为什么要发明RNN
我们先来看一个NLP很常见的问题,命名实体识别,举个例子,现在有两句话:
第一句话:I like eating apple!(我喜欢吃苹果!)
第二句话:The Apple is a great company!(苹果真是一家很棒的公司!)
现在的任务是要给apple打Label,我们都知道第一个apple是一种水果,第二个apple是苹果公司,假设我们现在有大量的已经标记好的数据以供训练模型,当我们使用全连接的神经网络时,我们做法是把apple这个单词的特征向量输入到我们的模型中(如上图),在输出结果时,让我们的label里,正确的label概率最大,来训练模型,但我们的语料库中,有的apple的label是水果,有的label是公司,这将导致模型在训练的过程中,预测的准确程度,取决于训练集中哪个label多一些
,这样的模型对于我们来说完全没有作用。问题就出在了我们没有结合上下文去训练模型,而是单独的在训练apple这个单词的label,这也是全连接神经网络模型所不能做到的,于是就有了我们的循环神经网络。
二. RNN的基本网络结构
1 网络组成
标准的RNN由以下几个主要部分组成:
-
输入层 (Input Layer):接收序列数据的
每一个时间步的输入向量
。 -
隐藏层 (Hidden Layer):包含循环连接,
用于储存和传递时间步之间的信息
。 - 输出层 (Output Layer):生成每个时间步的输出。
2 RNN基础结构
单层网络结构如下图所示:
输入是
x
x
x,经过变换
W
x
+
b
Wx + b
Wx+b 和 激活函数
f
f
f,得到输出
y
y
y。
假设这里的激活函数
f
f
f 是 sigmoid 函数:
f
(
x
)
=
1
1
+
e
−
x
f(x) = \frac{1}{1 + e^{-x}}
f(x)=1+e−x1
则进一步得到:
y
=
1
1
+
e
−
(
W
x
+
b
)
y = \frac{1}{1 + e^{-(Wx + b)}}
y=1+e−(Wx+b)1
在实际应用中,我们还会遇到很多序列形的数据。
为了建模序列问题,RNN 引入了 隐藏状态 h h h (hidden state) 的概念,隐藏状态 h h h 可以对序列形的数据提取特征,接着再转换为输出。
先从
h
1
h_1
h1 的计算开始看:
图示中记号的含义是:
a) 圆圈或方块表示的是向量。
b) 一个箭头就表示对该向量做一次变换
。如上图中
h
0
h_0
h0 和
x
1
x_1
x1 分别有一个箭头连接,就表示对
h
0
h_0
h0 和
x
1
x_1
x1 各做了一次变换。
h 2 h_2 h2 的计算和 h 1 h_1 h1 类似,但有两点需要注意:
-
在计算时,
每一步使用的参数
U , W , b U, W, b U,W,b都是一样的,也就是说每个步骤的参数都是共享的
,这是 RNN 的重要特点。(虽然说 X [ t − 1 ] , X [ t ] , X [ t + 1 ] X[t-1], X[t], X[t+1] X[t−1],X[t],X[t+1] 是表示不同时间刻的输入,但是真正输入到 RNN 网络中的时候,并不是作为单独的向量一个一个输入,而是组合在一起形成一个矩阵输入,然后这个矩阵再通过权重矩阵 U U U 的变化。其实是同一时刻输入地,只是计算的先后顺序不同
。因此同一个隐藏层中,不同时刻的输入他们的 W , V , U W, V, U W,V,U 参数是共享的。) -
LSTM 中的权值则不共享,
因为它是在两个不同的向量中
。而 RNN 的权值为何共享呢?很简单,因为RNN 的权值是在同一个向量中,只是不同时刻而已
。
依次计算剩下来的(使用相同的参数 U , W , b U, W, b U,W,b):
为了方便起见,只画出序列长度为4的情况,实际上,这个计算过程可以无限地持续下去。
我们目前的RNN还没有输出,得到输出值的方法就是直接通过
h
h
h 进行计算:
正如之前所说,一个箭头就表示对对应的向量做一次类似于 f ( W x + b ) f(Wx + b) f(Wx+b) 的变换,这里的这个箭头就表示对 h 1 h_1 h1 进行一次变换,得到输出 y 1 y_1 y1。
剩下的输出类似进行(使用和
h
1
h_1
h1 同样的参数
V
V
V 和
c
c
c):
这就是最经典的 RNN 结构,是 x 1 , x 2 , … , x n x_1, x_2, \dots, x_n x1,x2,…,xn,输出为 y 1 , y 2 , … , y n y_1, y_2, \dots, y_n y1,y2,…,yn。也就是说,输入和输出序列必须是等长的。
三. RNN的基本工作流程
1 序列数据的处理
RNN主要用于处理序列数据,如文本、语言、时间序列等。假设输入序列为 X = ( x 1 , x 2 , x 3 , … , x T ) X = (x_1, x_2, x_3, \ldots, x_T) X=(x1,x2,x3,…,xT),RNN逐步处理序列中的每一个时间步 t = 1 , 2 , … , T t = 1, 2, \ldots, T t=1,2,…,T。
2 时间步之间的信息传递
在每一个时间步
t
t
t,RNN接收当前输入
x
t
x_t
xt 和前一时间步的隐藏状态
h
t
−
1
h_{t-1}
ht−1,通过非线性变换计算当前时间步的隐藏状态
h
t
h_t
ht,并根据
h
t
h_t
ht 生成输出
y
t
y_t
yt。这种机制允许网络在处理当前输入时,结合之前的历史信息
。
3 信息流动图示
四. 数学基础
1 隐藏状态的计算
每个时间步的隐藏状态
h
t
h_t
ht 由当前输入
x
t
x_t
xt 和前一隐藏状态
h
t
−
1
h_{t-1}
ht−1 共同决定,计算公式如下:
h
t
=
tanh
(
W
x
h
x
t
+
W
h
h
h
t
−
1
+
b
h
)
h_t = \tanh(W_{xh}x_t + W_{hh}h_{t-1} + b_h)
ht=tanh(Wxhxt+Whhht−1+bh)
- W x h W_{xh} Wxh:输入到隐藏层的权重矩阵
- W h h W_{hh} Whh:隐藏层到隐藏层的权重矩阵(循环连接)
- b h b_h bh:隐藏层的偏置向量
- tanh \tanh tanh:激活函数,常用双曲正切函数以引入非线性
2 输出的计算
基于当前隐藏状态
h
t
h_t
ht,计算输出
y
t
y_t
yt:
y
t
=
W
h
y
h
t
+
b
y
y_t = W_{hy}h_t + b_y
y