RNN及其简单Python代码示例

来源:互联网 发布:vivo清除所有数据密码 编辑:程序博客网 时间:2024/05/15 13:39

1 概述

递归神经网络是时间递归神经网络(recurrent neural network)和结构递归神经网络(recursive neural network)的总称。RNN一般指代时间递归神经网络。

RNN早先被提到的可以追溯到1989年Axel Cleeremans的论文。
详情查看:http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.160.2979&rep=rep1&type=pdf
RNN被提出的初衷是用来处理序列数据的。
RNN相对于传统神经网络最大的不同是神经元的输入的改变。RNN隐藏层神经元的输入不止是上一层神经元的输出,还包括了本层的输出。
但是鉴于RNN误差反向传播时候梯度消失的问题。1997年Sepp Hochreiter等人提出了典型的LSTM网络。
详情查看:http://www.bioinf.jku.at/publications/older/2604.pdf
LMST是RNN的升级版,它的隐藏层神经元的输入和输出会在RNN的基础上做进一步的处理,在本文末有提到。

RNN背后的思想是利用顺序信息。它包含循环的网络,允许信息的持久化。

2 优缺点

优点:时间递归神经网络可以描述动态时间行为,因为和前馈神经网络接受较特定结构的输入不同,RNN将状态在自身网络中循环传递,因此可以接受更广泛的时间序列结构输入。

缺点:简单递归神经网络无法处理随着递归,梯度爆炸或者梯度消失的问题,并且难以捕捉长期时间关联;有效的处理方法是忘掉错误的信息,记住正确的信息。LSTM能够比较好的解决这个问题。

3 应用

RNN已经被在实践中证明对NLP是非常成功的。如词向量表达,语句合法性检查,词性标注等。在RNN中,目前使用最广泛最成功的模型是LSTM模型。
基于LSTM的系统可以学习翻译语言、控制机器人、图像分析、文档摘要、语音识别图像识别、手写识别、控制聊天机器人、预测疾病、点击率和股票、合成音乐等等任务。举个例子,在2015年,谷歌通过基于CTC训练的LSTM程序大幅提升了安卓手机和其他设备中语音识别的能力,使用了我的实验室在2006年发表的方法。百度也使用了CTC;苹果的iPhone在QucikType和Siri中使用了LSTM;微软不仅将LSTM用于语音识别,还将这一技术用于虚拟对话形象生成和编写程序代码等等。亚马逊Alexa通过双向LSTM在家中与你交流,而谷歌使用LSTM的范围更加广泛,它可以生成图像字幕,自动回复电子邮件,它包含在新的智能助手Allo中,也显著地提高了谷歌翻译的质量(从2016年开始)。事实上,谷歌数据中心的很大一部分计算资源现在都在执行LSTM任务。
内容链接地址:https://www.zhihu.com/question/37082800/answer/173870605

4 相关概念

序列: 序列是被排成一列的对象(或事件)。可以是一句话,一串数字等。RNN训练数据时,会以序列为单位训练数据。同一序列中的每次训练代表一个时刻t。

5 RNN网路结构

从上图我们可以看出,RNN隐藏层神经元的连接方式和普通神经网路的连接方式有一个非常明显的区别,就是同一层的神经元的输出也成为了这一层神经元的输入。当然同一时刻的输出是不可能作为这个时刻的输入的。所以是前一个时刻(t-1)的输出作为这个时刻(t)的输入。

上图就是一个序列的结构展开示意图。

6 公式推导

设输入层到隐层的权重矩阵为V;隐层自循环的权重矩阵为U;隐层到输出层的权重矩阵为W;对应的偏置为bh,by;隐层的输出为h;z表示激活前对应的加权和。假设为三层网络。

1)隐层输入变为:

zt=xtV+ht1U+bh

2)隐层最终输出变为:
ht=g(zt)

说明:这个序列的最终的输出概率基于之前所有的输出。距离当前时间越长,越早输入的序列,在更新后的状态中所占权重越小,从而表现出时间相关性。

其它部分与传统BP神经网络的推导没有太大区别,这里不再赘述了。

7 Python代码示例

例:用RNN来实现一个八位的二进制数加法运算。
代码实现地址:http://iamtrask.github.io/2015/11/15/anyone-can-code-lstm/

