---
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 效果都不好

所以最後我拿n_steps=30 做大量epochs的訓練

---
### <font size="6">__**GRU Model**__ </font>
$$
\text{GRU(100)} \rightarrow \text{Dense(1)}
$$
##### With Bidirectional = False
這個model可以看出來n_step=40 和 50 效果都不好

所以最後我拿n_steps=20 做大量epochs的訓練

---
### <font size="6">__**Bidirectional LSTM Model**__ </font>
$$
\text{LSTM(100)} \rightarrow \text{Dense(1)}
$$
##### With Bidirectional = True
這個model可以看出來 不管n_steps為多少效果都很好

所以最後我拿n_steps=50 做大量epochs的訓練,最後也是上傳這個model預測的值

---
### <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還是可惜一些

所以最後我拿n_steps=50 做大量epochs的訓練

---
### <font size="6">__**Bidirectional Simple RNN Model**__ </font>
$$
\text{SimpleRNN(100)} \rightarrow \text{Dense(1)}
$$
##### With Bidirectional = True
這個model可以看出來n_step=80 和 90 效果都不好

所以最後我拿n_steps=50 做大量epochs的訓練,但是效果有限

---
### <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 的效果 也不是很完美

所以最後我拿n_steps=87 做大量epochs的訓練

---