7.循环神经网络(RNN) 基础
7.1 RNN(recurrent neural network)原理
词序其实是很重要的
![](http://upload-images.jianshu.io/upload_images/6162555-7b4a72a6f9ecafc3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/336)
中文中,这样的例子也很多。“怎么样投资白银”vs“白银投资怎么样”;“北京到上海的机票”vs“上海到北京的机票”。
设计RNNs的目的,就是处理序列数据。
在传统的神经网络模型中,是从输入层到隐含层再到输出层,层与层之间是全连接的,每层之间的节点是无连接的。但是这种普通的神经网络对于很多问题却无能无力。例如,你要预测句子的下一个单词是什么,一般需要用到前面的单词,因为一个句子中前后单词并不是独立的。RNNs之所以称为循环神经网路,即一个序列当前的输出与前面的输出也有关。具体的表现形式为网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐藏层之间的节点不再无连接而是有连接的,并且隐藏层的输入不仅包括输入层的输出还包括上一时刻隐藏层的输出。理论上,RNNs能够对任何长度的序列数据进行处理。
RNN was born in 1980s!
图灵机Turing machine可以看作等价于任何有限逻辑数学过程的终极强大逻辑机器。图灵机又称确定型图灵机,是英国数学家艾伦·图灵于1936年提出的一种抽象计算模型,其更抽象的意义为一种数学逻辑机。
turing-complete的定义:
A Turing Complete system means a system in which a program can be written that will find an answer (although with no guarantees regarding runtime or memory).
So, if somebody says "my new thing is Turing Complete" that means in principle (although often not in practice) it could be used to solve any computation problem.
神经图灵机(Neural Turing Machine)
![](http://upload-images.jianshu.io/upload_images/6162555-34cca8c6a957cf86.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/554)
我们知道,一个三层的前馈神经网络可以学到任何的函数,而RNN则是“turing-complete”的,它可以逼近任何算法。
RNN can approximate any algorithm
a recurrent neural network RNN is Turing complete and so can compute anything that can be computed.
RNN具有强大的计算和建模能力,因而只要合理建模,它就可以模拟任何计算过程。
RNN具有记忆能力。给RNN同样的输入,得到的输出可能是不一样的。
RNNs包含输入单元(Input units),输入集标记为{x0,x1,...,xt,xt+1,...},而输出单元(Output units)的输出集则被标记为{y0,y1,...,yt,yt+1.,..}。RNNs还包含隐藏单元(Hidden units),我们将其输出集标记为{h0,h1,...,ht,ht+1,...},这些隐藏单元完成了最为主要的工作。
![](http://upload-images.jianshu.io/upload_images/6162555-c241b388d93c7a3c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/554)
各个变量的含义:
![](http://upload-images.jianshu.io/upload_images/6162555-3a369a1dfc40b999.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/554)
展开以后形式:
![](http://upload-images.jianshu.io/upload_images/6162555-bccda9c7e407c98c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/554)
一个RNN的小例子:
![](http://upload-images.jianshu.io/upload_images/6162555-03d4a31fd3cbbb15.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/553)
把RNN做深(deep)
![](http://upload-images.jianshu.io/upload_images/6162555-700fc40c7ffc908d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/554)
字符级别RNN
![](http://upload-images.jianshu.io/upload_images/6162555-55a25b56c69b059f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/551)
char-rnn的代码
Torch版本
https://github.com/karpathy/char-rnn
Tensorflow版本
https://github.com/sherjilozair/char-rnn-tensorflow
7.3.1 双向RNN (Bidirectional RNN )
RNN既然能继承历史信息,是不是也能吸收点未来的信息呢?因为在序列信号分析中,如果我能预知未来,对识别一定也是有所帮助的。因此就有了双向RNN、双向LSTM,同时利用历史和未来的信息。
![](http://upload-images.jianshu.io/upload_images/6162555-773b31d43ea9788e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/554)
双向RNN
![](http://upload-images.jianshu.io/upload_images/6162555-bd68c64c7af8868d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/554)
值得一提的是,但由于RNN 建模中的遗忘性,最后一个 state 中包含的信息是有损的,且序列越靠前的信息损失可能越严重。一种比较可行的解决方法是同时训练两个RNN,一个正向学习,一个反向学习,将正向的和反向的最后一个state 对应向量 concate 后得到的向量作为最终产物。
![](http://upload-images.jianshu.io/upload_images/6162555-7b90ce2c1f8b0210.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/441)
对于正向RNN最后一个向量中记录的信息量从前往后依次增强,反向的最后一个state记录的信息从后往前依次增强,两者组合正好记录了比较完整的信息
7.3.2 LSTM(Long Short-term Memory)
名字很有意思,又长又短的记忆?其实不是,注意“Short-term”中间有一个“—”连接。代表LSTM本质上还是短期记忆(short-term memory),只是它是比较长一点的short-term memory。
![](http://upload-images.jianshu.io/upload_images/6162555-627ea5dbca81d1e5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/554)
由于LSTM有四个参数做输入,LSTM需要的参数量是一般的神经网络模型的4倍。
![](http://book.aqinet.cn/doc3.files/doc355238.png)
台湾大学李宏毅讲的LSTM的小例子,非常清晰。
https://www.youtube.com/watch?v=xCGidAeyS4M
LSTM在1997年由“Hochreiter & Schmidhuber”提出,目前已经成为RNN中的标准形式。
7.3.3 GRU(Gated Recurrent Unit)
LSTM的一个稍微简化一点的版本。只有两个gate,据说效果和LSTM差不多,但是参数少了1/3,不容易过拟合。
如果发现LSTM训练出来的模型过拟合比较严重,可以试试GRU
LSTM vs GRU
![](http://upload-images.jianshu.io/upload_images/6162555-41a069719c039aab.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/554)
相较于CNN,RNN训练过程较不稳定,训练难度和计算量都大得多。当然,RNN用GPU加速效果会比较明显。
![](http://upload-images.jianshu.io/upload_images/6162555-645be6f1af7f54ba.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/554)
RNN不好训练的原因
![](http://upload-images.jianshu.io/upload_images/6162555-05cff9a60ffd7a3c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/554)
weight被高频地使用,0.99的1000次方和1.01的1000次方有本质的区别。导致RNN的误差面(error surface)常常要么是很平坦要么是很陡峭(The error surface is either very flat or very steep)。
![](http://upload-images.jianshu.io/upload_images/6162555-a1e986d6af944c7b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/554)
1997年,LSTM的提出就是为了解决RNN的梯度弥散的问题(gradient vanish)。那么LSTM比普通的RNN好在哪呢?LSTM为什么能够解决gradient vanish的问题?
LSTM如何避免梯度消失:
![](http://upload-images.jianshu.io/upload_images/6162555-b91a6089ac503b62.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/550)
参考文献:
[1] Rafa Jozefowicz et al. An Empirical Exploration of Recurrent Network Architectures.
[2] Junyoung Chung et al. Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling.
虽然LSTM并没有解决梯度爆炸的问题,但是梯度膨胀(gradient explosion)不是个严重的问题,一般靠裁剪后的优化算法即可解决,比如gradient clipping(如果梯度的范数大于某个给定值,将梯度同比收缩),具体参考“梯度裁剪”。
经验:
训练LSTM要保证forget gate多数情况下 都是开启的;
97年最开始提出LSTM就是为了解决梯度弥散的问题,最开始LSTM是没有forget gate的,forget gate是后来才加上的。
本文首发于:人工智能A7论坛
转载请注明出处
作者:_木豆_
链接:https://www.jianshu.com/p/9f155515bdf0
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。