1) 网络的输入:

#输入是(a[i],b[i]) 其中i>=0 且 i<8a_int = np.random.randint(largest_number/2) # int versiona = int2binary[a_int] # binary encodingb_int = np.random.randint(largest_number/2) # int versionb = int2binary[b_int] # binary encoding

2) 计算y值:

#真实值y (c[i]) i>=0 且 i<8c_int = a_int + b_intc = int2binary[c_int]

3)隐藏层:

#隐藏层1层 16个神经元hidden_dim = 16

4)输入层和隐藏层的连接方式,隐藏层和隐藏层的连接方式,隐藏层和输出层的连接方式:

输入层和隐藏层采用全连接;隐藏层中,位于同一层的神经元相互连接;隐藏层和输出层也采用全连接。

5)隐藏层和输出层神经元的输入值、输出值:

#隐藏层神经元的输入为输入层加上一时刻(t-1)神经元的输出:layer_1=sigmoid(np.dot(X,synapse_0)+np.dot(layer_1_values[-1],synapse_h))#输出层的输入、输出:layer_2 = sigmoid(np.dot(layer_1,synapse_1))

6)计算权重的调整值并迭代

X = np.array([[a[position],b[position]]])layer_1 = layer_1_values[-position-1]prev_layer_1 = layer_1_values[-position-2]# error at output layerlayer_2_delta = layer_2_deltas[-position-1]# error at hidden layerlayer_1_delta = (future_layer_1_delta.dot(synapse_h.T) + layer_2_delta.dot(synapse_1.T)) * sigmoid_output_to_derivative(layer_1)# 更新一个序列的w值并累加       synapse_1_update+=np.atleast_2d(layer_1).T.dot(layer_2_delta)synapse_h_update+=np.atleast_2d(prev_layer_1).T.dot(layer_1_delta)

7)查看最终训练结果:

#这是训练10000次的运行效果Error: [ 3.45638663]Pred: [0 0 0 0 0 0 0 1]True: [0 1 0 0 0 1 0 1]9  + 60  =  1------------Error: [ 3.63389116]Pred: [1 1 1 1 1 1 1 1]True: [0 0 1 1 1 1 1 1]28  + 35  =  255------------Error: [ 3.91366595]Pred: [0 1 0 0 1 0 0 0]True: [1 0 1 0 0 0 0 0]116  + 44  =  72------------Error: [ 3.72191702]Pred: [1 1 0 1 1 1 1 1]True: [0 1 0 0 1 1 0 1]4  + 73  =  223------------Error: [ 3.5852713]Pred: [0 0 0 0 1 0 0 0]True: [0 1 0 1 0 0 1 0]71  + 11  =  8------------Error: [ 2.53352328]Pred: [1 0 1 0 0 0 1 0]True: [1 1 0 0 0 0 1 0]81  + 113  =  162------------Error: [ 0.57691441]Pred: [0 1 0 1 0 0 0 1]True: [0 1 0 1 0 0 0 1]81  + 0  =  81------------Error: [ 1.42589952]Pred: [1 0 0 0 0 0 0 1]True: [1 0 0 0 0 0 0 1]4  + 125  =  129------------Error: [ 0.47477457]Pred: [0 0 1 1 1 0 0 0]True: [0 0 1 1 1 0 0 0]39  + 17  =  56------------Error: [ 0.21595037]Pred: [0 0 0 0 1 1 1 0]True: [0 0 0 0 1 1 1 0]11  + 3  =  14------------

8 扩展:LSTM

鉴于简单RNN出现的梯度消失问题,又推出了一种用来解决这些问题的升级版网络:LSTM网络。
LSTM网络和RNN的主要区别就是隐藏层神经元换成了如下图的block。

图中的几个参数说明:
1.Cell 对各个门的操作做记录和保存,它的激活函数是恒等定式 y = x,是为了防止梯度消失。
2.input Gate:输入门是负责控制输入信号的。
3.Output Gate:输出门市负责控制输出信号的。
4.Forget Gate:忘记门是用来决定是否忘记信号的。
每一个门的输入都来自不同的信号,组成成分复杂。

LSTM详细讲解请移步这里…

原创粉丝点击