RNN循环神经网络–潘登同学的深度学习笔记
文章目录
RNN
DNN 都只能单独的取处理一个个的输入,前一个输入和后一个输入是完全没有关系的。但是,某些任务需要能够更好的处理序列的信息,即前面的输入和后面的输入是有关系的。比如,当我们在理解一句话意思时,孤立的理解这句话的每个词是不够的,我们需要处理这些词连接起来的整个序列; 当我们处理视频的时候,我们也不能只单独的去分析每一帧,而要分析这些帧连接起来的整个序列。
与词向量算法的区别, 词向量算法 是 将一句话的词全部加起来求平均得到句子的词向量,所以对于同一句话,里面的词颠倒顺序,完全词不达意,只要还是那几个字,结果就完全一致;
用语言来描述一下整个过程:
- 大体上还是与DNN、CNN等神经网络算法一致,x进,O出,中间还是隐藏层,当然要看具体做什么内容,如果做的是图像识别,那隐藏层夹杂CNN;
- 而对于序列问题来说,我们想做到后面的输出会受到前面输入的影响,就通过w矩阵来操作,当后面的输入进入隐藏层中时,前面输入通过隐藏层得出的结果会经过w矩阵,得到一个相当于偏置项的结果,再与后面的输入加和,最后做非线性变换…
如果将RNN展开,将会是如下情况
X t − 1 , X t , X t + 1 X_{t-1},X_t,X_{t+1} Xt−1,Xt,Xt+1分别每个时刻的输入, U U U表示输入层到隐藏层, S t − 1 、 S t 、 S t + 1 S_{t-1}、S_{t}、S_{t+1} St−1、St、St+1表示每个时刻隐藏层的输出结果, W W W表示前一时刻的隐藏结果作用的下一时刻的作用矩阵, V V V表示隐藏层到输出层的作用矩阵
RNN的数学表达式
O t = g ( S t ⋅ V ) S t = f ( X t ⋅ U + S t − 1 ⋅ W ) O_t = g(S_t \cdot V)\\ S_t = f(X_t \cdot U + S_{t-1} \cdot W) Ot=g(St⋅V)St=f(Xt⋅U+St−1⋅W)
RNN手写数字识别
主要思路: 把一张图片的一行视作一次输入,在第28次输入的时候,产生的结果就是最终我们想要的结果,所以在RNN的一层中,总共会有28个RNN节点(将RNN展开的话);
RNN的拼接操作
隐藏层的加和操作,可以理解为:
- 输入矩阵 U m × n U_{m \times n} Um×n 与 矩阵 W n × n W_{n \times n} Wn×n 上下拼接成 新矩阵 T m + n × n T_{m+n \times n} Tm+n×n
- 输入数据矩阵 X B S × m X_{BS \times m} XBS×m 与 上一时刻传递过来的 矩阵 S B S × n S_{BS \times n} SBS×n 左右拼接成 新矩阵 X S B S × m + n XS_{BS \times m+n} XSBS×m+n
- 然后两个矩阵相乘即可
然后这种操作其实也对应着一种名字Vanilla RNN
就是最基础的BasicRNNCell
LSTM 长短时记忆(Long Short Time Memory)
前面的BasicRNNCell
,每次传递到下一时刻时,都会携带前t时刻的信息与下一时刻的输入进行拼接再进入tanh
,那么离当前时刻越近的输入,带到后面的信息就越多,离当前时刻越远的信息带到后面就越少,很像我们之前说到过的动量梯度下降的那个优化器,当前的动量 = 0.9*上一时刻动量 + 梯度;这是题外话了,回到正题; 正是因为这样的原因,离当前时刻越远的输入,到后面携带的信息量越少,对应反向传播的时候,回到最开始处的梯度就越小,当整个LSTM的链越长,那么就会产生梯度消失…
为了解决前面提到的问题,产生了LSTM
可以看到,与BasicRNNCell
相比,多了三个sigmoid
和一些点乘、点加操作,而这些sigmoid
分别都有自己的名字
- 遗忘门
- 输入门
- 输出门
LSTM数学表达
-
遗忘门:
f t = σ ( W f ⋅ [ h t − 1 , x t ] + b f ) f_t = \sigma(W_f \cdot [h_{t-1}, x_t] + b_f) ft=σ(Wf⋅[ht−1,xt]+bf)
-
输入门:
i t = σ ( W i ⋅ [ h t − 1 , x t ] + b i ) C t ~ = t a n h ( W c ⋅ [ h t − 1 , x t ] + b C ) i_t = \sigma (W_i \cdot [h_{t-1},x_t] + b_i) \\ \tilde{C_t} = tanh(W_c \cdot [h_{t-1},x_t] + b_C) it=σ(Wi⋅[ht−1,xt]+bi)Ct~=tanh(Wc⋅[ht−1,xt]+bC)
-
长时记忆:
C t = f t × C t − 1 + i t × C t ~ C_t = f_t \times C_{t-1} + i_t \times \tilde{C_t} Ct=ft×Ct−1+it×Ct~
-
输出门:
o t = σ ( W o ⋅ [ h t − 1 , x t ] + b 0 ) h t = o t × t a n h ( C t ) o_t = \sigma(W_o \cdot [h_{t-1},x_t] + b0) h_t = o_t \times tanh(C_t) ot=σ(Wo⋅[ht−1,xt]+b0)ht=ot×tanh(Ct)
LSTM手写数字识别
最后结果是要比BasicRNN
好狠多的,有的时候测试集准确率接近了1.0
双向LSTM
GRU
相比LSTM,使用GRU能够达到相当的效果,并且相比之下更容易进行训练,能够很大程度上提高训练效率,因此很多时候会更倾向于使用GRU。根据 Cho, et al. 在 2014 年的介绍,GRU 旨在解决标准 RNN 中出现的梯度消失问题。GRU 也可以被视为 LSTM 的变体,因为它们基础的理念都是相似的,且在某些情况能产生同样出色的结果
相较于LSTM的六个公式,四个W矩阵,GRU只有四个公式,三个W矩阵,其中 r t r_t rt表示新学到的知识, z t z_t zt表示新学到的与之前的知识应该如何取舍,观察最后的输出公式, h t = ( 1 − z t ) ∗ h h − 1 + z t ∗ h t ~ h_t = (1-z_t)*h_{h-1} + z_t * \tilde{h_t} ht=(1−zt)∗hh−1+zt∗ht~,当 z t z_t zt越接近与1,表示应该忘掉更多的旧知识转向新知识(或者与新知识有关的旧知识 h t ~ \tilde{h_t} ht~)…
RNN里面应用的Topology结构
AI写唐诗
这里的AI写唐诗采用的是many to many的网络拓扑结构,在训练阶段,输入数据与输出标签是错一位的关系,即一个RNN 的输出标签是下一个RNN的输入;而在推理阶段,输出值直接作为下一时刻的输入值,如下图所示