--- tags: DeepLearning_HW3_RNN title: Report --- # Time Series Prediction ## 目錄 ###### [TOC] ## 問題 #### 在這次的作業中,我們會被給予第一部份的序列 ${x(t)}_{t=1}^{1000}$. #### 目標是設計一個循環神經網路(Recurrent Neural Network, RNN)來預測第二部分的序列 ${x(t)}_{t=1001}^{1500}$ #### 而第二部分的序列將由老師自行測試,這部分的數據不會空開。 ## 方法 #### 以下方法將供你們參考 #### 你可以用任何RNN的模型(Simple RNN, LSTM, GRU)來做預測,請注意,其他種類的類神經網路將不被允許。 #### 在時間 $t+1$, 訓練後的RNN可以使用過去一連串的時間向量M步來預測出 $x(t+1)$,舉例, #### $X(t-M+1),X(t-M+2),...,X(t)$ #### 當$X(i)$是一個向量 包含了N個連續資料點$x(i),x(i-1),...,x(i-N-1)$ #### 為了可以有好的預測準確率,你可以隨意地去測定M和N的值 #### 使用老師的隱藏測試資料時,為了避免過度擬合,同學們最好在訓練中使用cross validatioin。 ## 解決 ### 使用keras來建立RNN的模型,使用老師給予的數據訓練,並探討Simple RNN LSTM、GLU的使用與輸入資料長短(n_steps)的調整 #### 繼HW1的jupyter notebook、HW2的Colab,這次使用PyCharm來見建構RNN #### import 我們需要的Library ``` from __future__ import absolute_import, division, print_function, unicode_literals import numpy as np from numpy import array from tensorflow.keras import layers, models, Sequential from tensorflow.keras.layers import LSTM, Dense, GRU, SimpleRNN, Bidirectional from tensorflow.keras.models import load_model import matplotlib.pyplot as plt ``` #### 寫一個函式來格式我們的input跟label #### sequence為我們待會要餵進RNN的資料,n_steps為我們預計要多少長度為一個單位 ##### sequence = [1,2,3,4,5,6], n_steps = 3 ##### output 為 [1,2,3] = 4, [2,3,4] = 5, [3,4,5] = 6 ``` # split a univariate sequence def split_sequence(sequence, n_steps): X, y = list(), list() for i in range(len(sequence)): # find the end of this pattern end_ix = i + n_steps # check if we are beyond the sequence if end_ix > len(sequence)-1: break # gather input and output parts of the pattern seq_x, seq_y = sequence[i:end_ix], sequence[end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) ``` 讀取我們要的資料(我預先將老師的資料存進txt) ``` def load_data(): raw_seq = [] f = open("D:\\blablabla\\blablabla\\training_data.txt", "r") for i in f: i = i.rstrip() i = float(i) raw_seq.append(i) ip = array(raw_seq) f.close() return ip ``` load data ``` # define input sequence raw_seq = load_data() ``` 設定長度 ``` # choose a number of time steps n_steps = 200 epochs = 2000 # split into samples X, y = split_sequence(raw_seq, n_steps) # reshape from [samples, timesteps] into [samples, timesteps, features] n_features = 1 X = X.reshape((X.shape[0], X.shape[1], n_features)) ``` Model_build: 本次作業,所以驅動函數(activation function) 都使用relu function,因為sigmoid function本身特性(0~1)與實際測試效果均不佳(會使預設值收斂),所以後面幾種Model都是使用ReLu Function ``` # define model model = Sequential() model.add(Bidirectional(GRU(100, activation='sigmoid'), \ input_shape=(n_steps, n_features))) # model.add(GRU(100, activation='relu', input_shape=(n_steps, n_features))) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') # fit model model.fit(X, y, epochs=200, verbose=1) evaluate = model.evaluate(X, y, verbose=0) print(evaluate) name = 'HM3_'+str(evaluate)+'_steps'+str(n_steps)+'_ep'+str(epochs)+'_GRU100_WBi' model.save(name+'.h5') # demonstrate prediction x_input = raw_seq[-100:] x_input = array(x_input) x_input_r = x_input.reshape((1, n_steps, n_features)) yhat = model.predict(x_input_r, verbose=1) ``` Predict ``` output_list = [] print(yhat) output_list.append(float(yhat)) for i in range(2, 501): x_predict_data = x_input[1:] x_predict_data = np.append(x_predict_data, yhat) x_input = x_predict_data x_predict_data_r = x_predict_data.reshape((1, n_steps, n_features)) yhat = model.predict(x_predict_data_r, verbose=0) output_list.append(float(yhat)) print("yhat is {}".format(float(yhat))) # print("input is {}".format(x_input)) # output_list.append(yhat) ``` save as txt ``` outF = open("D:\\blablabla\\blablabla\\output.txt", "w") for line in output_list: outF.write(str(line)) outF.write(",") outF.close() ``` ## 結果 基本上我都是透過try and error來測試出好的n_steps(輸入model的資料長度) 一開始都是由50開始切入,然後看預測出來的圖形往上或往下做調整 一開始會先使用epoch = 100來抓同一model中不同n_steps的大致效果 然後跟其他n_steps來做比較,最後取出比較好的n_steps做epoch = 2000的訓練 就目前有的訓練模型,從n_steps=10 ~ 200的測試結果,epoch=100或200的效果測試,到最後 特定n_steps和epochs=2000的訓練後。Bidirectional LSTM可以有比較好的預測 ### <font size="6">__**Bidirectional GRU Model**__ </font> $$ \text{GRU(100)} \rightarrow \text{Dense(1)} $$ ##### With Bidirectional = True 這個model可以看出來n_step=50 和 60 效果都不好 ![Imgur](https://i.imgur.com/F3R6n7u.png) 所以最後我拿n_steps=30 做大量epochs的訓練 ![Imgur](https://i.imgur.com/NO3Uaga.png) --- ### <font size="6">__**GRU Model**__ </font> $$ \text{GRU(100)} \rightarrow \text{Dense(1)} $$ ##### With Bidirectional = False 這個model可以看出來n_step=40 和 50 效果都不好 ![Imgur](https://i.imgur.com/MADBW0r.png) 所以最後我拿n_steps=20 做大量epochs的訓練 ![Imgur](https://i.imgur.com/FJiWxjp.png) --- ### <font size="6">__**Bidirectional LSTM Model**__ </font> $$ \text{LSTM(100)} \rightarrow \text{Dense(1)} $$ ##### With Bidirectional = True 這個model可以看出來 不管n_steps為多少效果都很好 ![Imgur](https://i.imgur.com/Esm2c1B.png) 所以最後我拿n_steps=50 做大量epochs的訓練,最後也是上傳這個model預測的值 ![Imgur](https://i.imgur.com/HzK2zeM.png) --- ### <font size="6">__**LSTM Model**__ </font> $$ \text{LSTM(100)} \rightarrow \text{Dense(1)} $$ ##### With Bidirectional = False 這個model可以看出來n_step=95 的效果不好 n_step = 87 的效果已經還不錯,但是相較於n_step=50還是可惜一些 ![Imgur](https://i.imgur.com/McWI48Q.png) 所以最後我拿n_steps=50 做大量epochs的訓練 ![Imgur](https://i.imgur.com/nqIHGrF.png) --- ### <font size="6">__**Bidirectional Simple RNN Model**__ </font> $$ \text{SimpleRNN(100)} \rightarrow \text{Dense(1)} $$ ##### With Bidirectional = True 這個model可以看出來n_step=80 和 90 效果都不好 ![Imgur](https://i.imgur.com/4jm2Uk6.png) 所以最後我拿n_steps=50 做大量epochs的訓練,但是效果有限 ![Imgur](https://i.imgur.com/mhzZpD7.png) --- ### <font size="6">__**Simple RNN Model**__ </font> $$ \text{SimpleRNN(100)} \rightarrow \text{Dense(1)} $$ ##### With Bidirectional = False 這個model可以看出來n_step=50 的效果不好 而n_step=80 和 n_step=95 的效果 也不是很完美 ![Imgur](https://i.imgur.com/IJ0BOuI.png) 所以最後我拿n_steps=87 做大量epochs的訓練 ![Imgur](https://i.imgur.com/igt3ZW3.png) ---