diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index eb5788ce..d0e66672 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -14,7 +14,7 @@ jobs: - name: Python uses: actions/setup-python@v2 with: - python-version: 3.8 + python-version: '3.10' - name: Build run: | diff --git a/.github/workflows/latest-dependencies.yml b/.github/workflows/latest-dependencies.yml index c0418a9f..9f241c8c 100644 --- a/.github/workflows/latest-dependencies.yml +++ b/.github/workflows/latest-dependencies.yml @@ -8,10 +8,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v2 with: - python-version: 3.8 + python-version: '3.10' - name: Install package run: | pip install --upgrade pip diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9fe6deca..cc20edee 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: [3.8] + python-version: ['3.10'] os: [ubuntu-latest, macos-latest, windows-latest] steps: - uses: actions/checkout@v1 @@ -32,7 +32,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12'] os: [ubuntu-latest] steps: - uses: actions/checkout@v1 @@ -50,7 +50,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12'] os: [ubuntu-latest, macos-latest] steps: - uses: actions/checkout@v1 @@ -68,7 +68,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12'] os: [ubuntu-latest, macos-latest, windows-latest] steps: - uses: actions/checkout@v1 @@ -105,8 +105,8 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: ['3.8'] - os: [macos-13] + python-version: ['3.9'] + os: [ubuntu-latest, macos-latest] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} @@ -115,7 +115,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install package and dependencies run: | - python -m pip install --upgrade pip + python -m pip install --upgrade 'pip<=24.1' python -m pip install invoke .[test] - name: invoke minimum run: invoke minimum @@ -125,7 +125,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12'] os: [ubuntu-latest, macos-latest, windows-latest] exclude: - os: windows-latest diff --git a/README.md b/README.md index cad59efa..a3a5454a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@

