Original_NNB/MQL5/Scripts/NeuroNetworksBook/rnn/lstm.py
super.admin e81e22b7b8 convert
2025-05-30 16:15:14 +02:00

262 lines
No EOL
14 KiB
Python

# -------------------------------------------------------#
# Скрипт для созданиия и сравнительного тестирования #
# модели полносвязного перцептрона с различными #
# свёрточными моделями на одном наборе данных. #
# В скрипте создается три модели: #
# - полносвязный перцептрон с тремя срытыми слоями #
# и регуляризацией. #
# - 2-х мерный свёрточный слой #
# - реккурентная сеть с LSTM блоком #
# При обучении моделей из обучающей выборки выделяется #
# 1% выборки для валидации результатов. #
# После обучения проводится проверка работоспособности #
# модели на тестовой выборке (отдельный файл данных) #
# -------------------------------------------------------#
# Импорт библиотек
import os
import pandas as pd
import numpy as np
import tensorflow as tf
from tensorflow import keras
import matplotlib.pyplot as plt
import MetaTrader5 as mt5
# Загрузка обучающей выборки
if not mt5.initialize():
print("initialize() failed, error code =",mt5.last_error())
quit()
path=os.path.join(mt5.terminal_info().data_path,r'MQL5\Files')
mt5.shutdown()
filename = os.path.join(path,'study_data.csv')
data = np.asarray( pd.read_table(filename,
sep=',',
header=None,
skipinitialspace=True,
encoding='utf-8',
float_precision='high',
dtype=np.float64,
low_memory=False))
# Разделение обучающей выборки на исходные данные и цели
inputs=data.shape[1]-2
targerts=2
train_data=data[:,0:inputs]
train_target=data[:,inputs:]
callback = tf.keras.callbacks.EarlyStopping(monitor='loss', patience=20)
# Созданиие модели перцептрона с тремя скрытыми слоями и регуляризацией
model1 = keras.Sequential([keras.layers.InputLayer(input_shape=inputs),
keras.layers.Dense(40, activation=tf.nn.swish, kernel_regularizer=keras.regularizers.l1_l2(l1=1e-7, l2=1e-5)),
keras.layers.Dense(40, activation=tf.nn.swish, kernel_regularizer=keras.regularizers.l1_l2(l1=1e-7, l2=1e-5)),
keras.layers.Dense(40, activation=tf.nn.swish, kernel_regularizer=keras.regularizers.l1_l2(l1=1e-7, l2=1e-5)),
keras.layers.Dense(targerts, activation=tf.nn.tanh)
])
model1.summary()
keras.utils.plot_model(model1, show_shapes=True, to_file=os.path.join(path,'model1.png'),dpi=72,show_layer_names=False,rankdir='LR')
# Добавляем в модель LSTM блок
model2 = keras.Sequential([keras.layers.InputLayer(input_shape=inputs),
# Переформатируем тензор в 3-х мерный. Указываем 2 измерения, т.к. 3-е измерение определяется размером пакета
keras.layers.Reshape((-1,4)),
# LSTM блок содержит 40 элементов и возвращает результата на каждом шаге
keras.layers.LSTM(40, return_sequences=False,
kernel_regularizer=keras.regularizers.l1_l2(l1=1e-7, l2=1e-5)),
keras.layers.Dense(40, activation=tf.nn.swish, kernel_regularizer=keras.regularizers.l1_l2(l1=1e-7, l2=1e-5)),
keras.layers.Dense(40, activation=tf.nn.swish, kernel_regularizer=keras.regularizers.l1_l2(l1=1e-7, l2=1e-5)),
keras.layers.Dense(40, activation=tf.nn.swish, kernel_regularizer=keras.regularizers.l1_l2(l1=1e-7, l2=1e-5)),
keras.layers.Dense(targerts, activation=tf.nn.tanh)
])
model2.summary()
keras.utils.plot_model(model2, show_shapes=True, to_file=os.path.join(path,'model2.png'),dpi=72,show_layer_names=False,rankdir='LR',expand_nested=True)
# Модель с 2-х мерным свёрточным слоем
model3 = keras.Sequential([keras.layers.InputLayer(input_shape=inputs),
# Переформатируем тензор в 4-х мерный. Указываем 3 измерения, т.к. 4-е измерение определяется размером пакета
keras.layers.Reshape((-1,4,1)),
# Свёрточный слой с 8-ю фильтрами
keras.layers.Conv2D(8,(3,1),1,activation=tf.nn.swish, kernel_regularizer=keras.regularizers.l1_l2(l1=1e-7, l2=1e-5)),
# Подвыборочный слой
keras.layers.MaxPooling2D((2,1),strides=1),
# Переформатируем тензор в 2-х мерный для полносвязных слоёв
keras.layers.Flatten(),
keras.layers.Dense(40, activation=tf.nn.swish, kernel_regularizer=keras.regularizers.l1_l2(l1=1e-7, l2=1e-5)),
keras.layers.Dense(40, activation=tf.nn.swish, kernel_regularizer=keras.regularizers.l1_l2(l1=1e-7, l2=1e-5)),
keras.layers.Dense(40, activation=tf.nn.swish, kernel_regularizer=keras.regularizers.l1_l2(l1=1e-7, l2=1e-5)),
keras.layers.Dense(targerts, activation=tf.nn.tanh)
])
model3.summary()
keras.utils.plot_model(model3, show_shapes=True, to_file=os.path.join(path,'model3.png'),dpi=72,show_layer_names=False,rankdir='LR')
# Модель LSTM блок без полносвязных слоёв
model4 = keras.Sequential([keras.layers.InputLayer(input_shape=inputs),
# Переформатируем тензор в 3-х мерный. Указываем 2 измерения, т.к. 3-е измерение определяется размером пакета
keras.layers.Reshape((-1,4)),
# 2 последовательных LSTM блока
# 1-й содержит 40 элементами
keras.layers.LSTM(40,
kernel_regularizer=keras.regularizers.l1_l2(l1=1e-7, l2=1e-5),
return_sequences=False),
# 2-й выдаёт результат вместо полносвязного слоя
keras.layers.Reshape((-1,2)),
keras.layers.LSTM(targerts)
])
model4.summary()
keras.utils.plot_model(model4, show_shapes=True, to_file=os.path.join(path,'model4.png'),dpi=72,show_layer_names=False,rankdir='LR')
# Модель LSTM блок без полносвязных слоёв
model5 = keras.Sequential([keras.layers.InputLayer(input_shape=inputs),
# Переформатируем тензор в 3-х мерный. Указываем 2 измерения, т.к. 3-е измерение определяется размером пакета
keras.layers.Reshape((-1,4)),
# 2 последовательных LSTM блока
# 1-й содержит 40 элементами и возвращает результата на каждом шаге
keras.layers.LSTM(40,
kernel_regularizer=keras.regularizers.l1_l2(l1=1e-7, l2=1e-5),
return_sequences=True),
# 2-й выдаёт результат вместо полносвязного слоя
keras.layers.LSTM(targerts)
])
model5.summary()
keras.utils.plot_model(model5, show_shapes=True, to_file=os.path.join(path,'model5.png'),dpi=72,show_layer_names=False,rankdir='LR')
model1.compile(optimizer='Adam',
loss='mean_squared_error',
metrics=['accuracy'])
history1 = model1.fit(train_data, train_target,
epochs=500, batch_size=1000,
callbacks=[callback],
verbose=2,
validation_split=0.01,
shuffle=True)
model1.save(os.path.join(path,'rnn1.h5'))
model2.compile(optimizer='Adam',
loss='mean_squared_error',
metrics=['accuracy'])
history2 = model2.fit(train_data, train_target,
epochs=500, batch_size=1000,
callbacks=[callback],
verbose=2,
validation_split=0.01,
shuffle=False)
model2.save(os.path.join(path,'rnn2.h5'))
model3.compile(optimizer='Adam',
loss='mean_squared_error',
metrics=['accuracy'])
history3 = model3.fit(train_data, train_target,
epochs=500, batch_size=1000,
callbacks=[callback],
verbose=2,
validation_split=0.01,
shuffle=True)
model3.save(os.path.join(path,'rnn3.h5'))
model4.compile(optimizer='Adam',
loss='mean_squared_error',
metrics=['accuracy'])
history4 = model4.fit(train_data, train_target,
epochs=500, batch_size=1000,
callbacks=[callback],
verbose=2,
validation_split=0.01,
shuffle=False)
model4.save(os.path.join(path,'rnn4.h5'))
model5.compile(optimizer='Adam',
loss='mean_squared_error',
metrics=['accuracy'])
history5 = model5.fit(train_data, train_target,
epochs=500, batch_size=1000,
callbacks=[callback],
verbose=2,
validation_split=0.01,
shuffle=False)
model5.save(os.path.join(path,'rnn5.h5'))
# Отрисовка результатов обучения моделей
plt.figure()
plt.plot(history1.history['loss'], label='Perceptron Train')
plt.plot(history1.history['val_loss'], label='Perceptron Validation')
plt.plot(history3.history['loss'], label='Conv2D Train')
plt.plot(history3.history['val_loss'], label='Conv2D Validation')
plt.plot(history2.history['loss'], label='LSTM Train')
plt.plot(history2.history['val_loss'], label='LSTM Validation')
plt.plot(history4.history['loss'], label='LSTM only Train')
plt.plot(history4.history['val_loss'], label='LSTM only Validation')
plt.plot(history5.history['loss'], label='LSTM sequences Train')
plt.plot(history5.history['val_loss'], label='LSTM sequences Validation')
plt.ylabel('$MSE$ $Loss$')
plt.xlabel('$Epochs$')
plt.title('Dinamic of Models train')
plt.legend(loc='upper right',fontsize='x-small',ncol=2)
plt.figure()
plt.plot(history1.history['accuracy'], label='Perceptron Train')
plt.plot(history1.history['val_accuracy'], label='Perceptron Validation')
plt.plot(history3.history['accuracy'], label='Conv2D Train')
plt.plot(history3.history['val_accuracy'], label='Conv2D Validation')
plt.plot(history2.history['accuracy'], label='LSTM Train')
plt.plot(history2.history['val_accuracy'], label='LSTM Validation')
plt.plot(history4.history['accuracy'], label='LSTM only Train')
plt.plot(history4.history['val_accuracy'], label='LSTM only Validation')
plt.plot(history5.history['accuracy'], label='LSTM sequences Train')
plt.plot(history5.history['val_accuracy'], label='LSTM sequences Validation')
plt.ylabel('$Accuracy$')
plt.xlabel('$Epochs$')
plt.title('Dinamic of Models train')
plt.legend(loc='lower right',fontsize='x-small',ncol=2)
# Загрузка тестовой выборки
test_filename = os.path.join(path,'test_data.csv')
test = np.asarray( pd.read_table(test_filename,
sep=',',
header=None,
skipinitialspace=True,
encoding='utf-8',
float_precision='high',
dtype=np.float64,
low_memory=False))
# Разделение тестовой выборки на исходные данные и цели
test_data=test[:,0:inputs]
test_target=test[:,inputs:]
# Проверка результатов моделей на тестовой выборке
test_loss1, test_acc1 = model1.evaluate(test_data, test_target, verbose=2)
test_loss2, test_acc2 = model2.evaluate(test_data, test_target, verbose=2)
test_loss3, test_acc3 = model3.evaluate(test_data, test_target, verbose=2)
test_loss4, test_acc4 = model4.evaluate(test_data, test_target, verbose=2)
test_loss5, test_acc5 = model5.evaluate(test_data, test_target, verbose=2)
# Вывод результатов тестирования в журнал
print('Perceptron Model')
print('Test accuracy:', test_acc1)
print('Test loss:', test_loss1)
print('Conv2D Model')
print('Test accuracy:', test_acc3)
print('Test loss:', test_loss3)
print('LSTM Model')
print('Test accuracy:', test_acc2)
print('Test loss:', test_loss2)
print('LSTM only Model')
print('Test accuracy:', test_acc4)
print('Test loss:', test_loss4)
print('LSTM sequences Model')
print('Test accuracy:', test_acc5)
print('Test loss:', test_loss5)
plt.figure()
plt.bar(['Perceptron','Conv2D','LSTM', 'LSTM only', 'LSTM sequences'],[test_loss1,test_loss3,test_loss2,test_loss4,test_loss5])
plt.ylabel('$MSE$ $Loss$')
plt.title('Result of test')
plt.figure()
plt.bar(['Perceptron','Conv2D','LSTM', 'LSTM only', 'LSTM sequences'],[test_acc1,test_acc3,test_acc2,test_acc4,test_acc5])
plt.ylabel('$Accuracy$')
plt.title('Result of test')
plt.show()