注解:
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()