循环神经网络(RNN)
DNN 以及 CNN 的模型和前向反向传播算法,这些算法都是前向反馈的,模型的输出和模型本身没有关联关系。
循环神经网络(Recurrent Neural Network)指一个随着时间的推移,重复发生的结构。它能够实现某种“记忆功能”,是进行时间序列分析时最好的选择。
RNN 模型如下:
这个网络在 tt 时刻接收到输入 xtxt 之后,隐藏层的值是 stst,输出值是 otot。关键一点是 stst 的值不仅仅取决于 xtxt,还取决于 st−1st−1。
U,W,VU,W,V 这三个矩阵是我们的模型的线性关系参数,它在整个 RNN 网络中是共享的,这点和 DNN 很不相同。 也正因为是共享了,它体现
了 RNN 的模型的“循环反馈”的思想。
RNN 神经网络是定义在全连接神经网络上的,上图右侧每个圆代表 RNN Cell,里面的结构就是全连接神经网络,虽然画出了三个圆,但是其
实都是同一个网络,即同一个 Cell,这体现了参数共享。假设输入层有 ii 个神经元,隐藏层有 hh 个神经元,则 RNN Cell 的内部进行的运算为:
h(t)=σ(z(t))=σ(Uh×ix(t)+Wh×hh(t−1)+b)h(t)=σ(z(t))=σ(Uh×ix(t)+Wh×hh(t−1)+b)
h(t)h(t) 就是图中的 s(t)s(t),σσ 为 RNN 的激活函数,一般为 tanh, b 为线性关系的偏置。
隐藏层到输出层的表达式比较简单:
o(t)=Vh(t)+co(t)=Vh(t)+c
y^(t)=σ(o(t))y^(t)=σ(o(t))
通常由于 RNN 是识别类的分类模型,所以输出层的激活函数一般是 softmax。
将输入层到隐藏层之间的线性运算做个变形:
z(t)=Uh×ix(t)+Wh×hh(t−1)+b=[Uh×iWh×h][x(t)h(t−1)]+bz(t)=Uh×ix(t)+Wh×hh(t−1)+b=[Uh×iWh×h][x(t)h(t−1)]+b
可以发现,RNN Cell 用一个线性层就可以实现了,它的输入神经元有 h+ih+i 个,输出神经元有 hh 个。如下图所示:
上图是 RNN 最简单的一个 Cell,它只有一个隐藏层,其中输入由 xtxt 和 ht−1ht−1 组成,网络结构上仍属于全连接神经网络。
那如何定义多隐藏层的循环神经网络呢?
上面两个图的最后一个隐藏层都需要再接一个输出层,这里没有画出来。下面推导一下 RNN 的反向传播算法。
BTPP 算法将第 ll 层 tt 时刻的误差项 δltδtl 值沿两个方向传播,一个方向是其传递到上一层网络,得到 δl−1tδtl−1,这部分只和权重矩阵 UU 有关;
另一个是方向是将其沿时间线 t−1,t−2,...,1t−1,t−2,...,1 传递到初始时刻,得到 δlt−1,δlt−2,...,δl1δt−1l,δt−2l,...,δ1l,这部分只和权重矩阵 WW 有关。
对于 RNN,由于我们在序列的每个时刻都有损失函数,因此最终的损失 LL 为:
L=∑t=1TLtL=∑t=1TLt
这个反向传播过程其实很简单,重点是观察反向传播路径,发现有两条,以下图为例:
我们要求误差函数 LL 对 h21h12 的偏导数,可以发现反向传播由两条路径,一条来自 L1L1,另一条来自 L2L2,所以将连个路径的偏导数分别求出来,
然后相加就可以了,每个路径的偏导数求法就和 DNN 完全一样。设
下面举个例子,训练如下模型: