(二,3NN-QI)Thensorflow——循环神经网络

第一章:神经网络理论知识

【第二章】Tensorflow

三、 循环神经网络

循环神经网络用于处理序列型数据,在上一篇文章中,卷积神经网络是用来处理图片型数据,这样的数据集,样本和样本之间是独立,没有任何关系,但是例如自然语言,时间序列这样的数据,样本和样本之间是相互关联的,所以在处理数据的时候并不能单独的处理。所以,神经网络在处理当前的数据的时候也会收到上一个节点的状态,同时在得出当前输出的同时也产出了下一个状态。但是如果序列过长之前节点的状态当当前的影响将会非常弱,所以传统的RNN在处理很长的时间序列的问题上表现的并不是很好。Seqq和Schmiduhber在1997年提出了一种结构LTSM——长短期记忆神经网络,这种网络结果增加了一种“遗忘门”结构,遗忘门会决定什么应该记住,什么应该遗忘,从而保持前期数据的影响。具体的理论内容,请看【第一章;
神经网络基础】
下面通过一个实例来说明循环神经网络的实现,预测sinx的函数值。

第一部分:导入模块

# -*- coding:utf-8 -*-
import numpy as np
import tensorflow as tf
# 加载matplotlib工具包,使用该工具可以对预测的sin函数曲线进行绘图。
import matplotlib as mpl
mpl.use('TKAgg')
from matplotlib import pyplot as plt

第二部分:设置参数

HIDDEN_SIZE = 30                      # LSTM中隐藏节点的个数
NUM_LAYERS = 2                        # LSTM的层数

??? 不明白30和2表示的是什么

TIMESTEPS = 10                        # 循环神经网络的训练序列长度

用前10个数据去预测后一个数据

TRAINING_STEPS = 10000                # 训练轮数
BATCH_SIZE = 32                       # batch大小
TRAINING_EXAMPLES = 10000             # 训练数据个数。
TESTING_EXAMPLES = 1000               # 测试数据个数。
SAMPLE_GAP = 0.01                     # 采样间隔。

第三部分:设置生成数据集函数
将输入和序列seq分别设置为训练数据X和目标数据Y

def generate_data(seq):
    X = []
    Y = []
    # 序列的第i项和后面的TIMESTEPS-1项合在一起作为输入:第1+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)

第四部分:添加Lstm结构

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)
    # outputs是顶层LSTM在每一步的输出结果,它的维度是[batch_size,time,HIDDEN_SIZE].
    # 在本问题中只关注最后一个时刻的输出结果。
    outputs = outputs[:,-1,:]

    # 对LSTM网络的输出再加一层全连接层计算损失。注意这里默认的损失为平均平方差损失函数。
    predictions = tf.contrib.layers.fully_connected(
        outputs, 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 train(sess,train_X,train_y):
    # 将训练数据以及数据集的方式提供给计算图
    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'):
        predictions,loss,train_op = lstm_model(X,Y,True)

    # 初始化变量。
    sess.run(tf.global_variables_initializer())
    for i in range(TRAINING_STEPS):
        _, l = sess.run([train_op,loss])
        if i % 100 == 0:
            print("train step:"+str(i)+",loss"+str(l))

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("Mean Square Error is: %f" % rmse)

    #对预测的sin函数曲线进行绘图,得到的结果如图所示。
    plt.figure()
    plt.plot(predictions,label = 'predictions',linestyle=':',color='black')
    plt.plot(labels,label = "real_sin",linestyle='-.',color='yellow')
    plt.legend()
    plt.show()

'''
用正选函数生成训练和测试数据集合.
numpy、linspace 函数可以创建一个等差序列的数组,它常用的参参数有三个参数,第一个参数表示起始值
第二个参数表示终止值,第三个参数表示数列的长度。例如,linespace(1,10,10),产生的数组是
array([1,2,3,4,5,6,7,8,9,10]).
'''
test_start = (TRAINING_EXAMPLES + TIMESTEPS)* SAMPLE_GAP
test_end = test_start + (TESTING_EXAMPLES+TIMESTEPS)*SAMPLE_GAP
train_X,train_y = generate_data(np.sin(np.linspace(
   0, test_start,TRAINING_EXAMPLES + TIMESTEPS,dtype=np.float32
)))
test_X,test_y = generate_data(np.sin(np.linspace(
    test_start,test_end,TESTING_EXAMPLES + TIMESTEPS,dtype=np.float32
)))

with tf.Session() as sess:
    # 训练模型。
    train(sess,train_X,train_y)
    # 使用训练好的模型对测试数据进行预测。
    run_eval(sess,test_X,test_y)
  • 结果
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值