[![Development Status](https://img.shields.io/badge/Development%20Status-2%20--%20Pre--Alpha-yellow)](https://pypi.org/search/?c=Development+Status+%3A%3A+2+-+Pre-Alpha) -[![Python](https://img.shields.io/badge/Python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11-blue)](https://badge.fury.io/py/orion-ml) +[![Python](https://img.shields.io/badge/Python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12-blue)](https://badge.fury.io/py/orion-ml) [![PyPi Shield](https://img.shields.io/pypi/v/orion-ml.svg)](https://pypi.python.org/pypi/orion-ml) [![Tests](https://github.com/sintel-dev/Orion/workflows/Run%20Tests/badge.svg)](https://github.com/sintel-dev/Orion/actions?query=workflow%3A%22Run+Tests%22+branch%3Amaster) [![Downloads](https://pepy.tech/badge/orion-ml)](https://pepy.tech/project/orion-ml) diff --git a/docs/conf.py b/docs/conf.py index 480f087f..365759de 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -31,7 +31,6 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ - 'm2r2', 'nbsphinx', 'sphinx.ext.autodoc', 'sphinx.ext.autosummary', @@ -96,7 +95,7 @@ # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = 'en' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. diff --git a/docs/user_guides/primitives_pipelines/primitives/DenseSeq2Seq.rst b/docs/user_guides/primitives_pipelines/primitives/DenseSeq2Seq.rst index ee7be16d..0aeb6f88 100644 --- a/docs/user_guides/primitives_pipelines/primitives/DenseSeq2Seq.rst +++ b/docs/user_guides/primitives_pipelines/primitives/DenseSeq2Seq.rst @@ -29,7 +29,7 @@ argument type description ``input_shape`` ``tuple`` tuple denoting the shape of an input sample ``target_shape`` ``tuple`` tuple denoting the shape of an output sample ``optimizer`` ``str`` string (name of optimizer) or optimizer instance. Default is ``keras.optimizers.Adam`` - ``loss`` ``str`` string (name of the objective function) or an objective function instance. Default is ``keras.losses.mean_squared_error`` + ``loss`` ``str`` string (name of the objective function) or an objective function instance. Default is ``tensorflow.losses.mse`` ``metrics`` ``list`` list of metrics to be evaluated by the model during training and testing. Default is ["mse"] ``return_seqeunces`` ``bool`` whether to return the last output in the output sequence, or the full sequence. Default is False ``layers`` ``list`` list of keras layers which are the basic building blocks of a neural network diff --git a/docs/user_guides/primitives_pipelines/primitives/LSTMSeq2Seq.rst b/docs/user_guides/primitives_pipelines/primitives/LSTMSeq2Seq.rst index dd3c1516..37b965e5 100644 --- a/docs/user_guides/primitives_pipelines/primitives/LSTMSeq2Seq.rst +++ b/docs/user_guides/primitives_pipelines/primitives/LSTMSeq2Seq.rst @@ -29,7 +29,7 @@ argument type description ``input_shape`` ``tuple`` tuple denoting the shape of an input sample ``target_shape`` ``tuple`` tuple denoting the shape of an output sample ``optimizer`` ``str`` string (name of optimizer) or optimizer instance. Default is ``keras.optimizers.Adam`` - ``loss`` ``str`` string (name of the objective function) or an objective function instance. Default is ``keras.losses.mean_squared_error`` + ``loss`` ``str`` string (name of the objective function) or an objective function instance. Default is ``tensorflow.losses.mse`` ``metrics`` ``list`` list of metrics to be evaluated by the model during training and testing. Default is ["mse"] ``return_seqeunces`` ``bool`` whether to return the last output in the output sequence, or the full sequence. Default is False ``layers`` ``list`` list of keras layers which are the basic building blocks of a neural network diff --git a/docs/user_guides/primitives_pipelines/primitives/LSTMTimeSeriesRegressor.rst b/docs/user_guides/primitives_pipelines/primitives/LSTMTimeSeriesRegressor.rst index d5ca166f..c669a695 100644 --- a/docs/user_guides/primitives_pipelines/primitives/LSTMTimeSeriesRegressor.rst +++ b/docs/user_guides/primitives_pipelines/primitives/LSTMTimeSeriesRegressor.rst @@ -28,7 +28,7 @@ argument type description ``input_shape`` ``tuple`` tuple denoting the shape of an input sample ``dense_units`` ``int`` number of values ahead to predict (target size). Default is 1. ``optimizer`` ``str`` string (name of optimizer) or optimizer instance. Default is ``keras.optimizers.Adam`` - ``loss`` ``str`` string (name of the objective function) or an objective function instance. Default is ``keras.losses.mean_squared_error`` + ``loss`` ``str`` string (name of the objective function) or an objective function instance. Default is ``tensorflow.losses.mse`` ``metrics`` ``list`` list of metrics to be evaluated by the model during training and testing. Default is ["mse"] ``return_seqeunces`` ``bool`` whether to return the last output in the output sequence, or the full sequence. Default is False ``layers`` ``list`` list of keras layers which are the basic building blocks of a neural network @@ -53,7 +53,7 @@ argument type description X = np.array([1] * 100).reshape(1, -1, 1) y = np.array([[1]]) primitive = load_primitive('keras.Sequential.LSTMTimeSeriesRegressor', - arguments={"X": X, "y": y, "input_shape":(100, 1), "batch_size": 1, "validation_split": 0}) + arguments={"X": X, "y": y, "input_shape":(100, 1), "batch_size": 1, "validation_split": 0, "loss": "tensorflow.losses.mse"}) primitive.fit() primitive.produce(X=X) diff --git a/orion/__main__.py b/orion/__main__.py index fe026cbe..8bb13e4d 100644 --- a/orion/__main__.py +++ b/orion/__main__.py @@ -5,8 +5,6 @@ import logging import warnings -import tabulate - from orion.analysis import get_available_templates from orion.benchmark import benchmark from orion.evaluation import CONTEXTUAL_METRICS as METRICS @@ -27,13 +25,6 @@ def _evaluate(args): print('Writing results in {}'.format(args.output)) scores.to_csv(args.output, index=False) - print(tabulate.tabulate( - scores, - showindex=False, - tablefmt='github', - headers=scores.columns - )) - def get_parser(): diff --git a/orion/pipelines/verified/lstm_dynamic_threshold/lstm_dynamic_threshold.json b/orion/pipelines/verified/lstm_dynamic_threshold/lstm_dynamic_threshold.json index 4d87efd6..35e05b2c 100644 --- a/orion/pipelines/verified/lstm_dynamic_threshold/lstm_dynamic_threshold.json +++ b/orion/pipelines/verified/lstm_dynamic_threshold/lstm_dynamic_threshold.json @@ -25,7 +25,8 @@ "window_size": 250 }, "keras.Sequential.LSTMTimeSeriesRegressor": { - "epochs": 35 + "epochs": 35, + "loss": "tensorflow.losses.mse" }, "orion.primitives.timeseries_anomalies.find_anomalies#1": { "window_size_portion": 0.33, diff --git a/orion/primitives/adapters/ncps.py b/orion/primitives/adapters/ncps.py index 097f6224..037a2542 100644 --- a/orion/primitives/adapters/ncps.py +++ b/orion/primitives/adapters/ncps.py @@ -8,7 +8,7 @@ def build_layer(layer, hyperparameters): layer_class = import_object(layer['class']) layer_kwargs = layer['parameters'].copy() - if issubclass(layer_class, tf.keras.layers.Wrapper): + if issubclass(layer_class, tf.keras.layers.Layer) and 'layer' in layer_kwargs: layer_kwargs['layer'] = build_layer(layer_kwargs['layer'], hyperparameters) elif issubclass(layer_class, tf.keras.layers.RNN) and isinstance(layer_kwargs['units'], dict): layer_kwargs['units'] = build_layer(layer_kwargs['units'], hyperparameters) diff --git a/orion/primitives/aer.py b/orion/primitives/aer.py index 94e94735..f44b15ea 100644 --- a/orion/primitives/aer.py +++ b/orion/primitives/aer.py @@ -11,22 +11,11 @@ from tensorflow.keras.models import Model from orion.primitives.timeseries_errors import reconstruction_errors, regression_errors +from orion.primitives.utils import build_layer LOGGER = logging.getLogger(__name__) -def build_layer(layer: dict, hyperparameters: dict): - layer_class = import_object(layer['class']) - layer_kwargs = layer['parameters'].copy() - # TODO: Upgrade to using tf.keras.layers.Wrapper in mlprimitives. - if issubclass(layer_class, tf.keras.layers.Wrapper): - layer_kwargs['layer'] = build_layer(layer_kwargs['layer'], hyperparameters) - for key, value in layer_kwargs.items(): - if isinstance(value, str): - layer_kwargs[key] = hyperparameters.get(value, value) - return layer_class(**layer_kwargs) - - class AER(object): """Autoencoder with bi-directional regression for time series anomaly detection. diff --git a/orion/primitives/jsons/keras.Sequential.DenseSeq2Seq.json b/orion/primitives/jsons/keras.Sequential.DenseSeq2Seq.json index c84d8806..d46c109f 100644 --- a/orion/primitives/jsons/keras.Sequential.DenseSeq2Seq.json +++ b/orion/primitives/jsons/keras.Sequential.DenseSeq2Seq.json @@ -92,7 +92,7 @@ }, "loss": { "type": "str", - "default": "tensorflow.keras.losses.mean_squared_error" + "default": "tensorflow.losses.mse" }, "metrics": { "type": "list", diff --git a/orion/primitives/jsons/keras.Sequential.LSTMSeq2Seq.json b/orion/primitives/jsons/keras.Sequential.LSTMSeq2Seq.json index 31242807..6069d47b 100644 --- a/orion/primitives/jsons/keras.Sequential.LSTMSeq2Seq.json +++ b/orion/primitives/jsons/keras.Sequential.LSTMSeq2Seq.json @@ -92,7 +92,7 @@ }, "loss": { "type": "str", - "default": "tensorflow.keras.losses.mean_squared_error" + "default": "tensorflow.losses.mse" }, "metrics": { "type": "list", diff --git a/orion/primitives/jsons/keras.Sequential.LTCTimeSeriesRegressor.json b/orion/primitives/jsons/keras.Sequential.LTCTimeSeriesRegressor.json index e49bfc64..45964528 100644 --- a/orion/primitives/jsons/keras.Sequential.LTCTimeSeriesRegressor.json +++ b/orion/primitives/jsons/keras.Sequential.LTCTimeSeriesRegressor.json @@ -92,7 +92,7 @@ }, "loss": { "type": "str", - "default": "tensorflow.keras.losses.mean_squared_error" + "default": "tensorflow.losses.mse" }, "metrics": { "type": "list", @@ -149,7 +149,7 @@ } }, { - "class": "ncps.tf.LTC", + "class": "ncps.keras.LTC", "parameters": { "units": { "class": "ncps.wirings.AutoNCP", diff --git a/orion/primitives/tadgan.py b/orion/primitives/tadgan.py index 5f3d9d14..4ade0b34 100644 --- a/orion/primitives/tadgan.py +++ b/orion/primitives/tadgan.py @@ -14,6 +14,7 @@ from tensorflow.keras import Model from orion.primitives.timeseries_errors import reconstruction_errors +from orion.primitives.utils import build_layer LOGGER = logging.getLogger(__name__) tf.keras.backend.set_floatx('float64') @@ -25,20 +26,6 @@ ] -def build_layer(layer: dict, hyperparameters: dict): - layer_class = import_object(layer['class']) - layer_kwargs = layer['parameters'].copy() - # TODO: Upgrade to using tf.keras.layers.Wrapper in mlprimitives. - if issubclass(layer_class, tf.keras.layers.Wrapper): - layer_kwargs['layer'] = build_layer(layer_kwargs['layer'], hyperparameters) - - for key, value in layer_kwargs.items(): - if isinstance(value, str): - layer_kwargs[key] = hyperparameters.get(value, value) - - return layer_class(**layer_kwargs) - - class TadGAN: """TadGAN model for time series reconstruction. diff --git a/orion/primitives/timeseries_anomalies.py b/orion/primitives/timeseries_anomalies.py index 023b7039..f19b2373 100644 --- a/orion/primitives/timeseries_anomalies.py +++ b/orion/primitives/timeseries_anomalies.py @@ -193,7 +193,7 @@ def _find_sequences(errors, epsilon, anomaly_padding): for idx in index_above.flatten(): above[max(0, idx - anomaly_padding):min(idx + anomaly_padding + 1, len(above))] = True - shift = above.shift(1).fillna(False) + shift = above.shift(1).astype('boolean').fillna(False) change = above != shift if above.all(): diff --git a/orion/primitives/timeseries_errors.py b/orion/primitives/timeseries_errors.py index 4fde3863..715ca6a5 100644 --- a/orion/primitives/timeseries_errors.py +++ b/orion/primitives/timeseries_errors.py @@ -91,9 +91,9 @@ def _area_error(y, y_hat, score_window=10): An array of area error. """ smooth_y = pd.Series(y).rolling( - score_window, center=True, min_periods=score_window // 2).apply(integrate.trapz) + score_window, center=True, min_periods=score_window // 2).apply(integrate.trapezoid) smooth_y_hat = pd.Series(y_hat).rolling( - score_window, center=True, min_periods=score_window // 2).apply(integrate.trapz) + score_window, center=True, min_periods=score_window // 2).apply(integrate.trapezoid) errors = abs(smooth_y - smooth_y_hat) diff --git a/orion/primitives/utils.py b/orion/primitives/utils.py new file mode 100644 index 00000000..bc1db171 --- /dev/null +++ b/orion/primitives/utils.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- + +import tensorflow as tf +from mlstars.utils import import_object + + +def build_layer(layer: dict, hyperparameters: dict): + layer_class = import_object(layer['class']) + layer_kwargs = layer['parameters'].copy() + # TODO: tf.keras.layers.Wrapper deprecated, Bidirectional inheret from Layer + if issubclass(layer_class, tf.keras.layers.Layer) and 'layer' in layer_kwargs: + layer_kwargs['layer'] = build_layer(layer_kwargs['layer'], hyperparameters) + for key, value in layer_kwargs.items(): + if isinstance(value, str): + layer_kwargs[key] = hyperparameters.get(value, value) + return layer_class(**layer_kwargs) diff --git a/orion/primitives/vae.py b/orion/primitives/vae.py index 26334d63..eb99c4a4 100644 --- a/orion/primitives/vae.py +++ b/orion/primitives/vae.py @@ -16,19 +16,17 @@ from tensorflow.keras.layers import Input from tensorflow.keras.models import Model +from orion.primitives.utils import build_layer + LOGGER = logging.getLogger(__name__) -def build_layer(layer: dict, hyperparameters: dict): - layer_class = import_object(layer['class']) - layer_kwargs = layer['parameters'].copy() - # TODO: Upgrade to using tf.keras.layers.Wrapper in mlprimitives. - if issubclass(layer_class, tf.keras.layers.Wrapper): - layer_kwargs['layer'] = build_layer(layer_kwargs['layer'], hyperparameters) - for key, value in layer_kwargs.items(): - if isinstance(value, str): - layer_kwargs[key] = hyperparameters.get(value, value) - return layer_class(**layer_kwargs) +class KLDivergenceLoss(tf.keras.layers.Layer): + def call(self, inputs): + z_log_sigma, z_mean = inputs + kl_loss = -0.5 * K.mean(1 + z_log_sigma - K.square(z_mean) - K.exp(z_log_sigma), axis=-1) + self.add_loss(kl_loss) + return inputs class VAE(object): @@ -180,13 +178,13 @@ def _build_vae(self, **kwargs): h = self.encoder(x) z_mean = tf.keras.layers.Dense(self.latent_dim)(h) z_log_sigma = tf.keras.layers.Dense(self.latent_dim)(h) + KLDivergenceLoss()([z_log_sigma, z_mean]) # kl loss z = tf.keras.layers.Lambda(self._sampling)([z_mean, z_log_sigma]) y_ = self.generator(z) self.vae_model = Model([x, y], y_) - self.vae_model.add_loss(self._vae_loss(y, y_, z_log_sigma, z_mean)) - self.vae_model.compile(optimizer=self.optimizer) + self.vae_model.compile(loss='mse', optimizer=self.optimizer) def fit(self, X: np.ndarray, y: np.ndarray, **kwargs): """Fit the model. @@ -211,7 +209,7 @@ def fit(self, X: np.ndarray, y: np.ndarray, **kwargs): for callback in self.callbacks ] - self.fit_history = self.vae_model.fit((X, y), + self.fit_history = self.vae_model.fit((X, y), y, batch_size=self.batch_size, epochs=self.epochs, shuffle=self.shuffle, diff --git a/setup.py b/setup.py index 4bc268e1..50d0ad45 100644 --- a/setup.py +++ b/setup.py @@ -17,18 +17,16 @@ install_requires = [ - 'tensorflow>=2.2,<2.15', - 'numpy>=1.17.5,<2', - 'pandas>=1,<3', - 'numba>=0.48,<0.60', - 's3fs>=0.2.2,<0.5', - 'mlblocks>=0.6.2,<0.7', - 'ml-stars>=0.2.1.dev0,<0.4', - 'scikit-learn>=0.22.1,<2', - 'scipy<1.14', - 'tabulate>=0.8.3,<0.9', + 'tensorflow>=2.16.1,<2.20', + 'numpy>=1.23.5,<2', + 'pandas>=1.4.0,<3', + 'numba>=0.56.2,<0.70', + 'mlblocks>=0.6.2,<0.8', + 'ml-stars>=0.2.2,<0.4', + 'scikit-learn>=1.1.0,<1.6', + 'scipy>=1.8.0,<2', 'pyts>=0.11,<0.14', - 'torch>=1.4,<2.6', + 'torch>=1.12.0,<2.6', 'azure-cognitiveservices-anomalydetector>=0.3,<0.4', 'xlsxwriter>=1.3.6,<1.4', 'tqdm>=4.36.1', @@ -45,8 +43,8 @@ 'smart_open', #timesfm - "timesfm[torch]>=1.2.0,<1.5;python_version>='3.11'", - "jax;python_version>='3.11'", + "timesfm[torch]>=1.2.0,<1.5;python_version>='3.11' and python_version<'3.12'", + "jax;python_version>='3.11' and python_version<'3.12'", ] @@ -65,27 +63,19 @@ # general 'pip>=9.0.1', 'bumpversion>=0.5.3,<0.6', - 'watchdog>=0.8.3,<0.11', + 'watchdog>=0.8.3,<5', # docs - 'docutils>=0.12,<0.18', - 'm2r2>=0.2.5,<0.3', - 'nbsphinx>=0.5.0,<0.7', - 'Sphinx>=3,<3.3', - 'pydata-sphinx-theme<0.5', - 'markupsafe<2.1.0', - 'ipython>=6.5,<9', - 'Jinja2>=2,<3', - - # fails on Sphinx < v3.4 - 'alabaster<=0.7.12', - # fails on Sphins < v5.0 - 'sphinxcontrib-applehelp<1.0.8', - 'sphinxcontrib-devhelp<1.0.6', - 'sphinxcontrib-htmlhelp<2.0.5', - 'sphinxcontrib-serializinghtml<1.1.10', - 'sphinxcontrib-qthelp<1.0.7', - + 'docutils>=0.12,<1', + 'nbsphinx>=0.5.0,<1', + 'sphinx_toolbox>=2.5,<4', + 'Sphinx>=3,<8', + 'pydata-sphinx-theme<1', + 'markupsafe<3', + 'ipython>=6.5,<12', + 'Jinja2>=2,<4', + 'pickleshare', # ipython sphinx + # style check 'flake8>=3.7.7,<4', 'isort>=4.3.4,<5', @@ -114,10 +104,10 @@ 'License :: OSI Approved :: MIT License', 'Natural Language :: English', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', ], description="Orion is a machine learning library built for unsupervised time series anomaly detection.", entry_points={ @@ -142,7 +132,7 @@ long_description_content_type='text/markdown', name='orion-ml', packages=find_packages(include=['orion', 'orion.*']), - python_requires='>=3.8,<3.12', + python_requires='>=3.9,<3.13', setup_requires=setup_requires, test_suite='tests', tests_require=tests_require, diff --git a/tests/unit/primitives/adapters/test_ncps.py b/tests/unit/primitives/adapters/test_ncps.py index 5f989f59..bf630c41 100644 --- a/tests/unit/primitives/adapters/test_ncps.py +++ b/tests/unit/primitives/adapters/test_ncps.py @@ -47,7 +47,7 @@ def test_build_layer_bidirectional(): def test_build_layer_ltc(): # Setup layer = { - 'class': 'ncps.tf.LTC', + 'class': 'ncps.keras.LTC', 'parameters': { 'units': { 'class': 'ncps.wirings.AutoNCP', @@ -63,7 +63,7 @@ def test_build_layer_ltc(): built = build_layer(layer, {}) # Assert - assert isinstance(built, ncps.tf.LTC) + assert isinstance(built, ncps.keras.LTC) def test__build_model(): @@ -76,7 +76,7 @@ def test__build_model(): } } ] - loss = 'tensorflow.keras.losses.mean_squared_error' + loss = 'tensorflow.losses.mse' optimizer = 'tensorflow.keras.optimizers.Adam' # Run @@ -111,7 +111,7 @@ def test_ncps_linear(build_mock): } } ] - loss = 'tensorflow.keras.losses.mean_squared_error' + loss = 'tensorflow.losses.mse' optimizer = 'tensorflow.keras.optimizers.Adam' ncps = NCPS(layers, loss, optimizer, False, batch_size=1)