From 56e706915429e7c78404bbc4a05483877db73929 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Tue, 26 Nov 2024 16:55:26 +0100 Subject: [PATCH 1/2] feat: rename `epoch_size` to `epoch_count` --- ...ral_network_for_image_classification.ipynb | 4 +-- docs/tutorials/time_series_forecasting.ipynb | 2 +- src/safeds/ml/nn/_model.py | 36 +++++++++---------- tests/safeds/ml/nn/test_cnn_workflow.py | 8 ++--- tests/safeds/ml/nn/test_dropout_workflow.py | 2 +- tests/safeds/ml/nn/test_forward_workflow.py | 2 +- tests/safeds/ml/nn/test_lstm_workflow.py | 4 +-- tests/safeds/ml/nn/test_model.py | 34 +++++++++--------- 8 files changed, 46 insertions(+), 46 deletions(-) diff --git a/docs/tutorials/convolutional_neural_network_for_image_classification.ipynb b/docs/tutorials/convolutional_neural_network_for_image_classification.ipynb index d7035bb84..77a15821e 100644 --- a/docs/tutorials/convolutional_neural_network_for_image_classification.ipynb +++ b/docs/tutorials/convolutional_neural_network_for_image_classification.ipynb @@ -197,11 +197,11 @@ "id": "3d8efa74951725cb" }, { - "cell_type": "code", - "source": "cnn_fitted = cnn.fit(dataset, epoch_size=8, batch_size=16)", "metadata": { "collapsed": false }, + "cell_type": "code", + "source": "cnn_fitted = cnn.fit(dataset, epoch_count=8, batch_size=16)", "id": "381627a94d500675", "outputs": [], "execution_count": null diff --git a/docs/tutorials/time_series_forecasting.ipynb b/docs/tutorials/time_series_forecasting.ipynb index 62c2184e9..6f011c08e 100644 --- a/docs/tutorials/time_series_forecasting.ipynb +++ b/docs/tutorials/time_series_forecasting.ipynb @@ -205,7 +205,7 @@ " forecast_horizon=1,\n", " continuous=False,\n", " extra_names= [\"date\"]\n", - "), epoch_size=25)" + "), epoch_count=25)" ], "metadata": { "collapsed": false, diff --git a/src/safeds/ml/nn/_model.py b/src/safeds/ml/nn/_model.py index 55dea7ecb..b9c6a4e74 100644 --- a/src/safeds/ml/nn/_model.py +++ b/src/safeds/ml/nn/_model.py @@ -166,7 +166,7 @@ def from_pretrained_model(huggingface_repo: str) -> NeuralNetworkRegressor: # p def fit( self, train_data: IFT, - epoch_size: int = 25, + epoch_count: int = 25, batch_size: int = 1, learning_rate: float = 0.001, callback_on_batch_completion: Callable[[int, float], None] | None = None, @@ -181,7 +181,7 @@ def fit( ---------- train_data: The data the network should be trained on. - epoch_size: + epoch_count: The number of times the training cycle should be done. batch_size: The size of data batches that should be loaded at one time. @@ -202,7 +202,7 @@ def fit( Raises ------ OutOfBoundsError - If epoch_size < 1 + If epoch_count < 1 If batch_size < 1 """ import torch @@ -218,7 +218,7 @@ def fit( if not self._input_conversion._is_fit_data_valid(train_data): raise FeatureDataMismatchError - _check_bounds("epoch_size", epoch_size, lower_bound=_ClosedBound(1)) + _check_bounds("epoch_count", epoch_count, lower_bound=_ClosedBound(1)) _check_bounds("batch_size", batch_size, lower_bound=_ClosedBound(1)) copied_model = copy.deepcopy(self) @@ -236,7 +236,7 @@ def fit( loss_fn = nn.MSELoss() optimizer = torch.optim.SGD(copied_model._model.parameters(), lr=learning_rate) - for _ in range(epoch_size): + for _ in range(epoch_count): loss_sum = 0.0 amount_of_loss_values_calculated = 0 for x, y in iter(dataloader): @@ -273,7 +273,7 @@ def fit( # "median_absolute_deviation", # "coefficient_of_determination", # ], - # epoch_size: int = 25, + # epoch_count: int = 25, # batch_size: int = 1, # learning_rate: float = 0.001, # ) -> Self: @@ -288,7 +288,7 @@ def fit( # The data the network should be trained on. # optimization_metric: # The metric that should be used for determining the performance of a model. - # epoch_size: + # epoch_count: # The number of times the training cycle should be done. # batch_size: # The size of data batches that should be loaded at one time. @@ -317,7 +317,7 @@ def fit( # "Hyperparameter optimization is currently not supported for CNN Regression Tasks.", # ) # pragma: no cover # - # _check_bounds("epoch_size", epoch_size, lower_bound=_ClosedBound(1)) + # _check_bounds("epoch_count", epoch_count, lower_bound=_ClosedBound(1)) # _check_bounds("batch_size", batch_size, lower_bound=_ClosedBound(1)) # # list_of_models = self._get_models_for_all_choices() @@ -334,7 +334,7 @@ def fit( # executor.submit( # model.fit, # train_set, # type: ignore[arg-type] - # epoch_size, + # epoch_count, # batch_size, # learning_rate, # ), @@ -774,7 +774,7 @@ def from_pretrained_model(huggingface_repo: str) -> NeuralNetworkClassifier: # def fit( self, train_data: IFT, - epoch_size: int = 25, + epoch_count: int = 25, batch_size: int = 1, learning_rate: float = 0.001, callback_on_batch_completion: Callable[[int, float], None] | None = None, @@ -789,7 +789,7 @@ def fit( ---------- train_data: The data the network should be trained on. - epoch_size: + epoch_count: The number of times the training cycle should be done. batch_size: The size of data batches that should be loaded at one time. @@ -810,7 +810,7 @@ def fit( Raises ------ ValueError - If epoch_size < 1 + If epoch_count < 1 If batch_size < 1 """ import torch @@ -831,7 +831,7 @@ def fit( if not self._input_conversion._is_fit_data_valid(train_data): raise FeatureDataMismatchError - _check_bounds("epoch_size", epoch_size, lower_bound=_ClosedBound(1)) + _check_bounds("epoch_count", epoch_count, lower_bound=_ClosedBound(1)) _check_bounds("batch_size", batch_size, lower_bound=_ClosedBound(1)) copied_model = copy.deepcopy(self) @@ -856,7 +856,7 @@ def fit( loss_fn = nn.BCELoss() optimizer = torch.optim.SGD(copied_model._model.parameters(), lr=learning_rate) - for _ in range(epoch_size): + for _ in range(epoch_count): loss_sum = 0.0 amount_of_loss_values_calculated = 0 for x, y in iter(dataloader): @@ -890,7 +890,7 @@ def fit( # train_data: IFT, # optimization_metric: Literal["accuracy", "precision", "recall", "f1_score"], # positive_class: Any = None, - # epoch_size: int = 25, + # epoch_count: int = 25, # batch_size: int = 1, # learning_rate: float = 0.001, # ) -> Self: @@ -907,7 +907,7 @@ def fit( # The metric that should be used for determining the performance of a model. # positive_class: # The class to be considered positive. Only needs to be provided when choosing precision, recall or f1_score as the optimization metric. - # epoch_size: + # epoch_count: # The number of times the training cycle should be done. # batch_size: # The size of data batches that should be loaded at one time. @@ -936,7 +936,7 @@ def fit( # "Continuous Predictions are currently not supported for Time Series Classification.", # ) # - # _check_bounds("epoch_size", epoch_size, lower_bound=_ClosedBound(1)) + # _check_bounds("epoch_count", epoch_count, lower_bound=_ClosedBound(1)) # _check_bounds("batch_size", batch_size, lower_bound=_ClosedBound(1)) # # list_of_models = self._get_models_for_all_choices() @@ -956,7 +956,7 @@ def fit( # executor.submit( # model.fit, # train_set, # type: ignore[arg-type] - # epoch_size, + # epoch_count, # batch_size, # learning_rate, # ), diff --git a/tests/safeds/ml/nn/test_cnn_workflow.py b/tests/safeds/ml/nn/test_cnn_workflow.py index 16a36757e..5353436df 100644 --- a/tests/safeds/ml/nn/test_cnn_workflow.py +++ b/tests/safeds/ml/nn/test_cnn_workflow.py @@ -88,7 +88,7 @@ def test_should_train_and_predict_model( InputConversionImageToTable(image_dataset.input_size), layers, ) - nn = nn_original.fit(image_dataset, epoch_size=2) + nn = nn_original.fit(image_dataset, epoch_count=2) assert nn_original._model is not nn._model prediction: ImageDataset = nn.predict(image_dataset.get_input()) assert one_hot_encoder.inverse_transform(prediction.get_output()) == Table({"class": prediction_label}) @@ -147,7 +147,7 @@ def test_should_train_and_predict_model( InputConversionImageToColumn(image_dataset.input_size), layers, ) - nn = nn_original.fit(image_dataset, epoch_size=2) + nn = nn_original.fit(image_dataset, epoch_count=2) assert nn_original._model is not nn._model prediction: ImageDataset = nn.predict(image_dataset.get_input()) assert prediction.get_output() == Column("class", prediction_label) @@ -188,7 +188,7 @@ def test_should_train_and_predict_model( InputConversionImageToImage(image_dataset.input_size), layers, ) - nn = nn_original.fit(image_dataset, epoch_size=20) + nn = nn_original.fit(image_dataset, epoch_count=20) assert nn_original._model is not nn._model prediction = nn.predict(image_dataset.get_input()) assert isinstance(prediction.get_output(), ImageList) @@ -229,7 +229,7 @@ def test_should_train_and_predict_model_variable_image_size( InputConversionImageToImage(VariableImageSize.from_image_size(image_dataset.input_size)), layers, ) - nn = nn_original.fit(image_dataset, epoch_size=20) + nn = nn_original.fit(image_dataset, epoch_count=20) assert nn_original._model is not nn._model prediction = nn.predict( image_dataset.get_input().resize( diff --git a/tests/safeds/ml/nn/test_dropout_workflow.py b/tests/safeds/ml/nn/test_dropout_workflow.py index b51f0708b..f4ac2b97a 100644 --- a/tests/safeds/ml/nn/test_dropout_workflow.py +++ b/tests/safeds/ml/nn/test_dropout_workflow.py @@ -32,6 +32,6 @@ def test_forward_model(device: Device) -> None: [ForwardLayer(neuron_count=1), DropoutLayer(probability=0.5)], ) - fitted_model = model.fit(train_table.to_tabular_dataset("value"), epoch_size=1, learning_rate=0.01) + fitted_model = model.fit(train_table.to_tabular_dataset("value"), epoch_count=1, learning_rate=0.01) assert fitted_model._model is not None assert fitted_model._model.state_dict()["_pytorch_layers.0._layer.weight"].device == _get_device() diff --git a/tests/safeds/ml/nn/test_forward_workflow.py b/tests/safeds/ml/nn/test_forward_workflow.py index acb8a1cd9..8440dc521 100644 --- a/tests/safeds/ml/nn/test_forward_workflow.py +++ b/tests/safeds/ml/nn/test_forward_workflow.py @@ -38,7 +38,7 @@ def test_forward_model(device: Device) -> None: [ForwardLayer(neuron_count=1)], ) - fitted_model = model.fit(train_table.to_tabular_dataset("target"), epoch_size=1, learning_rate=0.01) + fitted_model = model.fit(train_table.to_tabular_dataset("target"), epoch_count=1, learning_rate=0.01) fitted_model.predict(test_table.remove_columns_except(["value"])) assert fitted_model._model is not None assert fitted_model._model.state_dict()["_pytorch_layers.0._layer.weight"].device == _get_device() diff --git a/tests/safeds/ml/nn/test_lstm_workflow.py b/tests/safeds/ml/nn/test_lstm_workflow.py index 307a139c6..668cc3dc3 100644 --- a/tests/safeds/ml/nn/test_lstm_workflow.py +++ b/tests/safeds/ml/nn/test_lstm_workflow.py @@ -45,7 +45,7 @@ def test_lstm_model(device: Device) -> None: continuous=True, extra_names=["date"], ), - epoch_size=1, + epoch_count=1, ) trained_model.predict(test_table) @@ -57,7 +57,7 @@ def test_lstm_model(device: Device) -> None: continuous=False, extra_names=["date"], ), - epoch_size=1, + epoch_count=1, ) trained_model_2.predict(test_table) diff --git a/tests/safeds/ml/nn/test_model.py b/tests/safeds/ml/nn/test_model.py index ed486a74c..ac86ad0b8 100644 --- a/tests/safeds/ml/nn/test_model.py +++ b/tests/safeds/ml/nn/test_model.py @@ -55,8 +55,8 @@ def test_should_return_input_size(self, device: Device) -> None: ) assert model.input_size == 1 - def test_should_raise_if_epoch_size_out_of_bounds(self, device: Device) -> None: - invalid_epoch_size = 0 + def test_should_raise_if_epoch_count_out_of_bounds(self, device: Device) -> None: + invalid_epoch_count = 0 configure_test_with_device(device) with pytest.raises(OutOfBoundsError): NeuralNetworkClassifier( @@ -64,7 +64,7 @@ def test_should_raise_if_epoch_size_out_of_bounds(self, device: Device) -> None: [ForwardLayer(1)], ).fit( Table.from_dict({"a": [1], "b": [2]}).to_tabular_dataset("a"), - epoch_size=invalid_epoch_size, + epoch_count=invalid_epoch_count, ) def test_should_raise_if_batch_size_out_of_bounds(self, device: Device) -> None: @@ -285,11 +285,11 @@ def callback_was_called(self) -> bool: # ) # assert model.input_size == 1 # - # def test_should_raise_if_epoch_size_out_of_bounds_when_fitting_by_exhaustive_search( + # def test_should_raise_if_epoch_count_out_of_bounds_when_fitting_by_exhaustive_search( # self, # device: Device, # ) -> None: - # invalid_epoch_size = 0 + # invalid_epoch_count = 0 # configure_test_with_device(device) # with pytest.raises(OutOfBoundsError): # NeuralNetworkClassifier( @@ -298,7 +298,7 @@ def callback_was_called(self) -> bool: # ).fit_by_exhaustive_search( # Table.from_dict({"a": [1], "b": [0]}).to_tabular_dataset("b"), # "accuracy", - # epoch_size=invalid_epoch_size, + # epoch_count=invalid_epoch_count, # ) # # def test_should_raise_if_batch_size_out_of_bounds_when_fitting_by_exhaustive_search( @@ -435,7 +435,7 @@ def callback_was_called(self) -> bool: # train_table, # optimization_metric=metric, # positive_class=positive_class, - # epoch_size=2, + # epoch_count=2, # ) # # assert fitted_model.is_fitted @@ -497,7 +497,7 @@ def callback_was_called(self) -> bool: # assert not model.is_fitted # fitted_model = model.fit_by_exhaustive_search( # image_dataset, - # epoch_size=2, + # epoch_count=2, # optimization_metric=metric, # positive_class=positive_class, # ) @@ -561,7 +561,7 @@ def callback_was_called(self) -> bool: # assert not model.is_fitted # fitted_model = model.fit_by_exhaustive_search( # image_dataset, - # epoch_size=2, + # epoch_count=2, # optimization_metric=metric, # positive_class=positive_class, # ) @@ -843,8 +843,8 @@ def test_should_return_input_size(self, device: Device) -> None: ) assert model.input_size == 1 - def test_should_raise_if_epoch_size_out_of_bounds(self, device: Device) -> None: - invalid_epoch_size = 0 + def test_should_raise_if_epoch_count_out_of_bounds(self, device: Device) -> None: + invalid_epoch_count = 0 configure_test_with_device(device) with pytest.raises(OutOfBoundsError): NeuralNetworkRegressor( @@ -852,7 +852,7 @@ def test_should_raise_if_epoch_size_out_of_bounds(self, device: Device) -> None: [ForwardLayer(neuron_count=1)], ).fit( Table.from_dict({"a": [1], "b": [2]}).to_tabular_dataset("a"), - epoch_size=invalid_epoch_size, + epoch_count=invalid_epoch_count, ) def test_should_raise_if_batch_size_out_of_bounds(self, device: Device) -> None: @@ -1036,11 +1036,11 @@ def callback_was_called(self) -> bool: # ) # assert model.input_size == 1 # - # def test_should_raise_if_epoch_size_out_of_bounds_when_fitting_by_exhaustive_search( + # def test_should_raise_if_epoch_count_out_of_bounds_when_fitting_by_exhaustive_search( # self, # device: Device, # ) -> None: - # invalid_epoch_size = 0 + # invalid_epoch_count = 0 # configure_test_with_device(device) # with pytest.raises(OutOfBoundsError): # NeuralNetworkRegressor( @@ -1049,7 +1049,7 @@ def callback_was_called(self) -> bool: # ).fit_by_exhaustive_search( # Table.from_dict({"a": [1], "b": [1.0]}).to_tabular_dataset("b"), # "mean_squared_error", - # epoch_size=invalid_epoch_size, + # epoch_count=invalid_epoch_count, # ) # # def test_should_raise_if_batch_size_out_of_bounds_when_fitting_by_exhaustive_search( @@ -1157,7 +1157,7 @@ def callback_was_called(self) -> bool: # ) # assert not model.is_fitted # - # fitted_model = model.fit_by_exhaustive_search(train_table, optimization_metric=metric, epoch_size=2) + # fitted_model = model.fit_by_exhaustive_search(train_table, optimization_metric=metric, epoch_count=2) # # assert fitted_model.is_fitted # assert isinstance(fitted_model, NeuralNetworkRegressor) @@ -1207,7 +1207,7 @@ def callback_was_called(self) -> bool: # ) # assert not model.is_fitted # - # fitted_model = model.fit_by_exhaustive_search(train_table, optimization_metric=metric, epoch_size=2) + # fitted_model = model.fit_by_exhaustive_search(train_table, optimization_metric=metric, epoch_count=2) # # assert fitted_model.is_fitted # assert isinstance(fitted_model, NeuralNetworkRegressor) From ef4c163e84082c1de3e55994e664a80e31ca24be Mon Sep 17 00:00:00 2001 From: megalinter-bot <129584137+megalinter-bot@users.noreply.github.com> Date: Tue, 26 Nov 2024 16:18:00 +0000 Subject: [PATCH 2/2] style: apply automated linter fixes --- tests/safeds/ml/nn/test_cnn_workflow.py | 4 ++-- tests/safeds/ml/nn/test_dropout_workflow.py | 4 ++-- tests/safeds/ml/nn/test_forward_workflow.py | 4 ++-- tests/safeds/ml/nn/test_lstm_workflow.py | 4 ++-- tests/safeds/ml/nn/test_model.py | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/safeds/ml/nn/test_cnn_workflow.py b/tests/safeds/ml/nn/test_cnn_workflow.py index 5353436df..e39f99d56 100644 --- a/tests/safeds/ml/nn/test_cnn_workflow.py +++ b/tests/safeds/ml/nn/test_cnn_workflow.py @@ -3,6 +3,8 @@ import pytest import torch +from torch.types import Device + from safeds._config import _get_device from safeds.data.image.containers import ImageList from safeds.data.image.containers._single_size_image_list import _SingleSizeImageList @@ -27,8 +29,6 @@ MaxPooling2DLayer, ) from safeds.ml.nn.typing import VariableImageSize -from torch.types import Device - from tests.helpers import configure_test_with_device, device_cpu, device_cuda, images_all, resolve_resource_path if TYPE_CHECKING: diff --git a/tests/safeds/ml/nn/test_dropout_workflow.py b/tests/safeds/ml/nn/test_dropout_workflow.py index f4ac2b97a..0e6f6d78d 100644 --- a/tests/safeds/ml/nn/test_dropout_workflow.py +++ b/tests/safeds/ml/nn/test_dropout_workflow.py @@ -1,4 +1,6 @@ import pytest +from torch.types import Device + from safeds._config import _get_device from safeds.data.tabular.containers import Table from safeds.ml.nn import ( @@ -11,8 +13,6 @@ DropoutLayer, ForwardLayer, ) -from torch.types import Device - from tests.helpers import configure_test_with_device, get_devices, get_devices_ids diff --git a/tests/safeds/ml/nn/test_forward_workflow.py b/tests/safeds/ml/nn/test_forward_workflow.py index 8440dc521..a3957a83c 100644 --- a/tests/safeds/ml/nn/test_forward_workflow.py +++ b/tests/safeds/ml/nn/test_forward_workflow.py @@ -1,4 +1,6 @@ import pytest +from torch.types import Device + from safeds._config import _get_device from safeds.data.tabular.containers import Table from safeds.data.tabular.transformation import StandardScaler @@ -11,8 +13,6 @@ from safeds.ml.nn.layers import ( ForwardLayer, ) -from torch.types import Device - from tests.helpers import configure_test_with_device, get_devices, get_devices_ids, resolve_resource_path diff --git a/tests/safeds/ml/nn/test_lstm_workflow.py b/tests/safeds/ml/nn/test_lstm_workflow.py index 668cc3dc3..50a75c1d8 100644 --- a/tests/safeds/ml/nn/test_lstm_workflow.py +++ b/tests/safeds/ml/nn/test_lstm_workflow.py @@ -1,4 +1,6 @@ import pytest +from torch.types import Device + from safeds._config import _get_device from safeds.data.tabular.containers import Table from safeds.data.tabular.transformation import RangeScaler @@ -13,8 +15,6 @@ GRULayer, LSTMLayer, ) -from torch.types import Device - from tests.helpers import configure_test_with_device, get_devices, get_devices_ids, resolve_resource_path diff --git a/tests/safeds/ml/nn/test_model.py b/tests/safeds/ml/nn/test_model.py index ac86ad0b8..c425da5fd 100644 --- a/tests/safeds/ml/nn/test_model.py +++ b/tests/safeds/ml/nn/test_model.py @@ -2,6 +2,8 @@ import re import pytest +from torch.types import Device + from safeds.data.image.typing import ImageSize from safeds.data.labeled.containers import TabularDataset from safeds.data.tabular.containers import Table @@ -37,8 +39,6 @@ MaxPooling2DLayer, ) from safeds.ml.nn.typing import VariableImageSize -from torch.types import Device - from tests.helpers import configure_test_with_device, get_devices, get_devices_ids