循环神经网络(RNN)

RNN

神经网络只能单独的取处理一个个的输入,前一个输入和后一个输入是完全没有关系的。但是,某些任务需要能够更好的处理序列的信息,即前面的输入和后面的输入是有关系的。

基础的神经网络只在层与层之间建立了权连接,RNN最大的不同之处就是在层之间的神经元之间也建立的权连接。

RNN时间维度权值共享,CNN空间维度权值共享

将输入截断成小片段输入RNN

语言模型:用于由上文预测下文
image Captioning CNN得到的向量V输入RNN

RNN存在的问题

梯度消失的问题
RNN网络的激活函数一般选用双曲正切,而不是sigmod函数,(RNN的激活函数除了双曲正切,RELU函数也用的非常多)原因在于RNN网络在求解时涉及时间序列上的大量求导运算,使用sigmod函数容易出现梯度消失,且sigmod的导数形式较为复杂。事实上,即使使用双曲正切函数,传统的RNN网络依然存在梯度消失问题。
无论是梯度消失还是梯度爆炸,都是源于网络结构太深,造成网络权重不稳定,从本质上来讲是因为梯度反向传播中的连乘效应,类似于:0.99^{100}=0.36,于是梯度越来越小,开始消失,另一种极端情况就是1.1^{100}=13780
长期依赖的问题还有一个问题是无法“记忆”长时间序列上的信息,这个bug直到LSTM上引入了单元状态后才算较好地解决

LSTM

下面来了解一下LSTM(long short-term memory)。长短期记忆网络是RNN的一种变体,RNN由于梯度消失的原因只能有短期记忆,LSTM网络通过精妙的门控制将短期记忆与长期记忆结合起来,并且一定程度上解决了梯度消失的问题。


遗忘门:主要控制是否遗忘上一层的记忆细胞状态输入分别是当前时间步序列数据,上一时间步的隐藏状态,进行矩阵相乘,经sigmoid激活后,获得一个值域在[0, 1]的输出F,再跟上一层记忆细胞进行对应元素相乘,输出F中越接近0,代表需要遗忘上层记忆细胞的元素。
候选记忆细胞:这里的区别在于将sigmoid函数换成tanh激活函数,因此输出的值域在[-1, 1]。
输入门:与遗忘门类似,也是经过sigmoid激活后,获得一个值域在[0, 1]的输出。它用于控制当前输入X经过候选记忆细胞如何流入当前时间步的记忆细胞。 如果输入门输出接近为0,而遗忘门接近为1,则当前记忆细胞一直保存过去状态
输出门:也是通过sigmoid激活,获得一个值域在[0,1]的输出。主要控制记忆细胞到下一时间步隐藏状态的信息流动

其中,四个蓝色的小矩形就是普通神经网络的隐藏层结构,其中第一、二和四的激活函数是sigmoid,第三个的激活函数是tanh。t时刻的输入X和t-1时刻的输出h(t-1)进行拼接,然后输入cell中,其实可以这样理解,我们的输入X(t)分别feed进了四个小蓝矩形中,每个小黄矩形中进行的运算和正常的神经网络的计算一样(矩阵乘法),有关记忆的部分完全由各种门结构来控制(就是0和1),同时在输入时不仅仅有原始的数据集,同时还加入了上一个数据的输出结果,也就是h(t-1),那么讲来LSTM和正常的神经网络类似,只是在输入和输出上加入了一点东西。cell中可以大体分为两条横线,上面的横线用来控制长时记忆,下面的横线用来控制短时记忆。



f_{t}=\sigma\left(W_{f} \cdot\left[h_{t-1}, x_{t}\right]+b_{f}\right)
i_{t}=\sigma\left(W_{i} \cdot \left[h_{t-1}, x_{t}\right]+b_{i}\right)
o_{t}=\sigma\left(W_{o}\left[h_{t-1}, x_{t}\right]+b_{o}\right)
\tilde{C}_{t}=\tanh \left(W_{C} \cdot\left[h_{t-1}, x_{t}\right]+b_{C}\right)
C_{t+1}=f_{t} * w_{t}+i_{t} * \tilde{C}
h_{t}=o_{t} * \tanh \left(C_{t}\right)

不过LSTM依旧不能解决梯度“爆炸”的问题。但似乎梯度爆炸相对于梯度消失,问题没有那么严重。一般靠裁剪后的优化算法即可解决,比如gradient clipping(如果梯度的范数大于某个给定值,将梯度同比收缩)。
梯度剪裁的方法一般有两种:
1.一种是当梯度的某个维度绝对值大于某个上限的时候,就剪裁为上限。
2.另一种是梯度的L2范数大于上限后,让梯度除以范数,避免过大。

LSTM是一种拥有三个“门”的特殊网络结构,包括遗忘门、输入门、输出门。所谓“门”结构就是一个使用sigmoid神经网络和一个按位做乘法的操作,这两个操作合在一起就是一个“门”结构。

*********g=候选记忆细胞**************
遗忘门,选择被遗忘的信息

输入门,选择那些信息被保留

更新cell中的信息

输出门,输出


GRU结构

