今天我們要來實作LSTM以及GRU。
我們使用Colab來當作我們的實作平台,並使用Keras來完成。
我們使用Google stock price來當作我們的資料集。
訓練集:2012年到2016年(共1258天)
測試集:2017年1月(共20天)
訓練集下載處
測試集下載處
首先要把我們的資料scale到0~1之間。
from keras.layers import Input, Dense, Conv1D, Conv2D, MaxPooling1D,\
MaxPooling2D, UpSampling1D, UpSampling2D, Dropout, Lambda, Convolution2D,\
Reshape, Activation, Flatten, add, concatenate, BatchNormalization,LSTM
from keras.models import Model, Sequential
import numpy as np
import keras
import csv
train_set=np.array([])
# 開啟 CSV 檔案
with open(os.path.join(workspace_dir, 'Train.csv'), newline='') as csvfile:
rows = csv.reader(csvfile)
for row in rows:
train_set=np.append(train_set,row[1])
train_set=train_set[1:]
train_set=train_set.astype(float)
train_set=train_set.reshape((-1,1))
from sklearn.preprocessing import MinMaxScaler
sc = MinMaxScaler(feature_range = (0, 1))
x_train = sc.fit_transform(train_set)
接著設定Timestep。
X_train = [] #預測點的前N天的資料
y_train = [] #預測點
N=60#Timestep數量
for i in range(N, len(x_train)): # 1258 是訓練集總數
X_train.append(x_train[i-N:i, 0]) # 取出預測點的前N天放進訓練集
y_train.append(x_train[i, 0]) # 取出預測點放進label
X_train, y_train = np.array(X_train), np.array(y_train)
X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))
# model
input_shape=(X_train.shape[1], 1)
input = Input(input_shape, name='input')
layer=LSTM(units = 100, return_sequences = True)(input)
layer = Dropout(0.15)(layer)
layer=LSTM(units = 80, return_sequences = True)(layer)
layer = Dropout(0.15)(layer)
layer=LSTM(units = 60, return_sequences = True)(layer)
layer = Dropout(0.15)(layer)
layer=LSTM(units = 60)(layer)
layer = Dropout(0.15)(layer)
output=Dense(1)(layer)
model = Model(inputs=[input], outputs=[output])
model.summary()
model.compile(optimizer = 'adam', loss = 'MSE')
要注意的一點為 連接Output的地方return_sequences=false。
GRU也設一樣。
# model
input_shape=(X_train.shape[1], 1)
input = Input(input_shape, name='input')
layer=GRU(units = 100, return_sequences = True)(input)
layer = Dropout(0.15)(layer)
layer=GRU(units = 80, return_sequences = True)(layer)
layer = Dropout(0.15)(layer)
layer=GRU(units = 60, return_sequences = True)(layer)
layer = Dropout(0.15)(layer)
layer=GRU(units = 60)(layer)
layer = Dropout(0.15)(layer)
output=Dense(1)(layer)
model = Model(inputs=[input], outputs=[output])
model.summary()
model.compile(optimizer = 'adam', loss = 'MSE')
有了模型以後,就可以進行訓練了。
# 進行訓練
tag = 'LSTM0916_{}'.format(0)
h5_weight_path = os.path.join(WEIGHT_DIR, './' + tag + '.h5')
model.fit(X_train, y_train, epochs = 100, batch_size = 30)
#儲存權重
model.save_weights(os.path.join(WEIGHT_DIR, tag + ".h5"))
訓練完畢後,記得先把測試資料集也先scale。
test_set=np.array([])
# 開啟 CSV 檔案
with open(os.path.join(workspace_dir, 'Test.csv'), newline='') as csvfile:
rows = csv.reader(csvfile)
for row in rows:
test_set=np.append(test_set,row[1])
test_set=test_set[1:]
test_set=test_set.astype(float)
test_set=test_set.reshape((-1,1))
predict_dataset=np.append(train_set,test_set)
predict_dataset=predict_dataset[len(predict_dataset) - len(test_set) - N:]# timesteps為N:N+20 先前的N天資料+2017年的20天資料
predict_dataset=predict_dataset.reshape(-1,1)
predict_dataset=sc.transform(predict_dataset)
X_test = []
for i in range(N, len(predict_dataset)):
X_test.append(predict_dataset[i-N:i, 0])
X_test = np.array(X_test)
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))
值得一提的是這邊轉換是用sc.transform
,而不是sc.fit_transform
。
通常會對train data 使用fit_transform
,test data再使用sc.transform
。
轉完後,就可以測試啦XD
predicted_stock_price = model.predict(X_test)
predicted_stock_price = sc.inverse_transform(predicted_stock_price)
因為要畫出圖形,所以要把轉換的資料再轉換回去。
# Visualising the results
import matplotlib.pyplot as plt
plt.plot(test_set, color = 'red', label = 'True Google Stock Price') # 紅線表示真實股價
plt.plot(Grudata, color = 'k', label = 'Predicted Google Stock Price by GRU')
plt.plot(predicted_stock_price, color = 'blue', label = 'Predicted Google Stock Price by LSTM')
plt.title('Google Stock Price Prediction')
plt.xlabel('Day')
plt.ylabel('Google Stock Price')
plt.legend()
plt.savefig("./123.png",dpi=1000)
plt.show()
今天我們實作了LSTM以及GRU,並且結果與真實結果的走勢是差不多的,且GRU較LSTM還好了一點,但是我們可以發現價格上來說還是有落差,因此還是不要相信此模型去買股票喔(誤。
[實戰系列] 使用 Keras 搭建一個 LSTM 魔法陣(模型)
fit_transform,fit,transform區別和作用詳解!!!!!!