Time Series Prediction

目錄

問題

在這次的作業中,我們會被給予第一部份的序列
x(t)t=11000
.

目標是設計一個循環神經網路(Recurrent Neural Network, RNN)來預測第二部分的序列
x(t)t=10011500

而第二部分的序列將由老師自行測試,這部分的數據不會空開。

方法

以下方法將供你們參考

你可以用任何RNN的模型(Simple RNN, LSTM, GRU)來做預測,請注意,其他種類的類神經網路將不被允許。

在時間
t+1
, 訓練後的RNN可以使用過去一連串的時間向量M步來預測出
x(t+1)
,舉例,

X(tM+1),X(tM+2),...,X(t)

X(i)
是一個向量 包含了N個連續資料點
x(i),x(i1),...,x(iN1)

為了可以有好的預測準確率,你可以隨意地去測定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可以有比較好的預測

Bidirectional GRU Model

GRU(100)Dense(1)

With Bidirectional = True

這個model可以看出來n_step=50 和 60 效果都不好

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

所以最後我拿n_steps=30 做大量epochs的訓練
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


GRU Model

GRU(100)Dense(1)

With Bidirectional = False

這個model可以看出來n_step=40 和 50 效果都不好

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


Bidirectional LSTM Model

LSTM(100)Dense(1)

With Bidirectional = True

這個model可以看出來 不管n_steps為多少效果都很好

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


LSTM Model

LSTM(100)Dense(1)

With Bidirectional = False

這個model可以看出來n_step=95 的效果不好
n_step = 87 的效果已經還不錯,但是相較於n_step=50還是可惜一些

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


Bidirectional Simple RNN Model

SimpleRNN(100)Dense(1)

With Bidirectional = True

這個model可以看出來n_step=80 和 90 效果都不好

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


Simple RNN Model

SimpleRNN(100)Dense(1)

With Bidirectional = False

這個model可以看出來n_step=50 的效果不好
而n_step=80 和 n_step=95 的效果 也不是很完美

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