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