循环神经网络

循环神经网络的主要用途是处理和预测序列数据。

RNN:recurrent neural network:循环神经网络

在这里插入图片描述
循环神经网络的主体结构A 的输入除了来自输入层 x t x_t xt,还有一个循环的边来提供上一时刻的隐藏状态( hidden state) h t − 1 h_{t-1} ht1 。在每一个时刻,循环神经网络的模块A 在读取了 x t x_t xt h t − 1 h_{t-1} ht1之后会生成新的隐藏状态 h t h_t ht ,并产生本时刻的输出 o t o_t ot

LSTM:long short-term memory:长短时记忆网络

在这里插入图片描述

“门”的结构就是一个使用sigmoid 神经网络和一个按位做乘法的操作。经过激活函数sigmoid输出0-1之间的数,如果输出接近0就被放弃,如果输出接近1就被保留。
在这里插入图片描述
通过tf.nn.rnn cell.BasicLSTMCell类可以定义一个LSTM结构。

循环神经网络的变种

双向循环神经网络

在有些问题中, 当前时刻的输出不仅和之前的状态有关系,也和之后的状态相关。这时就需要使用双向循环神经网络( bidirectional RNN )来解决这类问题。
在这里插入图片描述
在每一个时刻t ,输入会同时提供给这两个方向相反的循环神经网络。两个网络独立进行计算,各自产生该时刻的新状态和输出,双向循环网络的最终输出是这两个单向循环神经网络的输出的简单拼接。

深层循环神经网络(Deep RNN)

为了增强模型的表达能力,可以在网络中设置多个循环层,将每层循环网络的输出传给下一层进行处理。
在这里插入图片描述
在一个L 层的深层循环网络中,每一时刻的输入X1 到输出01 之间有L 个循环体,网络因此可以从输入中抽取更加高层的信息。
在Tensor Flow 中只需要在BasicLSTMCell 的基础上再封装一层MultiRNNCell 就可以非常容易地实现深层循环神经网络了

lstm_cell= tf.nn.rnn_cell.BasicLSTMCell
stacked_lstm = tf.nn.rnn_cell.MultiRNNCell([lstm_cell(lstm_size) for _ in range(number_of_layers)])

循环神经网络中的dropout

dropout 可以避免过拟合问题,从而使得模型在测试数据上的效果更好。
卷积神经网络只在最后的全连接层中使用dropout ,而循环神经网络一般只在不同层循环体结构之间使用dropout ,而不在同一层的循环体结构之间使用。也就是说从时刻t-1 传递
到时刻t 时,循环神经网络不会进行状态的dropout ;而在同一个时刻t 中,不同层循环体之间会使用dropout 。
在这里插入图片描述
使用tf.nn.rnn_cell.DropoutWrapper 类实现dropout功能。

预测正弦函数样例代码

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt

#定义RNN的参数
HIDDEN_SIZE = 30                            # LSTM中隐藏节点的个数。
NUM_LAYERS = 2                              # LSTM的层数。
TIMESTEPS = 10                              # 循环神经网络的训练序列长度。
TRAINING_STEPS = 10000                      # 训练轮数。
BATCH_SIZE = 32                             # batch大小。
TRAINING_EXAMPLES = 10000                   # 训练数据个数。
TESTING_EXAMPLES = 1000                     # 测试数据个数。
SAMPLE_GAP = 0.01                           # 采样间隔。

#产生正弦数据
def generate_data(seq):
    X = []
    y = []
    # 序列的第i项和后面的TIMESTEPS-1项合在一起作为输入;第i + TIMESTEPS项作为输
    # 出。即用sin函数前面的TIMESTEPS个点的信息,预测第i + TIMESTEPS个点的函数值。
    for i in range(len(seq) - TIMESTEPS):
        X.append([seq[i: i + TIMESTEPS]])
        y.append([seq[i + TIMESTEPS]])
    return np.array(X, dtype=np.float32), np.array(y, dtype=np.float32)  

