1.Tensoflow2描述LSTM層
2.代碼實現
#! /usr/bin/env python # -*- coding:utf-8 -*- # __author__ = "yanjungan" import numpy as np import tensorflow as tf from tensorflow.keras.layers import Dropout, Dense, LSTM import matplotlib.pyplot as plt import os import pandas as pd from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import mean_squared_error, mean_absolute_error import math # 讀取股票文件 maotai = pd.read_csv('./datasets/SH600519.csv') # 前(2426-300=2126)天的開盤價作為訓練集,表格從0開始計數,2:3是提取[2:3]列,前閉后開,故提取出c列開盤價 training_set = maotai.iloc[0:2426 - 300, 2:3].values # 后300天數據 test_set = maotai.iloc[2426 - 300:, 2:3].values # 歸一化 # 定義歸一化,歸一化到(0,1)之間 sc = MinMaxScaler(feature_range=(0, 1)) # 求得訓練集的最大值,最小值這些訓練集固有的屬性,並在訓練集上進行歸一化 training_set_scaled = sc.fit_transform(training_set) # 利用訓練集的屬性對測試集進行歸一化 test_set = sc.transform(test_set) x_train = [] y_train = [] x_test = [] y_test = [] # 訓練集:csv表格中前2426-300=2126天數據 # 利用for循環,遍歷整個訓練集,提取訓練集中連續60天的開盤價作為輸入特征x_train, # 第61天的數據作為標簽,for循環共構建2426-300-60=2066組數據。 for i in range(60, len(training_set_scaled)): x_train.append(training_set_scaled[i - 60:i, 0]) y_train.append(training_set_scaled[i, 0]) # 打亂訓練集數據 np.random.seed(7) np.random.shuffle(x_train) np.random.seed(7) np.random.shuffle(y_train) tf.random.set_seed(7) # 將訓練集由list變成array格式 x_train, y_train = np.array(x_train), np.array(y_train) # 使x_train符合RNN輸入要求:[送入樣本數, 循環核時間展開步數, 每個時間步輸入特征個數]。 # 此處整個數據集送入,送入樣本數為x_train.shape[0]即2066組數據;輸入60個開盤價,預測出第61天的開盤價,循環核時間展開步數為60; # 每個時間步送入的特征是某一天的開盤價,只有1個數據,故每個時間步輸入特征個數為1 x_train = np.reshape(x_train, (x_train.shape[0], 60, 1)) # 測試集:csv表格中后300天數據 # 利用for循環,遍歷整個測試集,提取測試集中連續60天的開盤價作為輸入特征x_train,第61天的數據作為標簽,for循環共構建300-60=240組數據。 for i in range(60, len(test_set)): x_test.append(test_set[i - 60:i, 0]) y_test.append(test_set[i, 0]) # 將測試集由list變成array格式 x_test, y_test = np.array(x_test), np.array(y_test) # 測試集變array並reshape為符合RNN輸入要求:[送入樣本數, 循環核時間展開步數, 每個時間步輸入特征個數] x_test = np.reshape(x_test, [x_test.shape[0], 60, 1]) # 搭建神經網絡 model = tf.keras.Sequential([ LSTM(80, return_sequences=True), # return_sequences=True,循環核各時刻會把ht推送到下一層 Dropout(0.2), LSTM(100), Dropout(0.2), Dense(1) ]) # 配置訓練方法 model.compile( optimizer=tf.keras.optimizers.Adam(0.001), loss='mean_squared_error' # 損失函數用均方誤差 ) # 該應用只觀測loss數值,不觀測准確率,所以刪去metrics選項,一會在每個epoch迭代顯示時只顯示loss值 # 保存模型 checkpoint_path_save = './checkpoint/lstm_stock.ckpt' # 如果模型存在,就加載模型 if os.path.exists(checkpoint_path_save + '.index'): print('--------------------load the model----------------------') # 加載模型 model.load_weights(checkpoint_path_save) # 保存模型,借助tensorflow給出的回調函數,直接保存參數和網絡 ''' 注: monitor 配合 save_best_only 可以保存最優模型, 包括:訓練損失最小模型、測試損失最小模型、訓練准確率最高模型、測試准確率最高模型等。 ''' cp_callback = tf.keras.callbacks.ModelCheckpoint( filepath=checkpoint_path_save, save_weights_only=True, save_best_only=True, monitor='val_loss' ) # 模型訓練 history = model.fit(x_train, y_train, batch_size=64, epochs=50, validation_data=(x_test, y_test), validation_freq=1, callbacks=[cp_callback]) # 統計網絡結構參數 model.summary() # 參數提取,寫至weights_stock.txt文件中 file = open('./lstm_weights_stock.txt', 'w') for v in model.trainable_variables: file.write(str(v.name) + '\n') file.write(str(v.shape) + '\n') file.write(str(v.numpy()) + '\n') file.close() # 獲取loss loss = history.history['loss'] val_loss = history.history['val_loss'] # 繪制loss plt.plot(loss, label='Training Loss') plt.plot(val_loss, label='Validation Loss') plt.title('Training and Validation Loss') plt.legend() plt.show() ######################## predict ################################### # 測試集輸入到模型中進行預測 predicted_stock_price = model.predict(x_test) # 對預測數據還原---從(0, 1)反歸一化到原始范圍 predicted_stock_price = sc.inverse_transform(predicted_stock_price) # 對真實數據還原---從(0, 1)反歸一化到原始范圍 real_stock_price = sc.inverse_transform(test_set[60:]) # 畫出真實數據和預測數據的對比曲線 plt.plot(real_stock_price, color='red', label='Real MaoTai Stock Price') plt.plot(predicted_stock_price, color='blue', label='Predicted MaoTai Stock Price') plt.title('MaoTai Stock Price Prediction') plt.xlabel('Time') plt.ylabel('MaoTai Stock Price') plt.legend() plt.show() ###################### evluate ###################### # calculate MSE 均方誤差 ---> E[(預測值-真實值)^2] (預測值減真實值求平方后求均值) mse = mean_squared_error(predicted_stock_price, real_stock_price) # calculate RMSE 均方根誤差--->sqrt[MSE] (對均方誤差開方) rmse = math.sqrt(mean_squared_error(predicted_stock_price, real_stock_price)) # calculate MAE 平均絕對誤差----->E[|預測值-真實值|](預測值減真實值求絕對值后求均值) mae = mean_absolute_error(predicted_stock_price, real_stock_price) print('均方誤差: %.6f' % mse) print('均方根誤差: %.6f' % rmse) print('平均絕對誤差: %.6f' % mae)
需要改變的地方
輸出結果: