LSTM--简单实例

import numpy as np
import tensorflow as tf
from tensorflow.contrib import rnn
class SeriesPredictor:
    def __init__(self, input_dim, seq_size, hidden_dim=10):
        self.input_dim = input_dim #每次输入限量维数
        self.seq_size = seq_size #序列长度  time-step
        self.hidden_dim = hidden_dim #隐藏层维数
        self.W_out = tf.Variable(tf.random_normal([hidden_dim, 1]),name='W_out')#权值变量
        self.b_out = tf.Variable(tf.random_normal([1]), name='b_out')#权值偏置
        self.x = tf.placeholder(tf.float32, [None, seq_size, input_dim])#生成[batch_size,seq_size,input_dim]
        self.y = tf.placeholder(tf.float32, [None, seq_size])#生成[batch_size,seq_size]
        self.cost = tf.reduce_mean(tf.square(self.model() - self.y))#损失方程,均方差
        self.train_op = tf.train.AdamOptimizer().minimize(self.cost)#adam优化器
        self.saver = tf.train.Saver()
        """
        tf.train.Saver()-tensorflow中模型的保存及读取
作用:训练网络之后保存训练好的模型,以及在程序中读取已保存好的模型
使用步骤:
实例化一个Saver对象 saver = tf.train.Saver() 
在训练过程中,定期调用saver.save方法,像文件夹中写入包含当前模型中所有可训练变量的checkpoint文件 saver.save(sess,FLAGG.train_dir,global_step=step) 
之后可以使用saver.restore()方法,重载模型的参数,继续训练或者用于测试数据 saver.restore(sess,FLAGG.train_dir) 
在save之后会在相应的路径下面新增如下四个红色文件:
在saver实例每次调用save方法时,都会创建三个数据文件和一个检查点(checkpoint)文件,权重等参数被以字典的形式保存到.ckpt.data中,图和元数据被保存到.ckpt.meta中,可以被tf.train.import_meta_graph加载到当前默认的图
        """
    def model(self):
        cell = rnn.BasicLSTMCell(self.hidden_dim) #创建LSTM隐藏层
        outputs, states = tf.nn.dynamic_rnn(cell, self.x, dtype=tf.float32)  #对隐层进行前进运算
        print(outputs)
        print(states)
        """
        tf.nn.dynamic_rnn(
                cell,
                inputs,
                sequence_length=None,
                initial_state=None,
                dtype=None,
                parallel_iterations=None,
                swap_memory=False,
                time_major=False,
                scope=None
                cell: RNNCell的一个实例.

inputs: RNN输入.
如果time_major == False(默认), 则是一个shape为[batch_size, max_time, input_size]的Tensor,或者这些元素的嵌套元组。
如果time_major == True,则是一个shape为[max_time, batch_size, input_size]的Tensor,或这些元素的嵌套元组。
sequence_length: (可选)大小为[batch_size],数据的类型是int32/int64向量。如果当前时间步的index超过该序列的实际长度时,
则该时间步不进行计算,RNN的state复制上一个时间步的,同时该时间步的输出全部为零。

initial_state: (可选)RNN的初始state(状态)。如果cell.state_size(一层的RNNCell)是一个整数
,那么它必须是一个具有适当类型和形状的张量[batch_size,cell.state_size]。如果cell.state_size是一个元组(多层的RNNCell,如MultiRNNCell),
那么它应该是一个张量元组,每个元素的形状为[batch_size,s] for s in cell.state_size。

time_major: inputs 和outputs 张量的形状格式。如果为True,则这些张量都应该是(都会是)[max_time, batch_size, depth]。如果为false,
则这些张量都应该是(都会是)[batch_size,max_time, depth]。time_major=true说明输入和输出tensor的第一维是max_time。否则为batch_size。
使用time_major =True更有效,因为它避免了RNN计算开始和结束时的转置.但是,大多数TensorFlow数据都是batch-major,因此默认情况下,此函数接受输入并以batch-major形式发出输出.
返回值:
一对(outputs, state),其中:
outputs: RNN输出Tensor.
如果time_major == False(默认),这将是shape为[batch_size, max_time, cell.output_size]的Tensor.
如果time_major == True,这将是shape为[max_time, batch_size, cell.output_size]的Tensor.
state: 最终的状态.
一般情况下state的形状为 [batch_size, cell.output_size ]
如果cell是LSTMCells,则state将是包含每个单元格的LSTMStateTuple的元组,state的形状为[2,batch_size, cell.output_size ]

        """
        num_examples = tf.shape(self.x)[0]#获取batchsize大小
        W_repeated = tf.tile(tf.expand_dims(self.W_out, 0), [num_examples, 1, 1])#变化为[batch_size,seq_size, input_dim]
        # tf.expand_dims,0号位增加一个新的维度,再将矩阵进行扩展
        # W_repeated = tf.tile(tf.expand_dims(self.W_out, 0), [num_examples, 1, 1])变为[batchsize,hidden_dim,1]
        # tf_expand维度(1,10,1)
        """
        tf.tile(
            input,
            multiples,
            name=None
        )
input是待扩展的张量,multiples是扩展方法。
假如input是一个3维的张量。那么mutiples就必须是一个1x3的1维张量。这个张量的三个值依次表示input的第1,第2,第3维数据扩展几倍。
        """
        out = tf.matmul(outputs, W_repeated) + self.b_out#实现全连接层
        out = tf.squeeze(out)
        """
        squeeze(
        input,
        axis=None,
        name=None,
        squeeze_dims=None
)
 从tensor中删除所有大小是1的维度
 给定张量输入,此操作返回相同类型的张量,并删除所有尺寸为1的尺寸。 如果不想删除所有大小是1的维度,可以通过squeeze_dims指定。
        """
        return out

    """
    :param x: inputs of size [T, batch_size, input_size]
    :param W: matrix of fully-connected output layer weights
    :param b: vector of fully-connected output layer biases
    """

    def train(self, train_x, train_y):#训练函数
        with tf.Session() as sess:#建立会话
            tf.get_variable_scope().reuse_variables()#设置变量共享
            sess.run(tf.global_variables_initializer())#会话执行变量初始化
            # 迭代次数
            for i in range(1000):
                _, mse = sess.run([self.train_op, self.cost], feed_dict={self.x: train_x, self.y: train_y})
                if i % 100 == 0:
                    print(i, mse)
            save_path = self.saver.save(sess, './model')
            print('Model saved to {}'.format(save_path))

    def test(self, test_x):#取出模型对数据进行匹配
        with tf.Session() as sess:
            tf.get_variable_scope().reuse_variables()#变量共享
            self.saver.restore(sess, './model')#存储模型
            output = sess.run(self.model(), feed_dict={self.x: test_x})
            return output


if __name__ == '__main__':
    predictor = SeriesPredictor(input_dim=1, seq_size=4, hidden_dim=10)
    train_x = [[[1], [2], [5], [6]],
               [[5], [7], [7], [8]],
               [[3], [4], [5], [7]]]
    train_y = [[1, 3, 7, 11],
               [5, 12, 14, 15],
               [3, 7, 9, 12]]
    predictor.train(train_x, train_y)

    test_x = [[[1], [2], [3], [4]],#模型训练结果为train[0]+train[1] = label[1]
              [[4], [5], [6], [7]]]
    actual_y = [[1, 3, 5, 7],
                [4, 9, 11, 13]]
    pred_y = predictor.test(test_x)

    print("\nlets run some tests!\n")

    for i, x in enumerate(test_x):
        print('when the inputs is {}'.format(x))
        print('the ground truth output should be {}'.format(actual_y[i]))
        print('and the model thinks it is {}\n'.format(pred_y[i]))



发布了17 篇原创文章 · 获赞 1 · 访问量 3422

猜你喜欢

转载自blog.csdn.net/weixin_43983570/article/details/105244357