tensoeflow版本基于LSTM的sin函数预测

目录 :

  • 前言

  • 导入库及设置常参数

  • 生成sin函数的数据集,并切分为训练集和测试集

  • 定义神经网络参数

  • 定义神经网络结构

  • 训练神经网络模型

  • 模型性能检验及预测

前言:

本文虽为对其另一篇博客(后附)的修改版本,但是为了便于理解,以及增加代码的可读性、复用性,我还参考了《TensorFlow: 实战Google深度学习框架》,希望能对你提供帮助。

 导入库及设置常参数

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import csv
import codecs
from numpy import pi
# 设置常参数
HIDDEN_SIZE =10              # lstm隐藏层的节点数目
NUM_LAYERS = 2               # lstm的层数

TIMESTEPS = 10               # 循环神经网络的训练序列长度
TRAINING_STEPS =1           # 循环轮数
BATCH_SIZE = 32             # batch大小
LEARNING_RATE = 0.001         # 学习率
TESTING_EXAMPLES = 15
PRED_NUM =100               # 预测值的数目
INPUT_SIZE=1                 #输入层维度
OUTPUT_SIZE=1                #输出层维度

TRAIN_EXAMPLES =8000
TEST_EXAMPLES =2000
SAMPLE_GAP = 0.01
model_path = 'F:/Files/ML model/SIN/'

生成sin函数的数据集,并切分为训练集和测试集

#——————————————————导入数据——————————————————————
#生成sin数据
data = np.sin(np.linspace( 0, 8*pi, TRAIN_EXAMPLES+TEST_EXAMPLE,dtype = np.float32))
data0 = data
#以折线图展示data
plt.figure()
plt.plot(data)
# plt.show()
normalize_data = data
normalize_data=(data-np.mean(data))/np.std(data)  #标准化
normalize_data=normalize_data[:,np.newaxis]       #增加维度
radio = 0.8
s = int(len(data)*radio)
train_data=normalize_data[:s]
test_data=normalize_data[s:]


train_x,train_y=[],[]   #训练集
for i in range(len(train_data)-TIMESTEPS-1):
    x=train_data[i:i+TIMESTEPS]
    y=train_data[i+1:i+TIMESTEPS+1]  #后一个sin值为标签[y]
    train_x.append(x.tolist())
    train_y.append(y.tolist())
print(train_y)

print('测试集')
test_x,test_y=[],[]   #测试集
for i in range(len(test_data)-TIMESTEPS-1):
    x1=test_data[i:i+TIMESTEPS]
    y1=test_data[i+1:i+TIMESTEPS+1]  #后一个sin值为标签[y]
    test_x.append(x1.tolist())
    test_y.append(y1.tolist())
# print(test_y)
# print(len(test_y))

x0,y0=[],[]
for i in range(len(normalize_data)-TIMESTEPS-1):
    x2=normalize_data[i:i+TIMESTEPS]
    y2=normalize_data[i+1:i+TIMESTEPS+1]  #后一个sin值为标签[y]
    x0.append(x2.tolist())
    y0.append(y2.tolist())
print(x0)
print(len(y0))

定义神经网络参数

#——————————————————定义神经网络变量——————————————————
X=tf.placeholder(tf.float32, [None,TIMESTEPS,INPUT_SIZE])    #每批次输入网络的tensor
Y=tf.placeholder(tf.float32, [None,TIMESTEPS,OUTPUT_SIZE])   #每批次tensor对应的标签
#输入层、输出层权重、偏置
weights={
         'in':tf.Variable(tf.random_normal([INPUT_SIZE,HIDDEN_SIZE])),
         'out':tf.Variable(tf.random_normal([HIDDEN_SIZE,1]))
         }
