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]))
LSTM--简单实例
猜你喜欢
转载自blog.csdn.net/weixin_43983570/article/details/105244357
今日推荐
周排行