From 5f8efc97fa68a991fd39221796de0ca6c403064b Mon Sep 17 00:00:00 2001 From: Mark Aron Szulyovszky Date: Thu, 11 Nov 2021 18:29:05 +0100 Subject: [PATCH] feat(Model): now successfully training the basic LSTM model --- model_lstm.py | 49 +++++++++++++++++++--------------------------- utils/normalize.py | 2 +- utils/visualize.py | 15 ++++++++++++++ 3 files changed, 36 insertions(+), 30 deletions(-) create mode 100644 utils/visualize.py diff --git a/model_lstm.py b/model_lstm.py index 58389f2..acdd8c0 100644 --- a/model_lstm.py +++ b/model_lstm.py @@ -4,16 +4,18 @@ import pandas as pd from tensorflow import keras from utils.normalize import normalize import tensorflow as tf +from utils.visualize import visualize_loss data = load_files('data/', False) data.reset_index(drop=True, inplace=True) data = data[[column for column in data.columns if not column.endswith('volume')]] +# data = data[["ETH_returns", "BTC_returns"]] ticker_to_predict = 'ETH_returns' -learning_rate = 0.001 -batch_size = 128 -epochs = 30 +learning_rate = 0.002 +batch_size = 64 +epochs = 100 split_fraction = 0.715 train_split = int(split_fraction * int(data.shape[0])) @@ -31,7 +33,7 @@ val_data = data.loc[train_split:] #%% create features and target for training set & keras dataset x_train = normalize(train_data).values -# x_train = train_data.drop(ticker_to_predict, axis=1).values +# x_train = normalize(train_data).drop(ticker_to_predict, axis=1).values y_train = normalize(data).iloc[start:end][ticker_to_predict].values dataset_train = keras.preprocessing.timeseries_dataset_from_array( @@ -41,12 +43,13 @@ dataset_train = keras.preprocessing.timeseries_dataset_from_array( batch_size=batch_size, ) + #%% create features and target for validation set & keras dataset x_end = len(val_data) - past - future label_start = train_split + past + future x_val = normalize(val_data).iloc[:x_end].values -# x_val = val_data.iloc[:x_end].drop(ticker_to_predict, axis=1).values +# x_val = normalize(val_data).iloc[:x_end].drop(ticker_to_predict, axis=1).values y_val = normalize(data).iloc[label_start:][ticker_to_predict].values dataset_val = keras.utils.timeseries_dataset_from_array( @@ -59,47 +62,35 @@ dataset_val = keras.utils.timeseries_dataset_from_array( #%% -for batch in dataset_train.take(1): +for batch in dataset_train.take(10): batch_inputs, batch_targets = batch print("Input shape:", batch_inputs.shape) print("Target shape:", batch_targets.shape) +print(batch_inputs) +print(batch_targets) # %% -# model = keras.Sequential() -# model.add(keras.layers.LSTM(units = 50, return_sequences = True, input_shape=(batch_inputs.shape[1], batch_inputs.shape[2]))) -# model.add(keras.layers.Dropout(0.2)) -# model.add(keras.layers.Dense(units = 1)) +model = keras.Sequential() +model.add(keras.layers.LSTM(units = 32, return_sequences = True, activation = 'relu', input_shape=(batch_inputs.shape[1], batch_inputs.shape[2]))) +# model.add(keras.layers.Dropout(0.4)) +# model.add(keras.layers.Dense(units = 10, activation = 'relu')) +model.add(keras.layers.Dropout(0.4)) +model.add(keras.layers.Dense(units = 1, activation = 'relu')) -inputs = keras.layers.Input(shape=(batch_inputs.shape[1], batch_inputs.shape[2])) -lstm_out = keras.layers.LSTM(32)(inputs) -outputs = keras.layers.Dense(1)(lstm_out) -model = keras.Model(inputs=inputs, outputs=outputs) - -optimizer = keras.optimizers.Adam(learning_rate=learning_rate, clipnorm = 1.) +optimizer = keras.optimizers.Adam(learning_rate=learning_rate, clipnorm=1.0) model.compile(optimizer=optimizer, loss="mean_squared_error") model.summary() # %% path_checkpoint = "model_checkpoint.h5" -# es_callback = keras.callbacks.EarlyStopping(monitor="val_loss", min_delta=0, patience=5) - -# modelckpt_callback = keras.callbacks.ModelCheckpoint( -# monitor="val_loss", -# filepath=path_checkpoint, -# verbose=1, -# save_weights_only=True, -# save_best_only=True, -# ) -tf.debugging.enable_check_numerics( - stack_height_limit=30, path_length_limit=50 -) history = model.fit( dataset_train, epochs=epochs, validation_data=dataset_val, - # callbacks=[modelckpt_callback], ) # %% + +visualize_loss(history, "Training and Validation Loss") \ No newline at end of file diff --git a/utils/normalize.py b/utils/normalize.py index 8bd4661..057a9aa 100644 --- a/utils/normalize.py +++ b/utils/normalize.py @@ -3,4 +3,4 @@ import pandas as pd def normalize(data: pd.DataFrame) -> pd.DataFrame: data_mean = data.mean(axis=0) data_std = data.std(axis=0) - return (data - data_mean) / data_std + return ((data - data_mean) / data_std).fillna(0.) diff --git a/utils/visualize.py b/utils/visualize.py new file mode 100644 index 0000000..1186c9e --- /dev/null +++ b/utils/visualize.py @@ -0,0 +1,15 @@ +import matplotlib.pyplot as plt + + +def visualize_loss(history, title: str): + loss = history.history["loss"] + val_loss = history.history["val_loss"] + epochs = range(len(loss)) + plt.figure() + plt.plot(epochs, loss, "b", label="Training loss") + plt.plot(epochs, val_loss, "r", label="Validation loss") + plt.title(title) + plt.xlabel("Epochs") + plt.ylabel("Loss") + plt.legend() + plt.show()