biases={
        'in':tf.Variable(tf.constant(0.1,shape=[HIDDEN_SIZE,])),
        '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])  #需要将tensor转成2维进行计算,计算后的结果作为隐藏层的输入

    input_rnn=tf.matmul(input,w_in)+b_in
    input_rnn=tf.reshape(input_rnn,[-1,TIMESTEPS,HIDDEN_SIZE])  #将tensor转成3维,作为lstm cell的输入
    cell=tf.nn.rnn_cell.BasicLSTMCell(HIDDEN_SIZE)
    init_state=cell.zero_state(batch,dtype=tf.float32)

    # output_rnn是记录lstm每个输出节点的结果,final_states是最后一个cell的结果
    output_rnn,final_states=tf.nn.dynamic_rnn(cell, input_rnn,initial_state=init_state, dtype=tf.float32)
    output=tf.reshape(output_rnn,[-1,HIDDEN_SIZE]) #作为输出层的输入
    w_out=weights['out']
    b_out=biases['out']
    pred=tf.matmul(output,w_out)+b_out
    return pred,final_states


训练神经网络模型

#——————————————————训练模型——————————————————
def train_lstm(epoch=5000):
    global BATCH_SIZE
    pred,_=lstm(BATCH_SIZE)
    #损失函数
    cast=tf.reduce_mean(tf.square(tf.reshape(pred,[-1])-tf.reshape(Y, [-1])))
    train_op=tf.train.AdamOptimizer(LEARNING_RATE).minimize(cast)
    saver = tf.train.Saver( tf.global_variables() )  # 创建一个Saver对象
    module_file = tf.train.latest_checkpoint( model_path )                    # *************参数是基于已有模型恢复的参数*******
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        saver.restore( sess, module_file )                                    # ***************参数是基于已有模型恢复的参数****
        for i in range(epoch):
            step=0
            start=0
            end=start+BATCH_SIZE
            train_loss,  n_batch =  0, 0
            while (end < len( train_x )):
                _, loss_ = sess.run( [train_op, cast], feed_dict={X: train_x[start:end], Y: train_y[start:end]} )
                start += BATCH_SIZE
                end = start + BATCH_SIZE
                train_loss += loss_
                n_batch += 1
                # 每100步保存一次参数
                if step % 100 == 0:
                    print( "保存模型:", saver.save( sess, model_path ) )
                    print( "   train loss: %f" % (train_loss / n_batch) )
                step+=1

 

 模型性能检验及预测

#————————————————模型预测————————————————————
def prediction(pred_num=30):
    global model_path

    pred,_=lstm(1)      #预测时只输入[1,time_step,input_size]的测试数据

    saver = tf.train.Saver( tf.global_variables() )  # 创建一个Saver对象
    module_file = tf.train.latest_checkpoint( model_path )                    # *************参数是基于已有模型恢复的参数*******
    with tf.Session() as sess:
        # sess.run(tf.global_variables_initializer())
        saver.restore( sess, module_file )                                    # ***************参数是基于已有模型恢复的参数****
# -------------------------------测试部分---------------------------------------------
        #取训练集最后一行为测试样本。shape=[1,time_step,input_size]
        prev_seq=test_x[-1]
        # 测试集的预测值
        prediction = []
        num_test = int(len(test_x)-TIMESTEPS)
        # 真实的数字
        # labels = test_y[TIMESTEPS:]
        labels = data0[len(train_data)+TIMESTEPS*2+1:]
        for i in range( num_test ):
            next_seq=sess.run(pred,feed_dict={X:[prev_seq]})
            prediction.append(next_seq[-1])
            #每次得到最后一个时间步的预测结果,与之前的数据加在一起,形成新的测试样本
            prev_seq=np.vstack((prev_seq[1:],next_seq[-1]))
        # 计算rmse作为评价的指标
        pre_squ = np.array( prediction ).squeeze()
        labels = np.array(labels)
        lab_squ = np.array( labels ).squeeze()
        print(pre_squ)
        print(lab_squ)
        rmse = np.sqrt( ((pre_squ - lab_squ) ** 2).mean( axis=0 ) )
        print( "Mean Square Error is :%f" % (rmse) )
        plt.figure()
        plt.plot(labels,label='real_sin',color='b')
        plt.plot(prediction,label='predictions',color='r')
# ------------------------------预测部分------------------------------------------------
        # 得到之后pred_num个预测结果
        predict = []
        prev_seq_all = x0[-1]
        for i in range(pred_num):
            next_seq_all=sess.run(pred,feed_dict={X:[prev_seq_all]})
            predict.append(next_seq_all[-1])
            # 每次得到最后一个时间步的预测结果,与之前的数据加在一起,形成新的测试样本
            prev_seq_all=np.vstack((prev_seq_all[1:],next_seq_all[-1]))

        # #以折线图表示结果
        plt.figure()
        plt.plot( list( range( len( data0 ) ) ), data0, color='b' )
        plt.plot( list( range( len( data0 ), len( data0 ) + len( predict ) ) ), predict, color='r' )
        plt.show()
        # 将预测数据保存到文件中
        print(predict)
        # data_write_csv('',predict)

 

with tf.Session() as sess:
    # sess.run(tf.global_variables_initializer())    # 如果时第一次训练使用用这句,需要初始化
    # saver.restore( sess, module_file )             # 恢复训练过的模型使用这句  ,直接恢复模型中的参数                              

主函数:模型训练及预测的入口 

def main():
    with tf.variable_scope( 'train' ):
        epoch = TRAINING_STEPS
        train_lstm( epoch )
        print( 'train finsh' )

    with tf.variable_scope( 'train', reuse=True ):
        pred_num = PRED_NUM
        prediction( pred_num )

if __name__ == '__main__':
    main()

 

完整代码

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import csv
import codecs
from numpy import pi
# 设置常参数
HIDDEN_SIZE =10              # lstm隐藏层的节点数目
NUM_LAYERS = 2               # lstm的层数

TIMESTEPS = 10               # 循环神经网络的训练序列长度
TRAINING_STEPS =1           # 循环轮数
BATCH_SIZE = 32             # batch大小
LEARNING_RATE = 0.001         # 学习率
TESTING_EXAMPLES = 15
PRED_NUM =100               # 预测值的数目
INPUT_SIZE=1                 #输入层维度
OUTPUT_SIZE=1                #输出层维度

TRAIN_EXAMPLES =8000
TEST_EXAMPLES =2000
model_path = 'F:/Files/ML model/SIN/'


#——————————————————导入数据——————————————————————
#生成sin数据
data = np.sin(np.linspace( 0, 8*pi, TRAIN_EXAMPLES+TEST_EXAMPLES,dtype = np.float32))
data0 = data
#以折线图展示data
plt.figure()
plt.plot(data)
# plt.show()
normalize_data = data
normalize_data=(data-np.mean(data))/np.std(data)  #标准化
normalize_data=normalize_data[:,np.newaxis]       #增加维度
radio = 0.8
s = int(len(data)*radio)
train_data=normalize_data[:s]
test_data=normalize_data[s:]


train_x,train_y=[],[]   #训练集
for i in range(len(train_data)-TIMESTEPS-1):
    x=train_data[i:i+TIMESTEPS]
    y=train_data[i+1:i+TIMESTEPS+1]  #后一天的total_purchase_amt最为标签[y]
    train_x.append(x.tolist())
    train_y.append(y.tolist())
print(train_y)

print('测试集')
test_x,test_y=[],[]   #测试集
for i in range(len(test_data)-TIMESTEPS-1):
    x1=test_data[i:i+TIMESTEPS]
    y1=test_data[i+1:i+TIMESTEPS+1]  #后一天的total_purchase_amt最为标签[y]
    test_x.append(x1.tolist())
    test_y.append(y1.tolist())
# print(test_y)
# print(len(test_y))

x0,y0=[],[]
for i in range(len(normalize_data)-TIMESTEPS-1):
    x2=normalize_data[i:i+TIMESTEPS]
    y2=normalize_data[i+1:i+TIMESTEPS+1]  #后一天的total_purchase_amt最为标签[y]
    x0.append(x2.tolist())
    y0.append(y2.tolist())
print(x0)
print(len(y0))


def data_write_csv(file_name, datas):  # file_name为写入CSV文件的路径,datas为要写入数据列表
    file_csv = codecs.open( file_name, 'w+', 'utf-8' )  # 追加
    writer = csv.writer( file_csv, delimiter=' ', quotechar=' ', quoting=csv.QUOTE_MINIMAL )
    for data in datas:
        writer.writerow( data )
    print( "保存文件成功,处理结束" )

#——————————————————定义神经网络变量——————————————————
X=tf.placeholder(tf.float32, [None,TIMESTEPS,INPUT_SIZE])    #每批次输入网络的tensor
Y=tf.placeholder(tf.float32, [None,TIMESTEPS,OUTPUT_SIZE])   #每批次tensor对应的标签
#输入层、输出层权重、偏置
weights={
         'in':tf.Variable(tf.random_normal([INPUT_SIZE,HIDDEN_SIZE])),
         'out':tf.Variable(tf.random_normal([HIDDEN_SIZE,1]))
         }
biases={
        'in':tf.Variable(tf.constant(0.1,shape=[HIDDEN_SIZE,])),
        '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])  #需要将tensor转成2维进行计算,计算后的结果作为隐藏层的输入

    input_rnn=tf.matmul(input,w_in)+b_in
    input_rnn=tf.reshape(input_rnn,[-1,TIMESTEPS,HIDDEN_SIZE])  #将tensor转成3维,作为lstm cell的输入
    cell=tf.nn.rnn_cell.BasicLSTMCell(HIDDEN_SIZE)
    init_state=cell.zero_state(batch,dtype=tf.float32)

    # output_rnn是记录lstm每个输出节点的结果,final_states是最后一个cell的结果
    output_rnn,final_states=tf.nn.dynamic_rnn(cell, input_rnn,initial_state=init_state, dtype=tf.float32)
    output=tf.reshape(output_rnn,[-1,HIDDEN_SIZE]) #作为输出层的输入
    w_out=weights['out']
    b_out=biases['out']
    pred=tf.matmul(output,w_out)+b_out
    return pred,final_states




#——————————————————训练模型——————————————————
def train_lstm(epoch=5000):
    global BATCH_SIZE
    pred,_=lstm(BATCH_SIZE)
    #损失函数
    cast=tf.reduce_mean(tf.square(tf.reshape(pred,[-1])-tf.reshape(Y, [-1])))
    train_op=tf.train.AdamOptimizer(LEARNING_RATE).minimize(cast)
    saver = tf.train.Saver( tf.global_variables() )  # 创建一个Saver对象
    module_file = tf.train.latest_checkpoint( model_path )                    # *************参数是基于已有模型恢复的参数*******
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        saver.restore( sess, module_file )                                    # ***************参数是基于已有模型恢复的参数****
        for i in range(epoch):
            step=0
            start=0
            end=start+BATCH_SIZE
            train_loss,  n_batch =  0, 0
            while (end < len( train_x )):
                _, loss_ = sess.run( [train_op, cast], feed_dict={X: train_x[start:end], Y: train_y[start:end]} )
                start += BATCH_SIZE
                end = start + BATCH_SIZE
                train_loss += loss_
                n_batch += 1
                # 每100步保存一次参数
                if step % 100 == 0:
                    print( "保存模型:", saver.save( sess, model_path ) )
                    print( "   train loss: %f" % (train_loss / n_batch) )
                step+=1

#————————————————预测模型————————————————————
def prediction(pred_num=30):
    global model_path

    pred,_=lstm(1)      #预测时只输入[1,time_step,input_size]的测试数据

    saver = tf.train.Saver(tf.global_variables())  # 创建一个Saver对象
    """
    导入一个预先训练模式:
    a)创建网络结构图: 导入原始网络结构图
    b)加载的(变量)参数: 使用restore()方法恢复模型的变量参数。
    """
    with tf.Session() as sess:

        saver .restore(sess,tf.train.latest_checkpoint(model_path))

# -------------------------------测试部分---------------------------------------------
        #取训练集最后一行为测试样本。shape=[1,time_step,input_size]
        prev_seq=test_x[-1]
        # 测试集的预测值
        prediction = []
        num_test = int(len(test_x)-TIMESTEPS)
        # 真实的数字
        # labels = test_y[TIMESTEPS:]
        labels = data0[len(train_data)+TIMESTEPS*2+1:]
        for i in range( num_test ):
            next_seq=sess.run(pred,feed_dict={X:[prev_seq]})
            prediction.append(next_seq[-1])
            #每次得到最后一个时间步的预测结果,与之前的数据加在一起,形成新的测试样本
            prev_seq=np.vstack((prev_seq[1:],next_seq[-1]))
        # 计算rmse作为评价的指标
        pre_squ = np.array( prediction ).squeeze()
        labels = np.array(labels)
        lab_squ = np.array( labels ).squeeze()
        print(pre_squ)
        print(lab_squ)
        rmse = np.sqrt( ((pre_squ - lab_squ) ** 2).mean( axis=0 ) )
        print( "Mean Square Error is :%f" % (rmse) )
        plt.figure()
        plt.plot(labels,label='real_sin',color='b')
        plt.plot(prediction,label='predictions',color='r')
# ------------------------------预测部分------------------------------------------------
        # 得到之后pred_num个预测结果
        predict = []
        prev_seq_all = x0[-1]
        for i in range(pred_num):
            next_seq_all=sess.run(pred,feed_dict={X:[prev_seq_all]})
            predict.append(next_seq_all[-1])
            # 每次得到最后一个时间步的预测结果,与之前的数据加在一起,形成新的测试样本
            prev_seq_all=np.vstack((prev_seq_all[1:],next_seq_all[-1]))

        # #以折线图表示结果
        plt.figure()
        plt.plot( list( range( len( data0 ) ) ), data0, color='b' )
        plt.plot( list( range( len( data0 ), len( data0 ) + len( predict ) ) ), predict, color='r' )
        plt.show()
        # 将预测数据保存到文件中
        print(predict)
        # data_write_csv('',predict)



def main():
    with tf.variable_scope( 'train' ):
        epoch = TRAINING_STEPS
        train_lstm( epoch )
        print( 'train finsh' )

    with tf.variable_scope( 'train', reuse=True ):
        pred_num = PRED_NUM
        prediction( pred_num )

if __name__ == '__main__':
    main()

红线为预测值

Reference

《TensorFlow: 实战Google深度学习框架》 对于小白规范化自己的代码,增强代码的复用性很有必要看看

使用Keras进行LSTM实战

Tensorflow实例:利用LSTM预测股票每日最高价(一)

 

最后

作为一名deep learning初学者,欢迎大家和我交流,blog的不当之处还请大家不吝赐教。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值