GRU是LSTM网络的一种效果很好的变体,它较LSTM网络的结构更加简单,而且效果也很好,因此也是当前非常流形的一种网络。GRU既然是LSTM的变体,因此也是可以解决RNN网络中的长依赖问题。
在LSTM中引入了三个门函数:输入门、遗忘门和输出门来控制输入值、记忆值和输出值。而在GRU模型中只有两个门:分别是更新门和重置门。具体结构如下图所示:

image.png

BILSTM

如果能像访问过去的上下文信息一样,访问未来的上下文,这样对于许多序列标注任务是非常有益的。例如,在最特殊字符分类的时候,如果能像知道这个字母之前的字母一样,知道将要来的字母,这将非常有帮助。

双向循环神经网络(BRNN)的基本思想是提出每一个训练序列向前和向后分别是两个循环神经网络(RNN),而且这两个都连接着一个输出层。这个结构提供给输出层输入序列中每一个点的完整的过去和未来的上下文信息。下图展示的是一个沿着时间展开的双向循环神经网络。六个独特的权值在每一个时步被重复的利用,六个权值分别对应:输入到向前和向后隐含层(w1, w3),隐含层到隐含层自己(w2, w5),向前和向后隐含层到输出层(w4, w6)。值得注意的是:向前和向后隐含层之间没有信息流,这保证了展开图是非循环的。

tf.nn.rnn_cell.BasicLSTMCell()来实现BILSTM

image.png

深层循环神经网络(DRNN)

tf.rnn_cell.MultiRNNCell(lstm * number_of_layer)来构建DRNN,其中number_of_layer表示了有多少层
tf.nn.rnn_cell.DropoutWrapper来实现dropout功能

image.png

Text-RNN的原理

CNN的核心点在于可以捕获信息的局部相关性,具体到文本分类任务中可以利用CNN来提取句子中类似N-Gram的关键信息。

tensorflow lstm预测正弦函数

import numpy as np
import tensorflow as tf
from tensorflow.contrib.learn.python.learn.estimators.estimator import SKCompat
from tensorflow.python.ops import array_ops as array_ops_
import matplotlib.pyplot as plt
learn = tf.contrib.learn

#### 1. 设置神经网络的参数。

HIDDEN_SIZE = 30
NUM_LAYERS = 2

TIMESTEPS = 10
TRAINING_STEPS = 3000
BATCH_SIZE = 32

TRAINING_EXAMPLES = 10000
TESTING_EXAMPLES = 1000
SAMPLE_GAP = 0.01

#### 2. 定义生成正弦数据的函数。

def generate_data(seq):
    X = []
    y = []

    for i in range(len(seq) - TIMESTEPS - 1):
        X.append([seq[i: i + TIMESTEPS]])
        y.append([seq[i + TIMESTEPS]])
    return np.array(X, dtype=np.float32), np.array(y, dtype=np.float32)

#### 3. 定义lstm模型。

def lstm_model(X, y):/;;;p
    lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(HIDDEN_SIZE)
    cell = tf.nn.rnn_cell.MultiRNNCell([lstm_cell] * NUM_LAYERS)
    x_ = tf.unpack(X, axis=1)

    output, _ = tf.nn.rnn(cell, x_, dtype=tf.float32)
    output = output[-1]
    
    # 通过无激活函数的全联接层计算线性回归,并将数据压缩成一维数组的结构。
    predictions = tf.contrib.layers.fully_connected(output, 1, None)
    predictions = array_ops_.squeeze(predictions, squeeze_dims=[1])
    loss = tf.contrib.losses.mean_squared_error(predictions, y)
    
    train_op = tf.contrib.layers.optimize_loss(
        loss, tf.contrib.framework.get_global_step(),
        optimizer="Adagrad", learning_rate=0.1)

    return predictions, loss, train_op

#### 4. 进行训练。

# 封装之前定义的lstm。
regressor = SKCompat(learn.Estimator(model_fn=lstm_model,model_dir="Models/model_2"))

# 生成数据。
test_start = TRAINING_EXAMPLES * SAMPLE_GAP
test_end = (TRAINING_EXAMPLES + TESTING_EXAMPLES) * SAMPLE_GAP
train_X, train_y = generate_data(np.sin(np.linspace(
    0, test_start, TRAINING_EXAMPLES, dtype=np.float32)))
test_X, test_y = generate_data(np.sin(np.linspace(
    test_start, test_end, TESTING_EXAMPLES, dtype=np.float32)))

# 拟合数据。
regressor.fit(train_X, train_y, batch_size=BATCH_SIZE, steps=TRAINING_STEPS)

# 计算预测值。
predicted = [[pred] for pred in regressor.predict(test_X)]

# 计算MSE。
rmse = np.sqrt(((predicted - test_y) ** 2).mean(axis=0))
print ("Mean Square Error is: %f" % rmse[0])

#### 5. 画出预测值和真实值的曲线。

plot_predicted, = plt.plot(predicted, label='predicted')
plot_test, = plt.plot(test_y, label='real_sin')
plt.legend([plot_predicted, plot_test],['predicted', 'real_sin'])
plt.show()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容