diff --git a/aeon/regression/deep_learning/_cnn.py b/aeon/regression/deep_learning/_cnn.py index 351e3964d3..e2f6635fa2 100644 --- a/aeon/regression/deep_learning/_cnn.py +++ b/aeon/regression/deep_learning/_cnn.py @@ -1,5 +1,7 @@ """Time Convolutional Neural Network (TimeCNN) regressor.""" +from __future__ import annotations + __maintainer__ = ["hadifawaz1999"] __all__ = ["TimeCNNRegressor"] @@ -7,12 +9,18 @@ import os import time from copy import deepcopy +from typing import TYPE_CHECKING, Any +import numpy as np from sklearn.utils import check_random_state from aeon.networks import TimeCNNNetwork from aeon.regression.deep_learning.base import BaseDeepRegressor +if TYPE_CHECKING: + import tensorflow as tf + from tensorflow.keras.callbacks import Callback + class TimeCNNRegressor(BaseDeepRegressor): """Time Series Convolutional Neural Network (CNN). @@ -120,39 +128,39 @@ class TimeCNNRegressor(BaseDeepRegressor): >>> X, y = make_example_3d_numpy(n_cases=10, n_channels=1, n_timepoints=12, ... return_y=True, regression_target=True, ... random_state=0) - >>> rgs = TimeCNNRegressor(n_epochs=20, bacth_size=4) # doctest: +SKIP + >>> rgs = TimeCNNRegressor(n_epochs=20, batch_size=4) # doctest: +SKIP >>> rgs.fit(X, y) # doctest: +SKIP TimeCNNRegressor(...) """ def __init__( self, - n_layers=2, - kernel_size=7, - n_filters=None, - avg_pool_size=3, - activation="sigmoid", - padding="valid", - strides=1, - dilation_rate=1, - n_epochs=2000, - batch_size=16, - callbacks=None, - file_path="./", - save_best_model=False, - save_last_model=False, - save_init_model=False, - best_file_name="best_model", - last_file_name="last_model", - init_file_name="init_model", - verbose=False, - loss="mean_squared_error", - output_activation="linear", - metrics="mean_squared_error", - random_state=None, - use_bias=True, - optimizer=None, - ): + n_layers: int = 2, + kernel_size: int | list[int] = 7, + n_filters: int | list[int] | None = None, + avg_pool_size: int | list[int] = 3, + activation: str | list[str] = "sigmoid", + padding: str | list[str] = "valid", + strides: int | list[int] = 1, + dilation_rate: int | list[int] = 1, + n_epochs: int = 2000, + batch_size: int = 16, + callbacks: Callback | list[Callback] | None = None, + file_path: str = "./", + save_best_model: bool = False, + save_last_model: bool = False, + save_init_model: bool = False, + best_file_name: str = "best_model", + last_file_name: str = "last_model", + init_file_name: str = "init_model", + verbose: bool = False, + loss: str = "mean_squared_error", + output_activation: str = "linear", + metrics: str | list[str] = "mean_squared_error", + random_state: int | np.random.RandomState | None = None, + use_bias: bool | list[bool] = True, + optimizer: tf.keras.optimizers.Optimizer | None = None, + ) -> None: self.n_layers = n_layers self.avg_pool_size = avg_pool_size self.padding = padding @@ -196,7 +204,9 @@ def __init__( use_bias=self.use_bias, ) - def build_model(self, input_shape, **kwargs): + def build_model( + self, input_shape: tuple[int, ...], **kwargs: Any + ) -> tf.keras.Model: """Construct a compiled, un-trained, keras model that is ready for training. In aeon, time series are stored in numpy arrays of shape (d,m), where d @@ -213,7 +223,6 @@ def build_model(self, input_shape, **kwargs): ------- output : a compiled Keras Model """ - import numpy as np import tensorflow as tf from tensorflow import keras @@ -239,7 +248,7 @@ def build_model(self, input_shape, **kwargs): ) return model - def _fit(self, X, y): + def _fit(self, X: np.ndarray, y: np.ndarray) -> TimeCNNRegressor: """Fit the regressor on the training set (X, y). Parameters @@ -316,7 +325,9 @@ def _fit(self, X, y): return self @classmethod - def _get_test_params(cls, parameter_set="default"): + def _get_test_params( + cls, parameter_set: str = "default" + ) -> dict[str, Any] | list[dict[str, Any]]: """Return testing parameter settings for the estimator. Parameters diff --git a/aeon/regression/deep_learning/_disjoint_cnn.py b/aeon/regression/deep_learning/_disjoint_cnn.py index cc2b0cb321..ac5e61d202 100644 --- a/aeon/regression/deep_learning/_disjoint_cnn.py +++ b/aeon/regression/deep_learning/_disjoint_cnn.py @@ -1,5 +1,7 @@ """DisjointCNN regressor.""" +from __future__ import annotations + __maintainer__ = ["hadifawaz1999"] __all__ = ["DisjointCNNRegressor"] @@ -7,12 +9,18 @@ import os import time from copy import deepcopy +from typing import TYPE_CHECKING, Any +import numpy as np from sklearn.utils import check_random_state from aeon.networks import DisjointCNNNetwork from aeon.regression.deep_learning.base import BaseDeepRegressor +if TYPE_CHECKING: + import tensorflow as tf + from tensorflow.keras.callbacks import Callback + class DisjointCNNRegressor(BaseDeepRegressor): """Disjoint Convolutional Neural Netowkr regressor. @@ -159,37 +167,37 @@ class DisjointCNNRegressor(BaseDeepRegressor): def __init__( self, - n_layers=4, - n_filters=64, - kernel_size=None, - dilation_rate=1, - strides=1, - padding="same", - activation="elu", - use_bias=True, - kernel_initializer="he_uniform", - pool_size=5, - pool_strides=None, - pool_padding="valid", - hidden_fc_units=128, - activation_fc="relu", - n_epochs=2000, - batch_size=16, - use_mini_batch_size=False, - random_state=None, - verbose=False, - output_activation="linear", - loss="mean_squared_error", - metrics="mean_squared_error", - optimizer=None, - file_path="./", - save_best_model=False, - save_last_model=False, - save_init_model=False, - best_file_name="best_model", - last_file_name="last_model", - init_file_name="init_model", - callbacks=None, + n_layers: int = 4, + n_filters: int | list[int] = 64, + kernel_size: int | list[int] | None = None, + dilation_rate: int | list[int] = 1, + strides: int | list[int] = 1, + padding: str | list[str] = "same", + activation: str | list[str] = "elu", + use_bias: bool | list[bool] = True, + kernel_initializer: str | list[str] = "he_uniform", + pool_size: int = 5, + pool_strides: int | None = None, + pool_padding: str = "valid", + hidden_fc_units: int = 128, + activation_fc: str = "relu", + n_epochs: int = 2000, + batch_size: int = 16, + use_mini_batch_size: bool = False, + random_state: int | np.random.RandomState | None = None, + verbose: bool = False, + output_activation: str = "linear", + loss: str = "mean_squared_error", + metrics: str | list[str] = "mean_squared_error", + optimizer: tf.keras.optimizers.Optimizer | None = None, + file_path: str = "./", + save_best_model: bool = False, + save_last_model: bool = False, + save_init_model: bool = False, + best_file_name: str = "best_model", + last_file_name: str = "last_model", + init_file_name: str = "init_model", + callbacks: Callback | list[Callback] | None = None, ): self.n_layers = n_layers self.n_filters = n_filters @@ -247,7 +255,9 @@ def __init__( activation_fc=self.activation_fc, ) - def build_model(self, input_shape, **kwargs): + def build_model( + self, input_shape: tuple[int, ...], **kwargs: Any + ) -> tf.keras.Model: """Construct a compiled, un-trained, keras model that is ready for training. In aeon, time series are stored in numpy arrays of shape (d,m), where d @@ -266,7 +276,6 @@ def build_model(self, input_shape, **kwargs): ------- output : a compiled Keras Model """ - import numpy as np import tensorflow as tf rng = check_random_state(self.random_state) @@ -291,7 +300,7 @@ def build_model(self, input_shape, **kwargs): return model - def _fit(self, X, y): + def _fit(self, X: np.ndarray, y: np.ndarray) -> DisjointCNNRegressor: """Fit the regressor on the training set (X, y). Parameters @@ -376,7 +385,9 @@ def _fit(self, X, y): return self @classmethod - def _get_test_params(cls, parameter_set="default"): + def _get_test_params( + cls, parameter_set: str = "default" + ) -> dict[str, Any] | list[dict[str, Any]]: """Return testing parameter settings for the estimator. Parameters diff --git a/aeon/regression/deep_learning/_encoder.py b/aeon/regression/deep_learning/_encoder.py index fd3bf855cb..7388ce0928 100644 --- a/aeon/regression/deep_learning/_encoder.py +++ b/aeon/regression/deep_learning/_encoder.py @@ -1,18 +1,27 @@ """Encoder Regressor.""" +from __future__ import annotations + __author__ = ["AnonymousCodes911", "hadifawaz1999"] __all__ = ["EncoderRegressor"] + import gc import os import time from copy import deepcopy +from typing import TYPE_CHECKING, Any +import numpy as np from sklearn.utils import check_random_state from aeon.networks import EncoderNetwork from aeon.regression.deep_learning.base import BaseDeepRegressor +if TYPE_CHECKING: + import tensorflow as tf + from tensorflow.keras.callbacks import Callback + class EncoderRegressor(BaseDeepRegressor): """ @@ -111,31 +120,31 @@ class EncoderRegressor(BaseDeepRegressor): def __init__( self, - n_epochs=100, - batch_size=12, - kernel_size=None, - n_filters=None, - dropout_proba=0.2, - activation="sigmoid", - output_activation="linear", - max_pool_size=2, - padding="same", - strides=1, - fc_units=256, - callbacks=None, - file_path="./", - save_best_model=False, - save_last_model=False, - save_init_model=False, - best_file_name="best_model", - last_file_name="last_model", - init_file_name="init_model", - verbose=False, - loss="mean_squared_error", - metrics="mean_squared_error", - use_bias=True, - optimizer=None, - random_state=None, + n_epochs: int = 100, + batch_size: int = 12, + kernel_size: list[int] | None = None, + n_filters: list[int] | None = None, + dropout_proba: float = 0.2, + activation: str = "sigmoid", + output_activation: str = "linear", + max_pool_size: int = 2, + padding: str = "same", + strides: int = 1, + fc_units: int = 256, + callbacks: Callback | list[Callback] | None = None, + file_path: str = "./", + save_best_model: bool = False, + save_last_model: bool = False, + save_init_model: bool = False, + best_file_name: str = "best_model", + last_file_name: str = "last_model", + init_file_name: str = "init_model", + verbose: bool = False, + loss: str = "mean_squared_error", + metrics: str | list[str] = "mean_squared_error", + use_bias: bool = True, + optimizer: tf.keras.optimizers.Optimizer | None = None, + random_state: int | np.random.RandomState | None = None, ): self.n_filters = n_filters self.max_pool_size = max_pool_size @@ -179,7 +188,9 @@ def __init__( activation=self.activation, ) - def build_model(self, input_shape, **kwargs): + def build_model( + self, input_shape: tuple[int, ...], **kwargs: Any + ) -> tf.keras.Model: """Construct a compiled, un-trained, keras model that is ready for training. In aeon, time series are stored in numpy arrays of shape (d, m), where d @@ -195,7 +206,6 @@ def build_model(self, input_shape, **kwargs): ------- output : a compiled Keras Model """ - import numpy as np import tensorflow as tf rng = check_random_state(self.random_state) @@ -222,7 +232,7 @@ def build_model(self, input_shape, **kwargs): return model - def _fit(self, X, y): + def _fit(self, X: np.ndarray, y: np.ndarray) -> EncoderRegressor: """Fit the classifier on the training set (X, y). Parameters @@ -299,7 +309,9 @@ def _fit(self, X, y): return self @classmethod - def _get_test_params(cls, parameter_set="default"): + def _get_test_params( + cls, parameter_set: str = "default" + ) -> dict[str, Any] | list[dict[str, Any]]: """Return testing parameter settings for the estimator. Parameters diff --git a/aeon/regression/deep_learning/_fcn.py b/aeon/regression/deep_learning/_fcn.py index a6905580ac..082b8a7038 100644 --- a/aeon/regression/deep_learning/_fcn.py +++ b/aeon/regression/deep_learning/_fcn.py @@ -1,5 +1,7 @@ """Fully Convolutional Network (FCN) regressor.""" +from __future__ import annotations + __maintainer__ = ["hadifawaz1999"] __all__ = ["FCNRegressor"] @@ -7,12 +9,18 @@ import os import time from copy import deepcopy +from typing import TYPE_CHECKING, Any +import numpy as np from sklearn.utils import check_random_state from aeon.networks import FCNNetwork from aeon.regression.deep_learning.base import BaseDeepRegressor +if TYPE_CHECKING: + import tensorflow as tf + from tensorflow.keras.callbacks import Callback + class FCNRegressor(BaseDeepRegressor): """Fully Convolutional Network (FCN). @@ -117,32 +125,32 @@ class FCNRegressor(BaseDeepRegressor): def __init__( self, - n_layers=3, - n_filters=None, - kernel_size=None, - dilation_rate=1, - strides=1, - padding="same", - activation="relu", - file_path="./", - save_best_model=False, - save_last_model=False, - save_init_model=False, - best_file_name="best_model", - last_file_name="last_model", - init_file_name="init_model", - n_epochs=2000, - batch_size=16, - use_mini_batch_size=False, - callbacks=None, - verbose=False, - output_activation="linear", - loss="mean_squared_error", - metrics="mean_squared_error", - random_state=None, - use_bias=True, - optimizer=None, - ): + n_layers: int = 3, + n_filters: int | list[int] | None = None, + kernel_size: int | list[int] | None = None, + dilation_rate: int | list[int] = 1, + strides: int | list[int] = 1, + padding: str | list[str] = "same", + activation: str | list[str] = "relu", + file_path: str = "./", + save_best_model: bool = False, + save_last_model: bool = False, + save_init_model: bool = False, + best_file_name: str = "best_model", + last_file_name: str = "last_model", + init_file_name: str = "init_model", + n_epochs: int = 2000, + batch_size: int = 16, + use_mini_batch_size: bool = False, + callbacks: Callback | list[Callback] | None = None, + verbose: bool = False, + output_activation: str = "linear", + loss: str = "mean_squared_error", + metrics: str | list[str] = "mean_squared_error", + random_state: int | np.random.RandomState | None = None, + use_bias: bool = True, + optimizer: tf.keras.optimizers.Optimizer | None = None, + ) -> None: self.n_layers = n_layers self.kernel_size = kernel_size self.n_filters = n_filters @@ -182,7 +190,9 @@ def __init__( use_bias=self.use_bias, ) - def build_model(self, input_shape, **kwargs): + def build_model( + self, input_shape: tuple[int, ...], **kwargs: Any + ) -> tf.keras.Model: """Construct a compiled, un-trained, keras model that is ready for training. In aeon, time series are stored in numpy arrays of shape (d,m), where d @@ -199,7 +209,6 @@ def build_model(self, input_shape, **kwargs): ------- output : a compiled Keras Model """ - import numpy as np import tensorflow as tf rng = check_random_state(self.random_state) @@ -225,7 +234,7 @@ def build_model(self, input_shape, **kwargs): return model - def _fit(self, X, y): + def _fit(self, X: np.ndarray, y: np.ndarray) -> FCNRegressor: """Fit the regressor on the training set (X, y). Parameters @@ -310,7 +319,9 @@ def _fit(self, X, y): return self @classmethod - def _get_test_params(cls, parameter_set="default"): + def _get_test_params( + cls, parameter_set: str = "default" + ) -> dict[str, Any] | list[dict[str, Any]]: """Return testing parameter settings for the estimator. Parameters diff --git a/aeon/regression/deep_learning/_inception_time.py b/aeon/regression/deep_learning/_inception_time.py index 96e8a38362..e0d46f8089 100644 --- a/aeon/regression/deep_learning/_inception_time.py +++ b/aeon/regression/deep_learning/_inception_time.py @@ -1,5 +1,7 @@ """InceptionTime and Inception regressors.""" +from __future__ import annotations + __maintainer__ = ["hadifawaz1999"] __all__ = ["InceptionTimeRegressor"] @@ -7,6 +9,7 @@ import os import time from copy import deepcopy +from typing import TYPE_CHECKING, Any import numpy as np from sklearn.utils import check_random_state @@ -15,6 +18,10 @@ from aeon.regression.base import BaseRegressor from aeon.regression.deep_learning.base import BaseDeepRegressor +if TYPE_CHECKING: + import tensorflow as tf + from tensorflow.keras.callbacks import Callback + class InceptionTimeRegressor(BaseRegressor): """InceptionTime ensemble regressor. @@ -179,39 +186,39 @@ class InceptionTimeRegressor(BaseRegressor): def __init__( self, - n_regressors=5, - n_filters=32, - n_conv_per_layer=3, - kernel_size=40, - use_max_pooling=True, - max_pool_size=3, - strides=1, - dilation_rate=1, - padding="same", - activation="relu", - use_bias=False, - use_residual=True, - use_bottleneck=True, - bottleneck_size=32, - depth=6, - use_custom_filters=False, - output_activation="linear", - file_path="./", - save_last_model=False, - save_best_model=False, - save_init_model=False, - best_file_name="best_model", - last_file_name="last_model", - init_file_name="init_model", - batch_size=64, - use_mini_batch_size=False, - n_epochs=1500, - callbacks=None, - random_state=None, - verbose=False, - loss="mean_squared_error", - metrics="mean_squared_error", - optimizer=None, + n_regressors: int = 5, + n_filters: int | list[int] = 32, + n_conv_per_layer: int | list[int] = 3, + kernel_size: int | list[int] = 40, + use_max_pooling: bool | list[bool] = True, + max_pool_size: int | list[int] = 3, + strides: int | list[int] = 1, + dilation_rate: int | list[int] = 1, + padding: str | list[str] = "same", + activation: str | list[str] = "relu", + use_bias: bool | list[bool] = False, + use_residual: bool = True, + use_bottleneck: bool = True, + bottleneck_size: int = 32, + depth: int = 6, + use_custom_filters: bool = False, + output_activation: str = "linear", + file_path: str = "./", + save_last_model: bool = False, + save_best_model: bool = False, + save_init_model: bool = False, + best_file_name: str = "best_model", + last_file_name: str = "last_model", + init_file_name: str = "init_model", + batch_size: int = 64, + use_mini_batch_size: bool = False, + n_epochs: int = 1500, + callbacks: Callback | list[Callback] | None = None, + random_state: int | np.random.RandomState | None = None, + verbose: bool = False, + loss: str = "mean_squared_error", + metrics: str | list[str] = "mean_squared_error", + optimizer: tf.keras.optimizers.Optimizer | None = None, ): self.n_regressors = n_regressors @@ -251,11 +258,11 @@ def __init__( self.metrics = metrics self.optimizer = optimizer - self.regressors_ = [] + self.regressors_: list[IndividualInceptionRegressor] = [] super().__init__() - def _fit(self, X, y): + def _fit(self, X: np.ndarray, y: np.ndarray) -> InceptionTimeRegressor: """Fit each of the Individual Inception models. Parameters @@ -313,7 +320,7 @@ def _fit(self, X, y): return self - def _predict(self, X) -> np.ndarray: + def _predict(self, X: np.ndarray) -> np.ndarray: """Predict the values of the test set using InceptionTime. Parameters @@ -337,7 +344,9 @@ def _predict(self, X) -> np.ndarray: return ypreds @classmethod - def _get_test_params(cls, parameter_set="default"): + def _get_test_params( + cls, parameter_set: str = "default" + ) -> dict[str, Any] | list[dict[str, Any]]: """Return testing parameter settings for the estimator. Parameters @@ -507,38 +516,38 @@ class IndividualInceptionRegressor(BaseDeepRegressor): def __init__( self, - n_filters=32, - n_conv_per_layer=3, - kernel_size=40, - use_max_pooling=True, - max_pool_size=3, - strides=1, - dilation_rate=1, - padding="same", - activation="relu", - use_bias=False, - use_residual=True, - use_bottleneck=True, - bottleneck_size=32, - depth=6, - use_custom_filters=False, - output_activation="linear", - file_path="./", - save_best_model=False, - save_last_model=False, - save_init_model=False, - best_file_name="best_model", - last_file_name="last_model", - init_file_name="init_model", - batch_size=64, - use_mini_batch_size=False, - n_epochs=1500, - callbacks=None, - random_state=None, - verbose=False, - loss="mean_squared_error", - metrics="mean_squared_error", - optimizer=None, + n_filters: int | list[int] = 32, + n_conv_per_layer: int | list[int] = 3, + kernel_size: int | list[int] = 40, + use_max_pooling: bool | list[bool] = True, + max_pool_size: int | list[int] = 3, + strides: int | list[int] = 1, + dilation_rate: int | list[int] = 1, + padding: str | list[str] = "same", + activation: str | list[str] = "relu", + use_bias: bool | list[bool] = False, + use_residual: bool = True, + use_bottleneck: bool = True, + bottleneck_size: int = 32, + depth: int = 6, + use_custom_filters: bool = False, + output_activation: str = "linear", + file_path: str = "./", + save_best_model: bool = False, + save_last_model: bool = False, + save_init_model: bool = False, + best_file_name: str = "best_model", + last_file_name: str = "last_model", + init_file_name: str = "init_model", + batch_size: int = 64, + use_mini_batch_size: bool = False, + n_epochs: int = 1500, + callbacks: Callback | list[Callback] | None = None, + random_state: int | np.random.RandomState | None = None, + verbose: bool = False, + loss: str = "mean_squared_error", + metrics: str | list[str] = "mean_squared_error", + optimizer: tf.keras.optimizers.Optimizer | None = None, ): # predefined self.n_filters = n_filters @@ -595,7 +604,9 @@ def __init__( use_custom_filters=self.use_custom_filters, ) - def build_model(self, input_shape, **kwargs): + def build_model( + self, input_shape: tuple[int, ...], **kwargs: Any + ) -> tf.keras.Model: """ Construct a compiled, un-trained, keras model that is ready for training. @@ -609,7 +620,6 @@ def build_model(self, input_shape, **kwargs): tf.keras.models.Model A compiled Keras Model """ - import numpy as np import tensorflow as tf rng = check_random_state(self.random_state) @@ -631,7 +641,7 @@ def build_model(self, input_shape, **kwargs): return model - def _fit(self, X, y): + def _fit(self, X: np.ndarray, y: np.ndarray) -> IndividualInceptionRegressor: """ Fit the regressor on the training set (X, y). @@ -721,7 +731,9 @@ def _fit(self, X, y): return self @classmethod - def _get_test_params(cls, parameter_set="default"): + def _get_test_params( + cls, parameter_set: str = "default" + ) -> dict[str, Any] | list[dict[str, Any]]: """Return testing parameter settings for the estimator. Parameters diff --git a/aeon/regression/deep_learning/_lite_time.py b/aeon/regression/deep_learning/_lite_time.py index 9af8bbaf4e..d21a0b391b 100644 --- a/aeon/regression/deep_learning/_lite_time.py +++ b/aeon/regression/deep_learning/_lite_time.py @@ -1,5 +1,7 @@ """LITETime and LITE regressors.""" +from __future__ import annotations + __author__ = ["aadya940", "hadifawaz1999"] __all__ = ["IndividualLITERegressor", "LITETimeRegressor"] @@ -7,6 +9,7 @@ import os import time from copy import deepcopy +from typing import TYPE_CHECKING, Any import numpy as np from sklearn.utils import check_random_state @@ -14,6 +17,10 @@ from aeon.networks import LITENetwork from aeon.regression.deep_learning.base import BaseDeepRegressor, BaseRegressor +if TYPE_CHECKING: + import tensorflow as tf + from tensorflow.keras.callbacks import Callback + class LITETimeRegressor(BaseRegressor): """LITETime or LITEMVTime ensemble Regressor. @@ -137,29 +144,29 @@ class LITETimeRegressor(BaseRegressor): def __init__( self, - n_regressors=5, - use_litemv=False, - n_filters=32, - kernel_size=40, - strides=1, - activation="relu", - output_activation="linear", - file_path="./", - save_last_model=False, - save_best_model=False, - save_init_model=False, - best_file_name="best_model", - last_file_name="last_model", - init_file_name="init_model", - batch_size=64, - use_mini_batch_size=False, - n_epochs=1500, - callbacks=None, - random_state=None, - verbose=False, - loss="mean_squared_error", - metrics="mean_squared_error", - optimizer=None, + n_regressors: int = 5, + use_litemv: bool = False, + n_filters: int = 32, + kernel_size: int = 40, + strides: int | list[int] = 1, + activation: str | list[str] = "relu", + output_activation: str = "linear", + file_path: str = "./", + save_last_model: bool = False, + save_best_model: bool = False, + save_init_model: bool = False, + best_file_name: str = "best_model", + last_file_name: str = "last_model", + init_file_name: str = "init_model", + batch_size: int = 64, + use_mini_batch_size: bool = False, + n_epochs: int = 1500, + callbacks: Callback | list[Callback] | None = None, + random_state: int | np.random.RandomState | None = None, + verbose: bool = False, + loss: str = "mean_squared_error", + metrics: str | list[str] = "mean_squared_error", + optimizer: tf.keras.optimizers.Optimizer | None = None, ): self.n_regressors = n_regressors @@ -191,11 +198,11 @@ def __init__( self.metrics = metrics self.optimizer = optimizer - self.regressors_ = [] + self.regressors_: list[IndividualLITERegressor] = [] super().__init__() - def _fit(self, X, y): + def _fit(self, X: np.ndarray, y: np.ndarray) -> LITETimeRegressor: """Fit the ensemble of IndividualLITERegressor models. Parameters @@ -240,7 +247,7 @@ def _fit(self, X, y): return self - def _predict(self, X) -> np.ndarray: + def _predict(self, X: np.ndarray) -> np.ndarray: """Predict the values of the test set using LITETime. Parameters @@ -263,7 +270,7 @@ def _predict(self, X) -> np.ndarray: return vals @classmethod - def _get_test_params(cls, parameter_set="default"): + def _get_test_params(cls, parameter_set: str = "default") -> dict | list[dict]: """Return testing parameter settings for the estimator. Parameters @@ -413,28 +420,28 @@ class IndividualLITERegressor(BaseDeepRegressor): def __init__( self, - use_litemv=False, - n_filters=32, - kernel_size=40, - strides=1, - activation="relu", - output_activation="linear", - file_path="./", - save_best_model=False, - save_last_model=False, - save_init_model=False, - best_file_name="best_model", - last_file_name="last_model", - init_file_name="init_model", - batch_size=64, - use_mini_batch_size=False, - n_epochs=1500, - callbacks=None, - random_state=None, - verbose=False, - loss="mean_squared_error", - metrics="mean_squared_error", - optimizer=None, + use_litemv: bool = False, + n_filters: int = 32, + kernel_size: int = 40, + strides: int | list[int] = 1, + activation: str | list[str] = "relu", + output_activation: str = "linear", + file_path: str = "./", + save_best_model: bool = False, + save_last_model: bool = False, + save_init_model: bool = False, + best_file_name: str = "best_model", + last_file_name: str = "last_model", + init_file_name: str = "init_model", + batch_size: int = 64, + use_mini_batch_size: bool = False, + n_epochs: int = 1500, + callbacks: Callback | list[Callback] | None = None, + random_state: int | np.random.RandomState | None = None, + verbose: bool = False, + loss: str = "mean_squared_error", + metrics: str | list[str] = "mean_squared_error", + optimizer: tf.keras.optimizers.Optimizer | None = None, ): self.use_litemv = use_litemv self.n_filters = n_filters @@ -474,7 +481,9 @@ def __init__( activation=self.activation, ) - def build_model(self, input_shape, **kwargs): + def build_model( + self, input_shape: tuple[int, ...], **kwargs: Any + ) -> tf.keras.Model: """ Construct a compiled, un-trained, keras model that is ready for training. @@ -487,7 +496,6 @@ def build_model(self, input_shape, **kwargs): ------- output : a compiled Keras Model """ - import numpy as np import tensorflow as tf rng = check_random_state(self.random_state) @@ -513,7 +521,7 @@ def build_model(self, input_shape, **kwargs): return model - def _fit(self, X, y): + def _fit(self, X: np.ndarray, y: np.ndarray) -> IndividualLITERegressor: """ Fit the Regressor on the training set (X, y). @@ -602,7 +610,7 @@ def _fit(self, X, y): return self @classmethod - def _get_test_params(cls, parameter_set="default"): + def _get_test_params(cls, parameter_set: str = "default") -> dict | list[dict]: """Return testing parameter settings for the estimator. Parameters diff --git a/aeon/regression/deep_learning/_mlp.py b/aeon/regression/deep_learning/_mlp.py index 7de083e72f..fe1b28754f 100644 --- a/aeon/regression/deep_learning/_mlp.py +++ b/aeon/regression/deep_learning/_mlp.py @@ -1,5 +1,7 @@ """Multi Layer Perceptron Network (MLP) regressor.""" +from __future__ import annotations + __author__ = ["Aadya-Chinubhai", "hadifawaz1999"] __all__ = ["MLPRegressor"] @@ -7,12 +9,18 @@ import os import time from copy import deepcopy +from typing import TYPE_CHECKING, Any +import numpy as np from sklearn.utils import check_random_state from aeon.networks import MLPNetwork from aeon.regression.deep_learning.base import BaseDeepRegressor +if TYPE_CHECKING: + import tensorflow as tf + from tensorflow.keras.callbacks import Callback + class MLPRegressor(BaseDeepRegressor): """Multi Layer Perceptron Network (MLP). @@ -108,28 +116,28 @@ class MLPRegressor(BaseDeepRegressor): def __init__( self, - n_layers=3, - n_units=500, - activation="relu", - dropout_rate=None, - dropout_last=None, - use_bias=True, - n_epochs=2000, - batch_size=16, - callbacks=None, - verbose=False, - loss="mean_squared_error", - metrics="mean_squared_error", - file_path="./", - save_best_model=False, - save_last_model=False, - save_init_model=False, - best_file_name="best_model", - last_file_name="last_model", - init_file_name="init_model", - random_state=None, - output_activation="linear", - optimizer=None, + n_layers: int = 3, + n_units: int | list[int] = 500, + activation: str | list[str] = "relu", + dropout_rate: float | list[float] | None = None, + dropout_last: float = 0.3, + use_bias: bool = True, + n_epochs: int = 2000, + batch_size: int = 16, + callbacks: Callback | list[Callback] | None = None, + verbose: bool = False, + loss: str = "mean_squared_error", + metrics: str | list[str] = "mean_squared_error", + file_path: str = "./", + save_best_model: bool = False, + save_last_model: bool = False, + save_init_model: bool = False, + best_file_name: str = "best_model", + last_file_name: str = "last_model", + init_file_name: str = "init_model", + random_state: int | np.random.RandomState | None = None, + output_activation: str = "linear", + optimizer: tf.keras.optimizers.Optimizer | None = None, ): self.n_layers = n_layers self.n_units = n_units @@ -168,7 +176,9 @@ def __init__( use_bias=self.use_bias, ) - def build_model(self, input_shape, **kwargs): + def build_model( + self, input_shape: tuple[int, ...], **kwargs: Any + ) -> tf.keras.Model: """Construct a compiled, un-trained, keras model that is ready for training. In aeon, time series are stored in numpy arrays of shape (d,m), where d @@ -185,7 +195,6 @@ def build_model(self, input_shape, **kwargs): ------- output : a compiled Keras Model """ - import numpy as np import tensorflow as tf from tensorflow import keras @@ -211,7 +220,7 @@ def build_model(self, input_shape, **kwargs): ) return model - def _fit(self, X, y): + def _fit(self, X: np.ndarray, y: np.ndarray) -> MLPRegressor: """Fit the Regressor on the training set (X, y). Parameters @@ -292,7 +301,9 @@ def _fit(self, X, y): return self @classmethod - def _get_test_params(cls, parameter_set="default"): + def _get_test_params( + cls, parameter_set: str = "default" + ) -> dict[str, Any] | list[dict[str, Any]]: """Return testing parameter settings for the estimator. Parameters diff --git a/aeon/regression/deep_learning/_resnet.py b/aeon/regression/deep_learning/_resnet.py index 7f89a18ade..e123427517 100644 --- a/aeon/regression/deep_learning/_resnet.py +++ b/aeon/regression/deep_learning/_resnet.py @@ -1,5 +1,7 @@ """Residual Network (ResNet) regressor.""" +from __future__ import annotations + __maintainer__ = ["hadifawaz1999"] __all__ = ["ResNetRegressor"] @@ -7,12 +9,18 @@ import os import time from copy import deepcopy +from typing import TYPE_CHECKING, Any +import numpy as np from sklearn.utils import check_random_state from aeon.networks import ResNetNetwork from aeon.regression.deep_learning.base import BaseDeepRegressor +if TYPE_CHECKING: + import tensorflow as tf + from tensorflow.keras.callbacks import Callback + class ResNetRegressor(BaseDeepRegressor): """ @@ -126,39 +134,39 @@ class ResNetRegressor(BaseDeepRegressor): >>> X, y = make_example_3d_numpy(n_cases=10, n_channels=1, n_timepoints=12, ... return_y=True, regression_target=True, ... random_state=0) - >>> rgs = ResNetRegressor(n_epochs=20, bacth_size=4) # doctest: +SKIP + >>> rgs = ResNetRegressor(n_epochs=20, batch_size=4) # doctest: +SKIP >>> rgs.fit(X, y) # doctest: +SKIP ResNetRegressor(...) """ def __init__( self, - n_residual_blocks=3, - n_conv_per_residual_block=3, - n_filters=None, - kernel_size=None, - strides=1, - dilation_rate=1, - padding="same", - activation="relu", - use_bias=True, - n_epochs=1500, - callbacks=None, - verbose=False, - loss="mean_squared_error", - output_activation="linear", - metrics="mean_squared_error", - batch_size=64, - use_mini_batch_size=False, - random_state=None, - file_path="./", - save_best_model=False, - save_last_model=False, - save_init_model=False, - best_file_name="best_model", - last_file_name="last_model", - init_file_name="init_model", - optimizer=None, + n_residual_blocks: int = 3, + n_conv_per_residual_block: int = 3, + n_filters: int | list[int] | None = None, + kernel_size: int | list[int] | None = None, + strides: int | list[int] = 1, + dilation_rate: int | list[int] = 1, + padding: str | list[str] = "same", + activation: str | list[str] = "relu", + use_bias: bool | list[bool] = True, + n_epochs: int = 1500, + callbacks: Callback | list[Callback] | None = None, + verbose: bool = False, + loss: str = "mean_squared_error", + output_activation: str = "linear", + metrics: str | list[str] = "mean_squared_error", + batch_size: int = 64, + use_mini_batch_size: bool = False, + random_state: int | np.random.RandomState | None = None, + file_path: str = "./", + save_best_model: bool = False, + save_last_model: bool = False, + save_init_model: bool = False, + best_file_name: str = "best_model", + last_file_name: str = "last_model", + init_file_name: str = "init_model", + optimizer: tf.keras.optimizers.Optimizer | None = None, ): self.n_residual_blocks = n_residual_blocks self.n_conv_per_residual_block = n_conv_per_residual_block @@ -201,7 +209,9 @@ def __init__( padding=self.padding, ) - def build_model(self, input_shape, **kwargs): + def build_model( + self, input_shape: tuple[int, ...], **kwargs: Any + ) -> tf.keras.Model: """Construct a compiled, un-trained, keras model that is ready for training. In aeon, time series are stored in numpy arrays of shape (d,m), where d @@ -218,7 +228,6 @@ def build_model(self, input_shape, **kwargs): ------- output : a compiled Keras Model """ - import numpy as np import tensorflow as tf self.optimizer_ = ( @@ -246,7 +255,7 @@ def build_model(self, input_shape, **kwargs): return model - def _fit(self, X, y): + def _fit(self, X: np.ndarray, y: np.ndarray) -> ResNetRegressor: """Fit the regressor on the training set (X, y). Parameters @@ -331,7 +340,9 @@ def _fit(self, X, y): return self @classmethod - def _get_test_params(cls, parameter_set="default"): + def _get_test_params( + cls, parameter_set: str = "default" + ) -> dict[str, Any] | list[dict[str, Any]]: """Return testing parameter settings for the estimator. Parameters diff --git a/aeon/regression/deep_learning/base.py b/aeon/regression/deep_learning/base.py index b48e3b2792..52b6f38c1d 100644 --- a/aeon/regression/deep_learning/base.py +++ b/aeon/regression/deep_learning/base.py @@ -5,15 +5,22 @@ because we can generalise tags and _predict """ +from __future__ import annotations + __maintainer__ = [] __all__ = ["BaseDeepRegressor"] from abc import abstractmethod +from typing import TYPE_CHECKING, Any import numpy as np from aeon.regression.base import BaseRegressor +if TYPE_CHECKING: + import tensorflow as tf + from tensorflow.keras.callbacks import Callback + class BaseDeepRegressor(BaseRegressor): """Abstract base class for deep learning time series regression. @@ -41,7 +48,7 @@ class BaseDeepRegressor(BaseRegressor): } @abstractmethod - def __init__(self, batch_size=40, last_file_name="last_model"): + def __init__(self, batch_size: int = 40, last_file_name: str = "last_model"): self.batch_size = batch_size self.last_file_name = last_file_name @@ -50,7 +57,7 @@ def __init__(self, batch_size=40, last_file_name="last_model"): super().__init__() @abstractmethod - def build_model(self, input_shape): + def build_model(self, input_shape: tuple[int, ...]) -> tf.keras.Model: """ Construct a compiled, un-trained, keras model that is ready for training. @@ -65,7 +72,7 @@ def build_model(self, input_shape): """ ... - def summary(self): + def summary(self) -> dict[str, Any] | None: """ Summary function to return the losses/metrics for model fit. @@ -77,7 +84,7 @@ def summary(self): """ return self.history.history if self.history is not None else None - def _predict(self, X): + def _predict(self, X: np.ndarray) -> np.ndarray: """ Find regression estimate for all cases in X. @@ -96,7 +103,7 @@ def _predict(self, X): y_pred = np.squeeze(y_pred, axis=-1) return y_pred - def save_last_model_to_file(self, file_path="./"): + def save_last_model_to_file(self, file_path: str = "./") -> None: """Save the last epoch of the trained deep learning model. Parameters @@ -110,7 +117,7 @@ def save_last_model_to_file(self, file_path="./"): """ self.model_.save(file_path + self.last_file_name + ".keras") - def load_model(self, model_path): + def load_model(self, model_path: str) -> None: """Load a pre-trained keras model instead of fitting. When calling this function, all functionalities can be used @@ -132,7 +139,9 @@ def load_model(self, model_path): self.model_ = tf.keras.models.load_model(model_path) self.is_fitted = True - def _get_model_checkpoint_callback(self, callbacks, file_path, file_name): + def _get_model_checkpoint_callback( + self, callbacks: Callback | list[Callback], file_path: str, file_name: str + ) -> list[Callback]: import tensorflow as tf model_checkpoint_ = tf.keras.callbacks.ModelCheckpoint(