Skip to content

NeuralNetworkRegressor

Source code in src/safeds/ml/nn/_model.py
class NeuralNetworkRegressor:
    def __init__(self, layers: list[Layer]):
        self._model = _create_internal_model(layers, is_for_classification=False)
        self._input_size = self._model.input_size
        self._batch_size = 1
        self._is_fitted = False
        self._feature_names: None | list[str] = None
        self._total_number_of_batches_done = 0
        self._total_number_of_epochs_done = 0

    def fit(
        self,
        train_data: TaggedTable,
        epoch_size: int = 25,
        batch_size: int = 1,
        learning_rate: float = 0.001,
        callback_on_batch_completion: Callable[[int, float], None] | None = None,
        callback_on_epoch_completion: Callable[[int, float], None] | None = None,
    ) -> Self:
        """
        Train the neural network with given training data.

        The original model is not modified.

        Parameters
        ----------
        train_data
            The data the network should be trained on.
        epoch_size
            The number of times the training cycle should be done.
        batch_size
            The size of data batches that should be loaded at one time.
        learning_rate
            The learning rate of the neural network.
        callback_on_batch_completion
            Function used to view metrics while training. Gets called after a batch is completed with the index of the last batch and the overall loss average.
        callback_on_epoch_completion
            Function used to view metrics while training. Gets called after an epoch is completed with the index of the last epoch and the overall loss average.

        Raises
        ------
        ValueError
            If epoch_size < 1
            If batch_size < 1

        Returns
        -------
        trained_model :
            The trained Model
        """
        import torch
        from torch import nn

        if epoch_size < 1:
            raise OutOfBoundsError(actual=epoch_size, name="epoch_size", lower_bound=ClosedBound(1))
        if batch_size < 1:
            raise OutOfBoundsError(actual=batch_size, name="batch_size", lower_bound=ClosedBound(1))
        if train_data.features.number_of_columns is not self._input_size:
            raise InputSizeError(train_data.features.number_of_columns, self._input_size)

        copied_model = copy.deepcopy(self)

        copied_model._feature_names = train_data.features.column_names
        copied_model._batch_size = batch_size

        dataloader = train_data._into_dataloader_with_classes(copied_model._batch_size, 1)

        loss_fn = nn.MSELoss()

        optimizer = torch.optim.SGD(copied_model._model.parameters(), lr=learning_rate)
        for _ in range(epoch_size):
            loss_sum = 0.0
            amount_of_loss_values_calculated = 0
            for x, y in iter(dataloader):
                optimizer.zero_grad()

                pred = copied_model._model(x)

                loss = loss_fn(pred, y)
                loss_sum += loss.item()
                amount_of_loss_values_calculated += 1
                loss.backward()
                optimizer.step()
                copied_model._total_number_of_batches_done += 1
                if callback_on_batch_completion is not None:
                    callback_on_batch_completion(
                        copied_model._total_number_of_batches_done,
                        loss_sum / amount_of_loss_values_calculated,
                    )
            copied_model._total_number_of_epochs_done += 1
            if callback_on_epoch_completion is not None:
                callback_on_epoch_completion(
                    copied_model._total_number_of_epochs_done,
                    loss_sum / amount_of_loss_values_calculated,
                )
        copied_model._is_fitted = True
        copied_model._model.eval()
        return copied_model

    def predict(self, test_data: Table) -> TaggedTable:
        """
        Make a prediction for the given test data.

        The original Model is not modified.

        Parameters
        ----------
        test_data
            The data the network should predict.

        Returns
        -------
        prediction :
            The given test_data with an added "prediction" column at the end

        Raises
        ------
        ModelNotFittedError
            If the model has not been fitted yet
        """
        import torch

        if not self._is_fitted:
            raise ModelNotFittedError
        if not (sorted(test_data.column_names)).__eq__(
            sorted(self._feature_names) if self._feature_names is not None else None,
        ):
            raise TestTrainDataMismatchError
        dataloader = test_data._into_dataloader(self._batch_size)
        predictions = []
        with torch.no_grad():
            for x in dataloader:
                elem = self._model(x)
                predictions += elem.squeeze(dim=1).tolist()
        return test_data.add_column(Column("prediction", predictions)).tag_columns("prediction")

    @property
    def is_fitted(self) -> bool:
        """
        Check if the model is fitted.

        Returns
        -------
        is_fitted
            Whether the model is fitted.
        """
        return self._is_fitted

is_fitted: bool property

Check if the model is fitted.

Returns:

Type Description
is_fitted

Whether the model is fitted.

__init__(layers)

Source code in src/safeds/ml/nn/_model.py
def __init__(self, layers: list[Layer]):
    self._model = _create_internal_model(layers, is_for_classification=False)
    self._input_size = self._model.input_size
    self._batch_size = 1
    self._is_fitted = False
    self._feature_names: None | list[str] = None
    self._total_number_of_batches_done = 0
    self._total_number_of_epochs_done = 0

fit(train_data, epoch_size=25, batch_size=1, learning_rate=0.001, callback_on_batch_completion=None, callback_on_epoch_completion=None)

