Source code for optilab.functions.surrogate.mlp_surrogate_objective_function

"""
Surrogate objective function using sklearn MLPRegressor.
"""

from typing import Tuple

import numpy as np
from sklearn.neural_network import MLPRegressor

from ...data_classes import Point, PointList
from .surrogate_objective_function import SurrogateObjectiveFunction


[docs] class MLPSurrogateObjectiveFunction(SurrogateObjectiveFunction): """ Surrogate objective function using sklearn MLPRegressor. """
[docs] def __init__( self, hidden_layer_sizes: Tuple[int] = (32,), train_set: PointList | None = None, *, activation: str = "relu", solver: str = "adam", learning_rate_init: float = 0.001, l2_alpha: float = 0.0001, max_iter: int = 200, early_stopping: bool = True, random_seed: int | None = None, ) -> None: """ Class constructor. Args: hidden_layer_sizes: Shape of hidden layers. train_set: Training data for the model. activation: Activation function for hidden layers. solver: The solver for weight optimization. learning_rate_init: Initial learning rate used by optimizer. l2_alpha: L2 regularization weight. max_iter: Maximum number of optimization iterations. early_stopping: Whether to use validation-based early stopping. random_seed: Seed for reproducible initialization. """ self.hidden_layer_sizes = hidden_layer_sizes self.activation = activation self.solver = solver self.l2_alpha = l2_alpha self.learning_rate_init = learning_rate_init self.max_iter = max_iter self.early_stopping = early_stopping self.random_seed = random_seed self.model: MLPRegressor | None = None hidden_layers_repr = "_".join(str(size) for size in hidden_layer_sizes) super().__init__( f"MLP_{hidden_layers_repr}", train_set, { "hidden_layer_sizes": hidden_layer_sizes, "activation": activation, "solver": solver, "l2_alpha": l2_alpha, "learning_rate_init": learning_rate_init, "max_iter": max_iter, "early_stopping": early_stopping, "random_seed": random_seed, }, )
[docs] def train(self, train_set: PointList) -> None: """ Train the MLP surrogate function with provided data. Args: train_set: Training data for the model. """ super().train(train_set) x_train, y_train = self.train_set.pairs() self.model = MLPRegressor( hidden_layer_sizes=self.hidden_layer_sizes, activation=self.activation, solver=self.solver, alpha=self.l2_alpha, learning_rate_init=self.learning_rate_init, max_iter=self.max_iter, early_stopping=self.early_stopping, random_state=self.random_seed, ) # ignore warnings about overflows and zero divisions when covariance matrix # is ill-conditioned with np.errstate(divide="ignore", over="ignore", invalid="ignore"): self.model.fit(x_train, y_train)
# pylint: disable=duplicate-code
[docs] def __call__(self, point: Point) -> Point: """ Estimate the function value at a given point using MLP regression. Args: point: Point to estimate. Returns: Estimated value of the function at the given point. """ super().__call__(point) x_query = np.array([point.x], dtype=np.float64) # ignore warnings about overflows and zero divisions when covariance matrix # is ill-conditioned with np.errstate(divide="ignore", over="ignore", invalid="ignore"): y_pred = self.model.predict(x_query)[0] return Point( x=point.x, y=float(y_pred), is_evaluated=False, )