#用正弦函数生成训练和测试数据集合。
test_start = (TRAINING_EXAMPLES + TIMESTEPS) * SAMPLE_GAP
test_end = test_start + (TESTING_EXAMPLES + TIMESTEPS) * SAMPLE_GAP
'''
    numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
    在指定的间隔内返回均匀间隔的数字。
    返回num均匀分布的样本,在[start, stop]。
    num : int, optional(可选)生成的样本数,默认是50。必须是非负。
    endpoint : bool, optional如果是真,则一定包括stop,如果为False,一定不会有stop
    
'''
train_X, train_y = generate_data(np.sin(np.linspace(
    0, test_start, TRAINING_EXAMPLES + TIMESTEPS, dtype=np.float32)))
print(train_X, train_y)
test_X, test_y = generate_data(np.sin(np.linspace(
    test_start, test_end, TESTING_EXAMPLES + TIMESTEPS, dtype=np.float32)))
#定义网络结构和优化步骤
def lstm_model(X, y, is_training):
    #使用多层的LSTM结构。
    cell = tf.nn.rnn_cell.MultiRNNCell([
        tf.nn.rnn_cell.BasicLSTMCell(HIDDEN_SIZE) 
        for _ in range(NUM_LAYERS)])    

    #使用TensorFlow接口将多层的LSTM结构连接成RNN网络并计算其前向传播结果。
    outputs, _ = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32)
    output = outputs[:, -1, :]

    #对LSTM网络的输出再做加一层全链接层并计算损失。注意这里默认的损失为平均
    #平方差损失函数。
    predictions = tf.contrib.layers.fully_connected(
        output, 1, activation_fn=None)
    
    #只在训练时计算损失函数和优化步骤。测试时直接返回预测结果。
    if not is_training:
        return predictions, None, None
        
    #计算损失函数。
    loss = tf.losses.mean_squared_error(labels=y, predictions=predictions)

    #创建模型优化器并得到优化步骤。
    train_op = tf.contrib.layers.optimize_loss(
        loss, tf.train.get_global_step(),
        optimizer="Adagrad", learning_rate=0.1)
    return predictions, loss, train_op
    
#定义测试方法
def run_eval(sess, test_X, test_y):
    #将测试数据以数据集的方式提供给计算图。
    ds = tf.data.Dataset.from_tensor_slices((test_X, test_y))
    ds = ds.batch(1)
    X, y = ds.make_one_shot_iterator().get_next()
    
    #调用模型得到计算结果。这里不需要输入真实的y值。
    with tf.variable_scope("model", reuse=True):
        prediction, _, _ = lstm_model(X, [0.0], False)
    
    #将预测结果存入一个数组。
    predictions = []
    labels = []
    for i in range(TESTING_EXAMPLES):
        p, l = sess.run([prediction, y])
        predictions.append(p)
        labels.append(l)

    #计算rmse作为评价指标。
    predictions = np.array(predictions).squeeze()
    labels = np.array(labels).squeeze()
    rmse = np.sqrt(((predictions - labels) ** 2).mean(axis=0))
    print("Root Mean Square Error is: %f" % rmse)
    
    #对预测的sin函数曲线进行绘图。
    plt.figure()
    plt.plot(predictions, label='predictions')
    plt.plot(labels, label='real_sin')
    plt.legend()
    plt.show()

#执行训练和测试
#将训练数据以数据集的方式提供给计算图。
ds = tf.data.Dataset.from_tensor_slices((train_X, train_y))
ds = ds.repeat().shuffle(1000).batch(BATCH_SIZE)
X, y = ds.make_one_shot_iterator().get_next()

#定义模型,得到预测结果、损失函数,和训练操作。
with tf.variable_scope("model"):
    _, loss, train_op = lstm_model(X, y, True)
    
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    
    #测试在训练之前的模型效果。
    print "Evaluate model before training."
    run_eval(sess, test_X, test_y)
    
    #训练模型。
    for i in range(TRAINING_STEPS):
        _, l = sess.run([train_op, loss])
        if i % 1000 == 0:
            print("train step: " + str(i) + ", loss: " + str(l))
    
    #使用训练好的模型对测试数据进行预测。
    print "Evaluate model after training."
    run_eval(sess, test_X, test_y)

参考:
《TensorFlow实战Google深度学习框架2.0》第8章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值