RNN全称循环神经网络(Recurrent Neural Networks),对于处理有序的数据很有效,预测序列化的数据

在传统的神经网络模型中,从输入层到隐含层再到输出层,层与层之间是全连接的,每层之间的节点是无连接的。但是这种普通的神经网络对于很多关于时间序列的问题却无能无力。例如,你要预测句子的下一个单词是什么,一般需要用到前面的单词,因为一个句子中前后单词并不是独立的。RNN之所以称为循环神经网路,即一个序列当前的输出与前面的输出也有关。具体的表现形式为网络会对前面时刻的信息进行记忆并应用于当前输出的计算中,即隐藏层之间的节点不再无连接而是有连接的,并且隐藏层的输入不仅包括输入层的输出还包括上一时刻隐藏层的输出。  

tensorflow 双向LSTM_Memory

tensorflow 双向LSTM_Memory_02

序列数据,预测result0的时候是基于Data0,如果数据是有顺序的

那么NN也可以分析出来数据中的关联,就会产生很好的效果

如果让NN了解数据的关联?——记住之前发生的事情

tensorflow 双向LSTM_tensorflow 双向LSTM_03

计算Data0之后,把分析结果存入记忆,分析Data1的时候,NN会产生新的记忆,但是两个记忆没有关联,此时就可以将Data0的记忆调用过来,NN会将之前的记忆都累积起来,继续分析则继续累积。

普通的RNN,如果要预测的序列是一个很长的序列,则反向传播过程中存在梯度消失和梯度爆炸现象。

为了解决上述问题,提出了 LSTM RNN

Long Short-Term Memory,长短期记忆RNN

LSTM的改进:增加了三个控制器——输入控制、输出控制、忘记控制

tensorflow 双向LSTM_数据_04

tensorflow 双向LSTM_数据_05

输入:考虑要不要将分线剧情加入到主线剧情,如果某些分线剧情比较重要,那么就会按重要程度,将其写入总线剧情,再进行分析。

忘记:如果分线剧情改变了我们对主线剧情的认知,那么忘记剧情就会对之前的剧情进行忘记,按比例替换为现在的新剧情。

所以主线剧情的更新就取决于输入控制和忘记控制。

输出:基于目前的主线剧情和分线剧情,判断到底要输出什么。

基于上述控制机制,LSTM就延缓了记忆衰退。

摘录于:

极力推荐TensorFlow教程:

Python代码:

(测试数据链接:https://pan.baidu.com/s/1j9sgPmWUHM5boM5ekj3Q2w 提取码:go3f )

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

#读取序列数据
data = pd.read_excel("seq_data.xlsx")
#取前800个
data = data.values[1:800]
#标准化数据
normalize_data = (data - np.mean(data)) / np.std(data)
#normalize_data = normalize_data[:, np.newaxis]
#data=data[:, np.newaxis]
s= np.std(data)
m=np.mean(data)
#序列段长度
time_step = 96
#隐藏层节点数目
rnn_unit = 8
#cell层数
lstm_layers = 2
#序列段批处理数目
batch_size = 7
#输入维度
input_size = 1
#输出维度
output_size = 1
#学习率
lr = 0.006
train_x, train_y = [], []
for i in range(len(data) - time_step - 1):
    x = normalize_data[i:i + time_step]
    y =normalize_data[i + 1:i + time_step + 1]
    train_x.append(x.tolist())
    train_y.append(y.tolist())

X = tf.placeholder(tf.float32, [None, time_step, input_size])#shape(?,time_step, input_size)
Y = tf.placeholder(tf.float32, [None, time_step, output_size])#shape(?,time_step, out_size)

weights = {
    'in': tf.Variable(tf.random_normal([input_size, rnn_unit])),
    'out': tf.Variable(tf.random_normal([rnn_unit, 1]))
}
biases = {
    'in': tf.Variable(tf.constant(0.1, shape=[rnn_unit, ])),
    'out': tf.Variable(tf.constant(0.1, shape=[1, ]))
}


def lstm(batch):
    w_in = weights['in']
    b_in = biases['in']
    input = tf.reshape(X, [-1, input_size])
    input_rnn = tf.matmul(input, w_in) + b_in
    input_rnn = tf.reshape(input_rnn, [-1, time_step, rnn_unit])
    cell = tf.nn.rnn_cell.MultiRNNCell([tf.nn.rnn_cell.BasicLSTMCell(rnn_unit) for i in range(lstm_layers)])
    init_state = cell.zero_state(batch, dtype=tf.float32)
    output_rnn, final_states = tf.nn.dynamic_rnn(cell, input_rnn, initial_state=init_state, dtype=tf.float32)
    output = tf.reshape(output_rnn, [-1, rnn_unit])
    w_out = weights['out']
    b_out = biases['out']
    pred = tf.matmul(output, w_out) + b_out
    return pred, final_states

def train_lstm():
    global batch_size
    with tf.variable_scope("sec_lstm"):
        pred, _ = lstm(batch_size)
    loss = tf.reduce_mean(tf.square(tf.reshape(pred, [-1]) - tf.reshape(Y, [-1])))
    train_op = tf.train.AdamOptimizer(lr).minimize(loss)
    saver = tf.train.Saver(tf.global_variables())
    loss_list=[]
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        for i in range(100):  # We can increase the number of iterations to gain better result.
            start = 0
            end = start + batch_size
            while (end < len(train_x)):
                _, loss_ = sess.run([train_op, loss], feed_dict={X: train_x[start:end], Y: train_y[start:end]})
                start += batch_size
                end = end + batch_size
            loss_list.append(loss_)
            if i % 10 == 0:
                print("Number of iterations:", i, " loss:", loss_list[-1])
                if i > 0 and loss_list[-2] > loss_list[-1]:
                    saver.save(sess, 'model_save1\\modle.ckpt')
        # I run the code in windows 10,so use  'model_save1\\modle.ckpt'
        # if you run it in Linux,please use  'model_save1/modle.ckpt'
        print("The train has finished")
train_lstm()

def prediction():
    with tf.variable_scope("sec_lstm", reuse=tf.AUTO_REUSE):
        pred, _ = lstm(1)
    saver = tf.train.Saver(tf.global_variables())
    with tf.Session() as sess:
        saver.restore(sess, 'model_save1\\modle.ckpt')
        # I run the code in windows 10,so use  'model_save1\\modle.ckpt'
        # if you run it in Linux,please use  'model_save1/modle.ckpt'
        predict = []
        for i in range(0, np.shape(train_x)[0]):
            next_seq = sess.run(pred, feed_dict={X: [train_x[i]]})
            predict.append(next_seq[-1])
        plt.figure()
        plt.plot(list(range(len(data))),data, color='b')
        plt.plot(list(range(time_step + 1, np.shape(train_x)[0] + 1 + time_step)), [ value*s+m for value in predict], color='r')
        plt.show()

prediction()

tensorflow 双向LSTM_tensorflow 双向LSTM_06

基于keras的lstm代码(含数据)见https://github.com/fff2zrx/lstm_example