From 57aaa390d08f02b46b12a4bf467cc5eca7d889de Mon Sep 17 00:00:00 2001 From: robcaulk Date: Sun, 27 Nov 2022 17:42:03 +0100 Subject: [PATCH 01/11] start convolution neural network plugin --- .../freqai/base_models/BaseTensorFlowModel.py | 90 ++++++++++- .../prediction_models/CNNPredictionModel.py | 145 ++++++++++++++++++ requirements-freqai.txt | 1 + 3 files changed, 229 insertions(+), 7 deletions(-) create mode 100644 freqtrade/freqai/prediction_models/CNNPredictionModel.py diff --git a/freqtrade/freqai/base_models/BaseTensorFlowModel.py b/freqtrade/freqai/base_models/BaseTensorFlowModel.py index b41ee0175..a12a6a9ef 100644 --- a/freqtrade/freqai/base_models/BaseTensorFlowModel.py +++ b/freqtrade/freqai/base_models/BaseTensorFlowModel.py @@ -3,10 +3,10 @@ from time import time from typing import Any from pandas import DataFrame - +import numpy as np from freqtrade.freqai.data_kitchen import FreqaiDataKitchen from freqtrade.freqai.freqai_interface import IFreqaiModel - +import tensorflow as tf logger = logging.getLogger(__name__) @@ -17,6 +17,13 @@ class BaseTensorFlowModel(IFreqaiModel): User *must* inherit from this class and set fit() and predict(). """ + def __init__(self, **kwargs): + super().__init__(config=kwargs['config']) + self.keras = True + if self.ft_params.get("DI_threshold", 0): + self.ft_params["DI_threshold"] = 0 + logger.warning("DI threshold is not configured for Keras models yet. Deactivating.") + def train( self, unfiltered_df: DataFrame, pair: str, dk: FreqaiDataKitchen, **kwargs ) -> Any: @@ -41,13 +48,9 @@ class BaseTensorFlowModel(IFreqaiModel): training_filter=True, ) - start_date = unfiltered_df["date"].iloc[0].strftime("%Y-%m-%d") - end_date = unfiltered_df["date"].iloc[-1].strftime("%Y-%m-%d") - logger.info(f"-------------------- Training on data from {start_date} to " - f"{end_date} --------------------") # split data into train/test data. data_dictionary = dk.make_train_test_datasets(features_filtered, labels_filtered) - if not self.freqai_info.get("fit_live_predictions_candles", 0) or not self.live: + if not self.freqai_info.get("fit_live_predictions", 0) or not self.live: dk.fit_labels() # normalize all data based on train_dataset only data_dictionary = dk.normalize_data(data_dictionary) @@ -68,3 +71,76 @@ class BaseTensorFlowModel(IFreqaiModel): f"({end_time - start_time:.2f} secs) --------------------") return model + + +class WindowGenerator: + def __init__( + self, + input_width, + label_width, + shift, + train_df=None, + val_df=None, + test_df=None, + train_labels=None, + val_labels=None, + test_labels=None, + batch_size=None, + ): + # Store the raw data. + self.train_df = train_df + self.val_df = val_df + self.test_df = test_df + self.train_labels = train_labels + self.val_labels = val_labels + self.test_labels = test_labels + self.batch_size = batch_size + self.input_width = input_width + self.label_width = label_width + self.shift = shift + self.total_window_size = input_width + shift + self.input_slice = slice(0, input_width) + self.input_indices = np.arange(self.total_window_size)[self.input_slice] + + def make_dataset(self, data, labels=None): + data = np.array(data, dtype=np.float32) + if labels is not None: + labels = np.array(labels, dtype=np.float32) + ds = tf.keras.preprocessing.timeseries_dataset_from_array( + data=data, + targets=labels, + sequence_length=self.total_window_size, + sequence_stride=1, + sampling_rate=1, + shuffle=False, + batch_size=self.batch_size, + ) + + return ds + + @property + def train(self): + return self.make_dataset(self.train_df, self.train_labels) + + @property + def val(self): + return self.make_dataset(self.val_df, self.val_labels) + + @property + def test(self): + return self.make_dataset(self.test_df, self.test_labels) + + @property + def inference(self): + return self.make_dataset(self.test_df) + + @property + def example(self): + """Get and cache an example batch of `inputs, labels` for plotting.""" + result = getattr(self, "_example", None) + if result is None: + # No example batch was found, so get one from the `.train` dataset + result = next(iter(self.train)) + # And cache it for next time + self._example = result + return result diff --git a/freqtrade/freqai/prediction_models/CNNPredictionModel.py b/freqtrade/freqai/prediction_models/CNNPredictionModel.py new file mode 100644 index 000000000..4129a27cd --- /dev/null +++ b/freqtrade/freqai/prediction_models/CNNPredictionModel.py @@ -0,0 +1,145 @@ +import logging +from typing import Any, Dict, Tuple + +from pandas import DataFrame +from freqtrade.exceptions import OperationalException +from freqtrade.freqai.data_kitchen import FreqaiDataKitchen +import tensorflow as tf +from freqtrade.freqai.base_models.BaseTensorFlowModel import BaseTensorFlowModel, WindowGenerator +from tensorflow.keras.layers import Input, Conv1D, Dense +from tensorflow.keras.models import Model +import numpy as np + +logger = logging.getLogger(__name__) + +# tf.config.run_functions_eagerly(True) +# tf.data.experimental.enable_debug_mode() + +MAX_EPOCHS = 10 + + +class CNNPredictionModel(BaseTensorFlowModel): + """ + User created prediction model. The class needs to override three necessary + functions, predict(), fit(). + """ + + def fit(self, data_dictionary: Dict[str, Any], dk: FreqaiDataKitchen) -> Any: + """ + User sets up the training and test data to fit their desired model here + :params: + :data_dictionary: the dictionary constructed by DataHandler to hold + all the training and test data/labels. + """ + train_df = data_dictionary["train_features"] + train_labels = data_dictionary["train_labels"] + test_df = data_dictionary["test_features"] + test_labels = data_dictionary["test_labels"] + n_labels = len(train_labels.columns) + + if n_labels > 1: + raise OperationalException( + "Neural Net not yet configured for multi-targets. Please " + " reduce number of targets to 1 in strategy." + ) + + n_features = len(data_dictionary["train_features"].columns) + BATCH_SIZE = self.freqai_info.get("batch_size", 64) + input_dims = [BATCH_SIZE, self.CONV_WIDTH, n_features] + + w1 = WindowGenerator( + input_width=self.CONV_WIDTH, + label_width=1, + shift=1, + train_df=train_df, + val_df=test_df, + train_labels=train_labels, + val_labels=test_labels, + batch_size=BATCH_SIZE, + ) + + model = self.create_model(input_dims, n_labels) + + steps_per_epoch = np.ceil(len(test_df) / BATCH_SIZE) + lr_schedule = tf.keras.optimizers.schedules.InverseTimeDecay( + 0.001, decay_steps=steps_per_epoch * 1000, decay_rate=1, staircase=False + ) + + early_stopping = tf.keras.callbacks.EarlyStopping( + monitor="loss", patience=3, mode="min", min_delta=0.0001 + ) + + model.compile( + loss=tf.losses.MeanSquaredError(), + optimizer=tf.optimizers.Adam(lr_schedule), + metrics=[tf.metrics.MeanAbsoluteError()], + ) + + model.fit( + w1.train, + epochs=MAX_EPOCHS, + shuffle=False, + validation_data=w1.val, + callbacks=[early_stopping], + verbose=1, + ) + + return model + + def predict( + self, unfiltered_dataframe: DataFrame, dk: FreqaiDataKitchen, first=True + ) -> Tuple[DataFrame, DataFrame]: + """ + Filter the prediction features data and predict with it. + :param: unfiltered_dataframe: Full dataframe for the current backtest period. + :return: + :predictions: np.array of predictions + :do_predict: np.array of 1s and 0s to indicate places where freqai needed to remove + data (NaNs) or felt uncertain about data (PCA and DI index) + """ + + dk.find_features(unfiltered_dataframe) + filtered_dataframe, _ = dk.filter_features( + unfiltered_dataframe, dk.training_features_list, training_filter=False + ) + filtered_dataframe = dk.normalize_data_from_metadata(filtered_dataframe) + dk.data_dictionary["prediction_features"] = filtered_dataframe + + # optional additional data cleaning/analysis + self.data_cleaning_predict(dk, filtered_dataframe) + + if first: + full_df = dk.data_dictionary["prediction_features"] + + w1 = WindowGenerator( + input_width=self.CONV_WIDTH, + label_width=1, + shift=1, + test_df=full_df, + batch_size=len(full_df), + ) + + predictions = self.model.predict(w1.inference) + len_diff = len(dk.do_predict) - len(predictions) + if len_diff > 0: + dk.do_predict = dk.do_predict[len_diff:] + + else: + data = dk.data_dictionary["prediction_features"] + data = tf.expand_dims(data, axis=0) + predictions = self.model(data, training=False) + + predictions = predictions[:, 0, 0] + pred_df = DataFrame(predictions, columns=dk.label_list) + + pred_df = dk.denormalize_labels_from_metadata(pred_df) + + return (pred_df, np.ones(len(pred_df))) + + def create_model(self, input_dims, n_labels) -> Any: + + input_layer = Input(shape=(input_dims[1], input_dims[2])) + Layer_1 = Conv1D(filters=32, kernel_size=(self.CONV_WIDTH,), activation="relu")(input_layer) + Layer_3 = Dense(units=32, activation="relu")(Layer_1) + output_layer = Dense(units=n_labels)(Layer_3) + return Model(inputs=input_layer, outputs=output_layer) diff --git a/requirements-freqai.txt b/requirements-freqai.txt index 66730e29f..f83e65d8e 100644 --- a/requirements-freqai.txt +++ b/requirements-freqai.txt @@ -9,3 +9,4 @@ catboost==1.1.1; platform_machine != 'aarch64' lightgbm==3.3.3 xgboost==1.7.1 tensorboard==2.11.0 +tensorflow==3.2.2 From ad7729e5d85c05a08fcb0ab061d01687d6067e30 Mon Sep 17 00:00:00 2001 From: Emre Date: Sat, 3 Dec 2022 17:43:59 +0300 Subject: [PATCH 02/11] Fix function signature --- freqtrade/freqai/prediction_models/CNNPredictionModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/freqai/prediction_models/CNNPredictionModel.py b/freqtrade/freqai/prediction_models/CNNPredictionModel.py index 4129a27cd..80e3c447f 100644 --- a/freqtrade/freqai/prediction_models/CNNPredictionModel.py +++ b/freqtrade/freqai/prediction_models/CNNPredictionModel.py @@ -106,7 +106,7 @@ class CNNPredictionModel(BaseTensorFlowModel): dk.data_dictionary["prediction_features"] = filtered_dataframe # optional additional data cleaning/analysis - self.data_cleaning_predict(dk, filtered_dataframe) + self.data_cleaning_predict(dk) if first: full_df = dk.data_dictionary["prediction_features"] From 43c0d305a372ee28b59a371709cc67d54661be46 Mon Sep 17 00:00:00 2001 From: robcaulk Date: Mon, 5 Dec 2022 20:36:08 +0100 Subject: [PATCH 03/11] fix tensorflow version --- requirements-freqai.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-freqai.txt b/requirements-freqai.txt index f83e65d8e..3a9f26e32 100644 --- a/requirements-freqai.txt +++ b/requirements-freqai.txt @@ -9,4 +9,4 @@ catboost==1.1.1; platform_machine != 'aarch64' lightgbm==3.3.3 xgboost==1.7.1 tensorboard==2.11.0 -tensorflow==3.2.2 +tensorflow==2.11.0 From 72b1d1c9aea5c88b959964e24ba0bb215104564f Mon Sep 17 00:00:00 2001 From: robcaulk Date: Mon, 5 Dec 2022 20:55:05 +0100 Subject: [PATCH 04/11] allow users to pass 0 test data --- docs/freqai-parameter-table.md | 2 +- freqtrade/freqai/base_models/BaseTensorFlowModel.py | 1 + freqtrade/freqai/prediction_models/CNNPredictionModel.py | 7 ++++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/freqai-parameter-table.md b/docs/freqai-parameter-table.md index d05ce80f3..c0d82004b 100644 --- a/docs/freqai-parameter-table.md +++ b/docs/freqai-parameter-table.md @@ -89,6 +89,6 @@ Mandatory parameters are marked as **Required** and have to be set in one of the | Parameter | Description | |------------|-------------| | | **Extraneous parameters** -| `freqai.keras` | If the selected model makes use of Keras (typical for Tensorflow-based prediction models), this flag needs to be activated so that the model save/loading follows Keras standards.
**Datatype:** Boolean.
Default: `False`. +| `freqai.keras` | If the selected model makes use of Keras (typical for Tensorflow-based prediction models), this flag should be activated so that the model save/loading follows Keras standards. If the the provided `CNNPredictionModel` is used, then this is handled automatically.
**Datatype:** Boolean.
Default: `False`. | `freqai.conv_width` | The width of a convolutional neural network input tensor. This replaces the need for shifting candles (`include_shifted_candles`) by feeding in historical data points as the second dimension of the tensor. Technically, this parameter can also be used for regressors, but it only adds computational overhead and does not change the model training/prediction.
**Datatype:** Integer.
Default: `2`. | `freqai.reduce_df_footprint` | Recast all numeric columns to float32/int32, with the objective of reducing ram/disk usage and decreasing train/inference timing. This parameter is set in the main level of the Freqtrade configuration file (not inside FreqAI).
**Datatype:** Boolean.
Default: `False`. diff --git a/freqtrade/freqai/base_models/BaseTensorFlowModel.py b/freqtrade/freqai/base_models/BaseTensorFlowModel.py index a12a6a9ef..f7aec1f8b 100644 --- a/freqtrade/freqai/base_models/BaseTensorFlowModel.py +++ b/freqtrade/freqai/base_models/BaseTensorFlowModel.py @@ -23,6 +23,7 @@ class BaseTensorFlowModel(IFreqaiModel): if self.ft_params.get("DI_threshold", 0): self.ft_params["DI_threshold"] = 0 logger.warning("DI threshold is not configured for Keras models yet. Deactivating.") + self.dd.model_type = 'keras' def train( self, unfiltered_df: DataFrame, pair: str, dk: FreqaiDataKitchen, **kwargs diff --git a/freqtrade/freqai/prediction_models/CNNPredictionModel.py b/freqtrade/freqai/prediction_models/CNNPredictionModel.py index 80e3c447f..b6ab73138 100644 --- a/freqtrade/freqai/prediction_models/CNNPredictionModel.py +++ b/freqtrade/freqai/prediction_models/CNNPredictionModel.py @@ -75,11 +75,16 @@ class CNNPredictionModel(BaseTensorFlowModel): metrics=[tf.metrics.MeanAbsoluteError()], ) + if self.freqai_info.get('data_split_parameters', {}).get('test_size', 0.1) == 0: + val_data = None + else: + val_data = w1.val + model.fit( w1.train, epochs=MAX_EPOCHS, shuffle=False, - validation_data=w1.val, + validation_data=val_data, callbacks=[early_stopping], verbose=1, ) From 9ce8255f24859e684afae939952e067355be7b1a Mon Sep 17 00:00:00 2001 From: robcaulk Date: Mon, 5 Dec 2022 21:03:05 +0100 Subject: [PATCH 05/11] isort. --- .../freqai/base_models/BaseTensorFlowModel.py | 6 ++++-- .../prediction_models/CNNPredictionModel.py | 16 +++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/freqtrade/freqai/base_models/BaseTensorFlowModel.py b/freqtrade/freqai/base_models/BaseTensorFlowModel.py index f7aec1f8b..2f95b6314 100644 --- a/freqtrade/freqai/base_models/BaseTensorFlowModel.py +++ b/freqtrade/freqai/base_models/BaseTensorFlowModel.py @@ -2,11 +2,13 @@ import logging from time import time from typing import Any -from pandas import DataFrame import numpy as np +import tensorflow as tf +from pandas import DataFrame + from freqtrade.freqai.data_kitchen import FreqaiDataKitchen from freqtrade.freqai.freqai_interface import IFreqaiModel -import tensorflow as tf + logger = logging.getLogger(__name__) diff --git a/freqtrade/freqai/prediction_models/CNNPredictionModel.py b/freqtrade/freqai/prediction_models/CNNPredictionModel.py index b6ab73138..ed67088e5 100644 --- a/freqtrade/freqai/prediction_models/CNNPredictionModel.py +++ b/freqtrade/freqai/prediction_models/CNNPredictionModel.py @@ -1,14 +1,16 @@ import logging from typing import Any, Dict, Tuple -from pandas import DataFrame -from freqtrade.exceptions import OperationalException -from freqtrade.freqai.data_kitchen import FreqaiDataKitchen -import tensorflow as tf -from freqtrade.freqai.base_models.BaseTensorFlowModel import BaseTensorFlowModel, WindowGenerator -from tensorflow.keras.layers import Input, Conv1D, Dense -from tensorflow.keras.models import Model import numpy as np +import tensorflow as tf +from pandas import DataFrame +from tensorflow.keras.layers import Conv1D, Dense, Input +from tensorflow.keras.models import Model + +from freqtrade.exceptions import OperationalException +from freqtrade.freqai.base_models.BaseTensorFlowModel import BaseTensorFlowModel, WindowGenerator +from freqtrade.freqai.data_kitchen import FreqaiDataKitchen + logger = logging.getLogger(__name__) From 665eed39060cbc20277ba27cc2959780e6c9b180 Mon Sep 17 00:00:00 2001 From: robcaulk Date: Tue, 6 Dec 2022 23:26:07 +0100 Subject: [PATCH 06/11] add documentation for CNN, allow it to interact with model_training_parameters --- docs/freqai-configuration.md | 20 +++++++++++++++++++ .../prediction_models/CNNPredictionModel.py | 12 ++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/docs/freqai-configuration.md b/docs/freqai-configuration.md index 5c3bbf90c..b7ee1a4c5 100644 --- a/docs/freqai-configuration.md +++ b/docs/freqai-configuration.md @@ -242,3 +242,23 @@ If you want to predict multiple targets you must specify all labels in the same df['&s-up_or_down'] = np.where( df["close"].shift(-100) > df["close"], 'up', 'down') df['&s-up_or_down'] = np.where( df["close"].shift(-100) == df["close"], 'same', df['&s-up_or_down']) ``` + +### Convolutional Neural Network model + +The `CNNPredictionModel` is a non-linear regression based on `Tensorflow` which follows very similar configuration to the other regressors. Feature engineering and label creation remains the same as highlighted [here](#building-a-freqai-strategy) and [here](#setting-model-targets). Control of the model is focused in the `model_training_parameters` configuration dictionary, which accepts any hyperparameter available to the CNN `fit()` function of Tensorflow [more here](https://www.tensorflow.org/api_docs/python/tf/keras/Model#fit). For example, this is where the `epochs` and `batch_size` are controlled: + +```json + "model_training_parameters" : { + "batch_size": 64, + "epochs": 10, + "verbose": "auto", + "shuffle": false + "workers": 1, + "use_multiprocessing": False + } +``` + +Running the `CNNPredictionModel` is the same as other regressors: `--freqaimodel CNNPredictionModel`. + + +``` \ No newline at end of file diff --git a/freqtrade/freqai/prediction_models/CNNPredictionModel.py b/freqtrade/freqai/prediction_models/CNNPredictionModel.py index ed67088e5..3b4de4ca3 100644 --- a/freqtrade/freqai/prediction_models/CNNPredictionModel.py +++ b/freqtrade/freqai/prediction_models/CNNPredictionModel.py @@ -17,8 +17,6 @@ logger = logging.getLogger(__name__) # tf.config.run_functions_eagerly(True) # tf.data.experimental.enable_debug_mode() -MAX_EPOCHS = 10 - class CNNPredictionModel(BaseTensorFlowModel): """ @@ -46,7 +44,12 @@ class CNNPredictionModel(BaseTensorFlowModel): ) n_features = len(data_dictionary["train_features"].columns) - BATCH_SIZE = self.freqai_info.get("batch_size", 64) + BATCH_SIZE = self.model_training_parameters.get("batch_size", 64) + + # we need to remove batch_size from the model_training_params because + # we dont want fit() to get the incorrect assignment (we use the WindowGenerator) + # to handle our batches. + self.model_training_parameters.pop('batch_size') input_dims = [BATCH_SIZE, self.CONV_WIDTH, n_features] w1 = WindowGenerator( @@ -84,8 +87,7 @@ class CNNPredictionModel(BaseTensorFlowModel): model.fit( w1.train, - epochs=MAX_EPOCHS, - shuffle=False, + **self.model_training_parameters, validation_data=val_data, callbacks=[early_stopping], verbose=1, From 389ab7e44b0c8bf061c4dc6086b6b344212cb23e Mon Sep 17 00:00:00 2001 From: robcaulk Date: Tue, 6 Dec 2022 23:50:34 +0100 Subject: [PATCH 07/11] add test for CNNPredictionModel --- freqtrade/freqai/base_models/BaseTensorFlowModel.py | 1 - freqtrade/freqai/prediction_models/CNNPredictionModel.py | 6 ++---- tests/freqai/test_freqai_interface.py | 7 ++++++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/freqtrade/freqai/base_models/BaseTensorFlowModel.py b/freqtrade/freqai/base_models/BaseTensorFlowModel.py index 2f95b6314..a86a7f5e3 100644 --- a/freqtrade/freqai/base_models/BaseTensorFlowModel.py +++ b/freqtrade/freqai/base_models/BaseTensorFlowModel.py @@ -43,7 +43,6 @@ class BaseTensorFlowModel(IFreqaiModel): start_time = time() - # filter the features requested by user in the configuration file and elegantly handle NaNs features_filtered, labels_filtered = dk.filter_features( unfiltered_df, dk.training_features_list, diff --git a/freqtrade/freqai/prediction_models/CNNPredictionModel.py b/freqtrade/freqai/prediction_models/CNNPredictionModel.py index 3b4de4ca3..5a957f59e 100644 --- a/freqtrade/freqai/prediction_models/CNNPredictionModel.py +++ b/freqtrade/freqai/prediction_models/CNNPredictionModel.py @@ -14,9 +14,6 @@ from freqtrade.freqai.data_kitchen import FreqaiDataKitchen logger = logging.getLogger(__name__) -# tf.config.run_functions_eagerly(True) -# tf.data.experimental.enable_debug_mode() - class CNNPredictionModel(BaseTensorFlowModel): """ @@ -49,7 +46,8 @@ class CNNPredictionModel(BaseTensorFlowModel): # we need to remove batch_size from the model_training_params because # we dont want fit() to get the incorrect assignment (we use the WindowGenerator) # to handle our batches. - self.model_training_parameters.pop('batch_size') + if 'batch_size' in self.model_training_parameters: + self.model_training_parameters.pop('batch_size') input_dims = [BATCH_SIZE, self.CONV_WIDTH, n_features] w1 = WindowGenerator( diff --git a/tests/freqai/test_freqai_interface.py b/tests/freqai/test_freqai_interface.py index c53137093..f7251949c 100644 --- a/tests/freqai/test_freqai_interface.py +++ b/tests/freqai/test_freqai_interface.py @@ -34,7 +34,8 @@ def is_mac() -> bool: ('CatboostRegressor', False, False, False), ('ReinforcementLearner', False, True, False), ('ReinforcementLearner_multiproc', False, False, False), - ('ReinforcementLearner_test_4ac', False, False, False) + ('ReinforcementLearner_test_4ac', False, False, False), + ('CNNPredictionModel', False, False, False) ]) def test_extract_data_and_train_model_Standard(mocker, freqai_conf, model, pca, dbscan, float32): if is_arm() and model == 'CatboostRegressor': @@ -71,6 +72,10 @@ def test_extract_data_and_train_model_Standard(mocker, freqai_conf, model, pca, if 'test_4ac' in model: freqai_conf["freqaimodel_path"] = str(Path(__file__).parents[1] / "freqai" / "test_models") + if 'CNNPredictionModel' in model: + freqai_conf['freqai']['model_training_parameters'].pop('n_estimators') + model_save_ext = 'h5' + strategy = get_patched_freqai_strategy(mocker, freqai_conf) exchange = get_patched_exchange(mocker, freqai_conf) strategy.dp = DataProvider(freqai_conf, exchange) From 6343fbf9e3213799c68e78297a41529006ec017d Mon Sep 17 00:00:00 2001 From: robcaulk Date: Wed, 7 Dec 2022 00:02:02 +0100 Subject: [PATCH 08/11] remove verbose from CNNPredictionModel --- freqtrade/freqai/prediction_models/CNNPredictionModel.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/freqtrade/freqai/prediction_models/CNNPredictionModel.py b/freqtrade/freqai/prediction_models/CNNPredictionModel.py index 5a957f59e..35d0b75fb 100644 --- a/freqtrade/freqai/prediction_models/CNNPredictionModel.py +++ b/freqtrade/freqai/prediction_models/CNNPredictionModel.py @@ -85,10 +85,9 @@ class CNNPredictionModel(BaseTensorFlowModel): model.fit( w1.train, - **self.model_training_parameters, validation_data=val_data, callbacks=[early_stopping], - verbose=1, + **self.model_training_parameters, ) return model From b438cd4b3f645bf1462cba2419a24ac37e98c9de Mon Sep 17 00:00:00 2001 From: robcaulk Date: Wed, 7 Dec 2022 19:52:31 +0100 Subject: [PATCH 09/11] add newline to end of freqai-configuration.md --- docs/freqai-configuration.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/freqai-configuration.md b/docs/freqai-configuration.md index b7ee1a4c5..3366ac592 100644 --- a/docs/freqai-configuration.md +++ b/docs/freqai-configuration.md @@ -259,6 +259,3 @@ The `CNNPredictionModel` is a non-linear regression based on `Tensorflow` which ``` Running the `CNNPredictionModel` is the same as other regressors: `--freqaimodel CNNPredictionModel`. - - -``` \ No newline at end of file From 71c6ff18c46ec0f5fee7202e46e8ca81c2e6df0c Mon Sep 17 00:00:00 2001 From: robcaulk Date: Wed, 7 Dec 2022 20:08:31 +0100 Subject: [PATCH 10/11] try to avoid possible memory leaks --- docs/freqai-configuration.md | 4 ++-- freqtrade/freqai/prediction_models/CNNPredictionModel.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/freqai-configuration.md b/docs/freqai-configuration.md index 3366ac592..c49efa753 100644 --- a/docs/freqai-configuration.md +++ b/docs/freqai-configuration.md @@ -252,9 +252,9 @@ The `CNNPredictionModel` is a non-linear regression based on `Tensorflow` which "batch_size": 64, "epochs": 10, "verbose": "auto", - "shuffle": false + "shuffle": false, "workers": 1, - "use_multiprocessing": False + "use_multiprocessing": false } ``` diff --git a/freqtrade/freqai/prediction_models/CNNPredictionModel.py b/freqtrade/freqai/prediction_models/CNNPredictionModel.py index 35d0b75fb..bf9ad22d5 100644 --- a/freqtrade/freqai/prediction_models/CNNPredictionModel.py +++ b/freqtrade/freqai/prediction_models/CNNPredictionModel.py @@ -133,6 +133,7 @@ class CNNPredictionModel(BaseTensorFlowModel): else: data = dk.data_dictionary["prediction_features"] data = tf.expand_dims(data, axis=0) + data = tf.convert_to_tensor(data) predictions = self.model(data, training=False) predictions = predictions[:, 0, 0] From 2c3a310ce2bde3a8a6b0dd1fb34350593a72cd93 Mon Sep 17 00:00:00 2001 From: robcaulk Date: Wed, 7 Dec 2022 20:30:13 +0100 Subject: [PATCH 11/11] allow DI with CNN --- freqtrade/freqai/base_models/BaseTensorFlowModel.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freqtrade/freqai/base_models/BaseTensorFlowModel.py b/freqtrade/freqai/base_models/BaseTensorFlowModel.py index a86a7f5e3..91133966c 100644 --- a/freqtrade/freqai/base_models/BaseTensorFlowModel.py +++ b/freqtrade/freqai/base_models/BaseTensorFlowModel.py @@ -22,9 +22,9 @@ class BaseTensorFlowModel(IFreqaiModel): def __init__(self, **kwargs): super().__init__(config=kwargs['config']) self.keras = True - if self.ft_params.get("DI_threshold", 0): - self.ft_params["DI_threshold"] = 0 - logger.warning("DI threshold is not configured for Keras models yet. Deactivating.") + # if self.ft_params.get("DI_threshold", 0): + # self.ft_params["DI_threshold"] = 0 + # logger.warning("DI threshold is not configured for Keras models yet. Deactivating.") self.dd.model_type = 'keras' def train(