循环神经网络, Recurrent neural network, RNN
RNN简介
起源于1982年的霍普菲尔德网络。
RNN的主要用途是处理和预测序列数据。应用于语音识别、语言模型、机器翻译以及时序分析等问题。
CNN中隐藏层中的节点是无连接的。RNN隐藏层的输入不仅包括输入层的输出,也包括上一时刻隐藏层的输出。
前向传播
损失函数为所有时刻上损失函数的总和。
使用numpy库模拟前向传播
示意图:
代码:
1 | import numpy as np |
当循环体过多时,会发生梯度消失问题。
LTSM
RNN中一个重要结构:长短时记忆网络, long short-term memory, LSTM
1997年提出,为了解决长期依赖问题(long-term dependencies)
LSTM是一种特殊的循环体结构,拥有三个门:输入门、遗忘门、输出门。
之所以是门,是因为使用了全连接网络+sigmoid激活函数,通过[0,1]内的输出来决定有多少信息可以通过这个门。
遗忘门的作用是使得RNN忘记之前没有用的信息,遗忘门根据当前的输入x(t)、上一时刻的状态c(t-1)和上一时刻的输出h(t-1)来决定哪一部分记忆需要被遗忘。
输入门的作用是补充最新的记忆,输入们同样通过当前的输入x(t)、上一时刻的状态c(t-1)和上一时刻的输出h(t-1)来决定哪一部分当前信息进入这一时刻的状态中。
通过输入门和遗忘门,LSTM结构可以更加有效的决定哪些信息应该被遗忘,哪些信息应该得到保留,即得到当前状态c(t)。
输出门会根据当前的输入x(t)、这一时刻的状态c(t)和上一时刻的输出h(t-1)来决定这一时刻的输出h(t)
伪代码如下:
1 | lstm = rnn_cell.BasicLSTMCell(lstm_hidden_size) |
RNN的变种
双向RNN和深层RNN
双向循环神经网络bidirectional RNN,使得当前时刻的输出不仅与上一时刻的状态有关,也与后一时刻的状态有关。使用2个RNN进行组合。
深层循环神经网络deepRNN,将每一时刻的循环体重复多次。不同层的参数不同,而不同时刻同一层的参数相同。
1 | lstm = rnn_cell.BasicLSTMCell(lstm_size) |
RNN的Dropout
1 | lstm = rnn_cell.BasicLSTMCell(lstm_size) |
RNN样例应用
自然语言建模
一个句子看作是一个单词的序列,一个句子出现的概率为
1 | p(S)=p(w1,w2,w3,...,wm) |
以上的每一个p均为语言模型的一个参数,为了估计参数取值,常见方法有:n-gram方法、决策树、最大熵模型、条件随机场、神经网络语言模型等等。
n-gram中的n一般取1,2,3,分别称为unigram、bigram(常用)、trigram。
语言模型的评价指标为复杂度(perplexity),表示平均分支系数(average branch factor),模型预测下一个词时的平均可选择数量。
PTB文本数据集
PTB(Penn Treebank Dataset) 下载地址
使用tar zxvf simple-examples.tgz
解压
数据使用代码
1 | import tensorflow as tf |
输出如下:
1 | 929589 |
- 数据集中包含929589个单词
- 每次单词有特有的ID,每个句子的结束标识为2
- 截断大小为5:代表RNN的输入最多只有5个元素,过多会导致梯度消失
- batch_size为4:代表得到几批数据
- 会自动生成每个batch对应的答案,代表当前单词的后一个单词
完整的RNN语言模型代码
1 | import numpy as np |
时间序列预测
TFLearn IRIS代码实例
1 | from sklearn import model_selection |
预测sin曲线
1 | import numpy as np |