Source code for optilab.optimizers.lmm_cma_es

"""
LMM-CMA-ES optimizer: CMA-ES with local polynomial regression metamodel.
"""

from ..data_classes import Bounds, PointList
from ..functions import ObjectiveFunction
from ..functions.surrogate import LocallyWeightedPolynomialRegression
from ..metamodels import ApproximateRankingMetamodel
from .cma_es import CmaEs
from .optimizer import Optimizer


[docs] class LmmCmaEs(CmaEs): """ LMM-CMA-ES optimizer: CMA-ES with local polynomial regression metamodel. """
[docs] def __init__( self, population_size: int, sigma0: float, polynomial_dim: int, ): """ Class constructor. Args: population_size: Size of the population. sigma0: Starting value of the sigma, polynomial_dim: Dimension of the polynomial regression. """ # Skipping super().__init__ and calling grandparent init instead. # pylint: disable=super-init-not-called, non-parent-init-called Optimizer.__init__( self, "lmm-cma-es", population_size, { "sigma0": sigma0, "polynomial_dim": polynomial_dim, }, )
# pylint: disable=duplicate-code
[docs] def optimize( self, function: ObjectiveFunction, bounds: Bounds, call_budget: int, tolerance: float, target: float = 0.0, ) -> PointList: """ Run a single optimization of provided objective function. Args: function: Objective function to optimize. bounds: Search space of the function. call_budget: Max number of calls to the objective function. tolerance: Tolerance of y value to count a solution as acceptable. target: Objective function value target, default 0. Returns: Results log from the optimization. """ num_neighbors = function.metadata.dim * (function.metadata.dim + 3) + 2 metamodel = ApproximateRankingMetamodel( self.metadata.population_size, self.metadata.population_size // 2, function, LocallyWeightedPolynomialRegression( self.metadata.hyperparameters["polynomial_dim"], num_neighbors ), ) es = self._spawn_cmaes( bounds, function.metadata.dim, self.metadata.population_size, self.metadata.hyperparameters["sigma0"], ) while not self._stop( es, metamodel.get_log(), self.metadata.population_size, call_budget, target, tolerance, ): solutions = PointList.from_list(es.ask()) metamodel.surrogate_function.set_covariance_matrix(es.C) metamodel.adapt(solutions) xy_pairs = metamodel(solutions) x, y = xy_pairs.pairs() es.tell(x, y) return metamodel.get_log()