LSTM模型預測sin函數詳解


注解:

fun_data()
函數生成訓練數據和標簽,同時生成測試數據和測試標簽
HIDDEN_SIZE = 128,使用128維的精度來定義LSTM的狀態和輸出精度,就是LSTM中的h,c
lstm_model()函數定義了一個可重入的模型,
分別由評估函數和訓練函數調用,在訓練前使用空模型預測並輸出未訓練數據並可視化
通過with tf.variable_scope("lstm_model",reuse=tf.AUTO_REUSE) as scope:定義了在多次實例化模型的時候共享訓練結果

run_eval()定義了評估函數:實現了訓練及可視化結果
run_train()定義了訓練函數:實現了訓練過程。

如果還要提高擬合精度可以把TRAINING_STEPS設大些,不過比較耗時,我的電腦比較老,感覺訓練一千次擬合精度就很高了,再訓練已經沒意義了,呵呵。

圖一:還未訓練之間的結果,擬合基本上不行
圖二:訓練500-2000次基本就能很好的預測sin上的任何點了。

 
        



  1 # LSTM預測sin曲線
  2 #tensorflow 1.13.1
  3 #numpy 1.16.2
  4 import numpy as np
  5 import tensorflow as tf
  6 import matplotlib.pyplot as plt
  7 plt.rcParams['font.sans-serif']=['FangSong'] # 用來正常顯示中文標簽
  8 plt.rcParams['axes.unicode_minus']=False# 用來正常顯示負號
  9 ########################################################################################
 10 # RNN模型相關參數
 11 HIDDEN_SIZE = 128                           # LSTM中隱藏節點的個數,定義輸出及狀態的向量維度。
 12 NUM_LAYERS = 3                              # LSTM的層數。
 13 TIME_STEPS = 10                             # 循環神經網絡的訓練序列長度
 14 TRAINING_STEPS = 2000                       # 訓練輪數。
 15 BATCH_SIZE = 32                             # batch大小。
 16 #數據樣本數量
 17 TRAINING_EXAMPLES = 10000                   # 訓練數據個數。
 18 TESTING_EXAMPLES = 1000                     # 測試數據個數。
 19 ########################################################################################
 20 def fun_data():
 21     # 用正弦函數生成訓練和測試數據集合。
 22     SAMPLE_GAP = 0.01# 采樣間隔。
 23     test_start = (TRAINING_EXAMPLES + TIME_STEPS) * SAMPLE_GAP
 24     test_end = test_start + (TESTING_EXAMPLES + TIME_STEPS) * SAMPLE_GAP
 25     MYTRAIN = np.sin(np.linspace(0, test_start, TRAINING_EXAMPLES + TIME_STEPS, dtype=np.float32))
 26     MYTEST  = np.sin(np.linspace(test_start, test_end, TESTING_EXAMPLES + TIME_STEPS, dtype=np.float32))
 27     
 28     def generate_data(seq):
 29         X,Y = [],[]
 30         for i in range(len(seq) - TIME_STEPS):
 31             X.append([seq[i: i + TIME_STEPS]]) # 用[0]至[9]個特征
 32             Y.append([seq[i + TIME_STEPS]])    # 預測[10]這個值 
 33         return np.array(X, dtype=np.float32), np.array(Y, dtype=np.float32)  
 34 
 35     #生成訓練數據和測試數據
 36     #(10000, 1, 10) (10000, 1)
 37     train_x, train_y = generate_data(MYTRAIN)
 38     #(1000, 1, 10) (1000, 1)
 39     test_x, test_y = generate_data(MYTEST)
 40     
 41     return train_x, train_y, test_x, test_y   
 42 
 43 def lstm_model(X, y):
 44     # 定義算法圖:可重入,共享訓練變量
 45     # 每調用一次lstm_model函數會在同一個系統缺省圖
 46     # tf.variable_scope("lstm_model",reuse=tf.AUTO_REUSE)定義共享訓練變量
 47     with tf.variable_scope("lstm_model",reuse=tf.AUTO_REUSE) as scope:
 48         #定義多層LSTM
 49         cell = tf.nn.rnn_cell.MultiRNNCell(
 50             [tf.nn.rnn_cell.LSTMCell(HIDDEN_SIZE) for _ in range(NUM_LAYERS)])
 51         #根據tf.nn.dynamic_rnn對數據的要求變換shape    
 52         #XX (?, 10, 1),X(?, 1, 10)
 53         XX = tf.reshape(X,[-1, X.shape[-1], X.shape[-2]])
 54         # outputs (?, 10, 128)
 55         outputs, _ = tf.nn.dynamic_rnn(cell, XX, dtype=tf.float32)
 56         # 取TIME_STEPS最后一個單元上的輸出作為預測值
 57         # output (?, 128)
 58         output = outputs[:, -1, :]
 59         # 加一層全連接直接輸出預測值
 60         # predictions (?, 1)
 61         mypredictions = tf.layers.dense(output,1)
 62         # 平均平方差損失函數計算工時,用這個函數來求loss。
 63         loss = tf.losses.mean_squared_error(labels=y, predictions=mypredictions)
 64         # 使用AdamOptimizer進行優化
 65         train_op = tf.train.AdamOptimizer(0.01).minimize(loss)
 66     return mypredictions, loss, train_op
 67 
 68 def run_eval(sess):
 69     # 評估算法
 70     ds = tf.data.Dataset.from_tensor_slices((self.test_X, self.test_y))
 71     ds = ds.batch(1)#一次取一個樣本
 72     X, y = ds.make_one_shot_iterator().get_next()
 73     prediction, loss, train_op = lstm_model(X, y)
 74     predictions = []
 75     labels = []
 76     for i in range(TESTING_EXAMPLES):
 77         p, l = sess.run([prediction, y])
 78         predictions.append(p)
 79         labels.append(l)
 80     predictions = np.array(predictions).squeeze()
 81     labels = np.array(labels).squeeze()
 82     
 83     #對預測的sin函數曲線進行繪圖。
 84     plt.figure()
 85     plt.plot(predictions, label='預測',linestyle='solid', color='red')
 86     plt.plot(labels, label='真實數據',linestyle='dotted',color='black')
 87     plt.legend()
 88     plt.show()
 89     
 90     return
 91 
 92 def run_train(sess):
 93     #定義訓練過程
 94     for ecoh in range(TRAINING_STEPS):
 95         myloss, _ = sess.run([self.loss, self.train_op])
 96         if ecoh % 100 == 0:
 97             print('訓練次數:{:}損失函數值:{:}'.format(ecoh,myloss))
 98     return
 99 
100 def run_main():
101       
102     #准備數據  
103     self.train_X, self.train_y,self.test_X, self.test_y = fun_data()
104     ds = tf.data.Dataset.from_tensor_slices((self.train_X, self.train_y))
105     ds = ds.repeat().shuffle(1000).batch(BATCH_SIZE)#一次取BATCH_SIZE個樣本
106     X, y = ds.make_one_shot_iterator().get_next()
107     
108     #定義模型  
109     self.prediction, self.loss, self.train_op = lstm_model(X, y)   
110     # 初始化方法定義
111     init = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
112             
113     with tf.Session() as sess:
114         sess.run(init)
115         # 測試在訓練之前的模型效果。
116         run_eval(sess)
117         # 訓練模型。
118         run_train(sess)
119         # 使用訓練好的模型對測試數據進行預測。
120         run_eval(sess)
121     return
122             
123 if __name__ == "__main__" :        
124     run_main()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM