Source code for autooed.mobo.surrogate_model.base

'''
Surrogate model that predicts the objective values of given design variables.
'''

from abc import ABC, abstractmethod
import numpy as np

from autooed.utils.normalization import StandardNormalization


[docs]class SurrogateModel(ABC): ''' Base class of surrogate model. '''
[docs] def __init__(self, problem, **kwargs): ''' Initialize a surrogate model. Parameters ---------- problem: autooed.problem.Problem The optimization problem. ''' self.problem = problem self.n_var, self.n_obj = problem.n_var, problem.n_obj self.bounds = np.array([problem.xl, problem.xu]) self.transformation = problem.transformation self.normalization = StandardNormalization(self.bounds) self.fitted = False
[docs] def fit(self, X, Y, dtype='raw'): ''' Fit a surrogate model from data. Parameters ---------- X: np.array Input design variables. Y: np.array Input objective values. ''' assert dtype in ['raw', 'continuous', 'normalized'], f'Undefined data type {dtype} in surrogate fitting' if dtype == 'raw': X = self.transformation.do(X) if dtype == 'raw' or dtype == 'continuous': self.normalization.fit(X, Y) X, Y = self.normalization.do(x=X, y=Y) self._fit(X, Y) self.fitted = True
[docs] @abstractmethod def _fit(self, X, Y): ''' Fit a surrogate model from normalized and continuous data. Parameters ---------- X: np.array Input design variables (normalized, continuous). Y: np.array Input objective values (normalized). ''' pass
[docs] def evaluate(self, X, dtype='raw', std=False, gradient=False, hessian=False): ''' Predict the performance given a set of design variables. Parameters ---------- X: np.array Input design variables. std: bool Whether to calculate the standard deviation of the prediction. gradient: bool Whether to calculate the gradient of the prediction. hessian: bool Whether to calculate the hessian of the prediction. Returns ------- out: dict A output dictionary containing following properties of performance:\n - out['F']: mean, shape (N, n_obj) - out['dF']: gradient of mean, shape (N, n_obj, n_var) - out['hF']: hessian of mean, shape (N, n_obj, n_var, n_var) - out['S']: std, shape (N, n_obj) - out['dS']: gradient of std, shape (N, n_obj, n_var) - out['hS']: hessian of std, shape (N, n_obj, n_var, n_var) ''' assert self.fitted, f'Surrogate model is not fitted yet' assert dtype in ['raw', 'continuous', 'normalized'], f'Undefined data type {dtype} in surrogate evaluation' if dtype == 'raw': X = self.transformation.do(X) if dtype == 'raw' or dtype == 'continuous': X = self.normalization.do(x=X) out = self._evaluate(X, std, gradient, hessian) out['F'] = self.normalization.undo(y=out['F']) if gradient: out['dF'] = self.normalization.rescale(y=out['dF'].transpose(0, 2, 1)).transpose(0, 2, 1) if std: out['S'] = self.normalization.rescale(y=out['S']) if std and gradient: out['dS'] = self.normalization.rescale(y=out['dS'].transpose(0, 2, 1)).transpose(0, 2, 1) return out
[docs] @abstractmethod def _evaluate(self, X, std, gradient, hessian): ''' Predict the performance given a set of normalized and continuous design variables. Parameters ---------- X: np.array Input design variables (normalized, continuous). std: bool Whether to calculate the standard deviation of the prediction. gradient: bool Whether to calculate the gradient of the prediction. hessian: bool Whether to calculate the hessian of the prediction. Returns ------- out: dict A output dictionary containing following properties of performance:\n - out['F']: mean, shape (N, n_obj) - out['dF']: gradient of mean, shape (N, n_obj, n_var) - out['hF']: hessian of mean, shape (N, n_obj, n_var, n_var) - out['S']: std, shape (N, n_obj) - out['dS']: gradient of std, shape (N, n_obj, n_var) - out['hS']: hessian of std, shape (N, n_obj, n_var, n_var) ''' pass
[docs] def predict(self, X, dtype='raw', std=False): ''' ''' out = self.evaluate(X, dtype=dtype, std=std) if std: return out['F'], out['S'] else: return out['F']