Train the neural network with given training data.

The original model is not modified.

Parameters:

Name Type Description Default
train_data TaggedTable

The data the network should be trained on.

required
epoch_size int

The number of times the training cycle should be done.

25
batch_size int

The size of data batches that should be loaded at one time.

1
learning_rate float

The learning rate of the neural network.

0.001
callback_on_batch_completion Callable[[int, float], None] | None

Function used to view metrics while training. Gets called after a batch is completed with the index of the last batch and the overall loss average.

None
callback_on_epoch_completion Callable[[int, float], None] | None

Function used to view metrics while training. Gets called after an epoch is completed with the index of the last epoch and the overall loss average.

None

Raises:

Type Description
ValueError

If epoch_size < 1 If batch_size < 1

Returns:

Name Type Description
trained_model Self

The trained Model

Source code in src/safeds/ml/nn/_model.py
def fit(
    self,
    train_data: TaggedTable,
    epoch_size: int = 25,
    batch_size: int = 1,
    learning_rate: float = 0.001,
    callback_on_batch_completion: Callable[[int, float], None] | None = None,
    callback_on_epoch_completion: Callable[[int, float], None] | None = None,
) -> Self:
    """
    Train the neural network with given training data.

    The original model is not modified.

    Parameters
    ----------
    train_data
        The data the network should be trained on.
    epoch_size
        The number of times the training cycle should be done.
    batch_size
        The size of data batches that should be loaded at one time.
    learning_rate
        The learning rate of the neural network.
    callback_on_batch_completion
        Function used to view metrics while training. Gets called after a batch is completed with the index of the last batch and the overall loss average.
    callback_on_epoch_completion
        Function used to view metrics while training. Gets called after an epoch is completed with the index of the last epoch and the overall loss average.

    Raises
    ------
    ValueError
        If epoch_size < 1
        If batch_size < 1

    Returns
    -------
    trained_model :
        The trained Model
    """
    import torch
    from torch import nn

    if epoch_size < 1:
        raise OutOfBoundsError(actual=epoch_size, name="epoch_size", lower_bound=ClosedBound(1))
    if batch_size < 1:
        raise OutOfBoundsError(actual=batch_size, name="batch_size", lower_bound=ClosedBound(1))
    if train_data.features.number_of_columns is not self._input_size:
        raise InputSizeError(train_data.features.number_of_columns, self._input_size)

    copied_model = copy.deepcopy(self)

    copied_model._feature_names = train_data.features.column_names
    copied_model._batch_size = batch_size

    dataloader = train_data._into_dataloader_with_classes(copied_model._batch_size, 1)

    loss_fn = nn.MSELoss()

    optimizer = torch.optim.SGD(copied_model._model.parameters(), lr=learning_rate)
    for _ in range(epoch_size):
        loss_sum = 0.0
        amount_of_loss_values_calculated = 0
        for x, y in iter(dataloader):
            optimizer.zero_grad()

            pred = copied_model._model(x)

            loss = loss_fn(pred, y)
            loss_sum += loss.item()
            amount_of_loss_values_calculated += 1
            loss.backward()
            optimizer.step()
            copied_model._total_number_of_batches_done += 1
            if callback_on_batch_completion is not None:
                callback_on_batch_completion(
                    copied_model._total_number_of_batches_done,
                    loss_sum / amount_of_loss_values_calculated,
                )
        copied_model._total_number_of_epochs_done += 1
        if callback_on_epoch_completion is not None:
            callback_on_epoch_completion(
                copied_model._total_number_of_epochs_done,
                loss_sum / amount_of_loss_values_calculated,
            )
    copied_model._is_fitted = True
    copied_model._model.eval()
    return copied_model

predict(test_data)

Make a prediction for the given test data.

The original Model is not modified.

Parameters:

Name Type Description Default
test_data Table

The data the network should predict.

required

Returns:

Name Type Description
prediction TaggedTable

The given test_data with an added "prediction" column at the end

Raises:

Type Description
ModelNotFittedError

If the model has not been fitted yet

Source code in src/safeds/ml/nn/_model.py
def predict(self, test_data: Table) -> TaggedTable:
    """
    Make a prediction for the given test data.

    The original Model is not modified.

    Parameters
    ----------
    test_data
        The data the network should predict.

    Returns
    -------
    prediction :
        The given test_data with an added "prediction" column at the end

    Raises
    ------
    ModelNotFittedError
        If the model has not been fitted yet
    """
    import torch

    if not self._is_fitted:
        raise ModelNotFittedError
    if not (sorted(test_data.column_names)).__eq__(
        sorted(self._feature_names) if self._feature_names is not None else None,
    ):
        raise TestTrainDataMismatchError
    dataloader = test_data._into_dataloader(self._batch_size)
    predictions = []
    with torch.no_grad():
        for x in dataloader:
            elem = self._model(x)
            predictions += elem.squeeze(dim=1).tolist()
    return test_data.add_column(Column("prediction", predictions)).tag_columns("prediction")