예제 #1
0
    def setUp(self):
        kwargs = {
            'n_samples': 1000,
            'n_burnin': 100,
            'subsample_interval': 5,
            'step_size': 1e-1,
            'leapfrog_steps': 20,
            'optimize_restarts': 10,
            'num_inducing': 15,
            'acquisition_transformation': 'softplus',
            'acquisition_jitter': 0.02,
            'acquisition_weight': 2.5,
            'acquisition_transformation': 'softplus'
        }

        ## --- Defaults for some of the tests
        self.space = Design_space(space=[{
            'name': 'var1',
            'type': 'continuous',
            'domain': (-10, 10),
            'dimensionality': 2
        }])
        self.cost = CostModel(None)
        self.arguments_manager = ArgumentsManager(kwargs)
        self.model = self.arguments_manager.model_creator(model_type='GP',
                                                          exact_feval=True,
                                                          space=self.space)
        self.acquisition_optimizer = AcquisitionOptimizer(self.space)
        self.acquisition = self.arguments_manager.acquisition_creator(
            'EI', self.model, self.space, self.acquisition_optimizer,
            self.cost)
예제 #2
0
    def setUp(self):
        kwargs  = {'n_samples':1000,
                    'n_burnin':100,
                    'subsample_interval':5,
                    'step_size': 1e-1,
                    'leapfrog_steps':20,
                    'optimize_restarts':10,
                    'num_inducing':15,
                    'acquisition_transformation':'softplus',
                    'acquisition_jitter':0.02,
                    'acquisition_weight':2.5,
                    'acquisition_transformation':'softplus'
                    }

        ## --- Defaults for some of the tests
        self.space = Design_space(space =[{'name': 'var1', 'type': 'continuous', 'domain': (-10,10),'dimensionality': 2}])
        self.cost = CostModel(None)
        self.arguments_manager = ArgumentsManager(kwargs)
        self.model = self.arguments_manager.model_creator(model_type = 'GP', exact_feval= True, space = self.space)
        self.acquisition_optimizer = AcquisitionOptimizer(self.space)
        self.acquisition = self.arguments_manager.acquisition_creator('EI', self.model, self.space, self.acquisition_optimizer, self.cost)
예제 #3
0
class TestArgumentsManager(unittest.TestCase):
    '''
    The test just checks that the arguments are passed and handled, not that the model
    or the acquisition does the right thing with them.
    '''
    def setUp(self):
        kwargs = {
            'n_samples': 1000,
            'n_burnin': 100,
            'subsample_interval': 5,
            'step_size': 1e-1,
            'leapfrog_steps': 20,
            'optimize_restarts': 10,
            'num_inducing': 15,
            'acquisition_transformation': 'softplus',
            'acquisition_jitter': 0.02,
            'acquisition_weight': 2.5,
            'acquisition_transformation': 'softplus'
        }

        ## --- Defaults for some of the tests
        self.space = Design_space(space=[{
            'name': 'var1',
            'type': 'continuous',
            'domain': (-10, 10),
            'dimensionality': 2
        }])
        self.cost = CostModel(None)
        self.arguments_manager = ArgumentsManager(kwargs)
        self.model = self.arguments_manager.model_creator(model_type='GP',
                                                          exact_feval=True,
                                                          space=self.space)
        self.acquisition_optimizer = AcquisitionOptimizer(self.space)
        self.acquisition = self.arguments_manager.acquisition_creator(
            'EI', self.model, self.space, self.acquisition_optimizer,
            self.cost)

    def test_model_gp_mcmc_arguments(self):
        '''
        Testing the arguments of the GP model with MCMC
        '''
        model_type = 'GP_MCMC'
        exact_feval = True
        created_model = self.arguments_manager.model_creator(
            model_type, exact_feval, self.space)
        self.assertTrue(isinstance(created_model, GPModel_MCMC))
        self.assertEquals(created_model.n_samples, 1000)
        self.assertEquals(created_model.n_burnin, 100)
        self.assertEquals(created_model.subsample_interval, 5)
        self.assertEquals(created_model.step_size, 1e-1)
        self.assertEquals(created_model.leapfrog_steps, 20)

    def test_model_sparse_gp_arguments(self):
        '''
        Testing the arguments of the standard GP model
        '''
        model_type = 'sparseGP'
        exact_feval = True
        created_model = self.arguments_manager.model_creator(
            model_type, exact_feval, self.space)
        self.assertTrue(isinstance(created_model, GPModel))
        self.assertEquals(created_model.optimize_restarts, 10)
        self.assertEquals(created_model.num_inducing, 15)

    def test_model_rf_arguments(self):
        '''
        Testing the arguments of the Random Forrest
        '''
        model_type = 'RF'
        exact_feval = True
        created_model = self.arguments_manager.model_creator(
            model_type, exact_feval, self.space)
        self.assertTrue(isinstance(created_model, RFModel))

    def test_model_inputwarpedgp_arguments(self):
        '''
        Testing the arguments of the input warped GP
        '''
        model_type = 'input_warped_GP'
        exact_feval = True
        created_model = self.arguments_manager.model_creator(
            model_type, exact_feval, self.space)
        self.assertTrue(isinstance(created_model, InputWarpedGPModel))

    def test_model_warpedgo_arguments(self):
        '''
        Testing the arguments of the warped GP
        '''
        model_type = 'warpedGP'
        exact_feval = True
        created_model = self.arguments_manager.model_creator(
            model_type, exact_feval, self.space)
        self.assertTrue(isinstance(created_model, WarpedGPModel))

    def test_acquisition_ei_arguments(self):
        '''
        Testing the arguments of the Expected Improvement
        '''
        acquisition_type = 'EI'
        created_acquisition = self.arguments_manager.acquisition_creator(
            acquisition_type, self.model, self.space,
            self.acquisition_optimizer, self.cost)
        self.assertTrue(isinstance(created_acquisition, AcquisitionEI))
        self.assertEquals(created_acquisition.jitter, 0.02)

    def test_acquisition_lcb_arguments(self):
        '''
        Testing the arguments of the Lower Confidence Bound
        '''
        acquisition_type = 'LCB'
        created_acquisition = self.arguments_manager.acquisition_creator(
            acquisition_type, self.model, self.space,
            self.acquisition_optimizer, self.cost)
        self.assertTrue(isinstance(created_acquisition, AcquisitionLCB))
        self.assertEquals(created_acquisition.exploration_weight, 2.5)

    def test_evaluator_arguments(self):
        '''
        Testing the arguments of the local_penalization evaluator
        '''
        evaluator_type = 'local_penalization'
        batch_size = 2
        model_type = 'GP'
        created_evaluator = self.arguments_manager.evaluator_creator(
            evaluator_type, self.acquisition, batch_size, model_type,
            self.model, self.space, self.acquisition_optimizer)
        self.assertTrue(isinstance(created_evaluator, LocalPenalization))
        self.assertEquals(created_evaluator.acquisition.transform, 'softplus')
    def __init__(self,
                 estimator,
                 domain=None,
                 constraints=None,
                 cost_withGradients=None,
                 model_type="GP",
                 X=None,
                 Y=None,
                 initial_design_numdata=5,
                 initial_design_type="random",
                 acquisition_type="EI",
                 normalize_Y=True,
                 exact_feval=False,
                 acquisition_optimizer_type="lbfgs",
                 model_update_interval=1,
                 evaluator_type="sequential",
                 batch_size=1,
                 num_cores=1,
                 verbosity_model=False,
                 verbosity=False,
                 de_duplication=False,
                 max_iter=50,
                 refit=True,
                 cv=None,
                 scoring=None,
                 n_jobs=1,
                 verbose=False,
                 **kwargs):
        """Initialise the estimator."""
        # super(BayesianOptimization, self).__init__(
        #     f=f, domain=domain, constraints=constraints,
        #     cost_withGradients=cost_withGradients, model_type=model_type,
        #     X=X, Y=Y, initial_design_numdata=initial_design_numdata,
        #     initial_design_type=initial_design_type,
        #     acquisition_type=acquisition_type, normalize_Y=normalize_Y,
        #     exact_feval=exact_feval,
        #     acquisition_optimizer_type=acquisition_optimizer_type,
        #     model_update_interval=model_update_interval,
        #     evaluator_type=evaluator_type, batch_size=batch_size,
        #     num_cores=num_cores,
        #     verbosity=verbosity, verbosity_model=verbosity_model,
        #     maximize=True, de_duplication=de_duplication, **kwargs)
        self.modular_optimization = False
        self.initial_iter = True
        self.verbosity = verbosity
        self.verbosity_model = verbosity_model
        self.model_update_interval = model_update_interval
        self.de_duplication = de_duplication
        self.kwargs = kwargs

        # --- Handle the arguments passed via kargs
        self.problem_config = ArgumentsManager(kwargs)

        # --- CHOOSE design space
        self.constraints = constraints
        self.domain = domain or {}
        self.space = Design_space(self.domain, self.constraints)

        # --- CHOOSE objective function
        self.objective_name = kwargs.get("objective_name", "") or "no_name"
        self.batch_size = batch_size
        self.num_cores = num_cores
        # self.maximize = True
        # self.objective = None

        # --- CHOOSE the cost model
        self.cost = CostModel(cost_withGradients)

        # --- CHOOSE initial design
        self.X = X  # parameters
        self.Y = Y  # evaluation
        self.initial_design_type = initial_design_type
        self.initial_design_numdata = initial_design_numdata

        # --- CHOOSE the model type. If an instance of a GPyOpt model is passed (possibly user defined), it is used.
        # note that this 2 options are not used with the predefined model
        self.model_type = model_type
        self.exact_feval = exact_feval
        self.normalize_Y = normalize_Y

        if "model" in self.kwargs and isinstance(kwargs["model"],
                                                 GPyOpt.models.base.BOModel):
            self.model = kwargs["model"]
            self.model_type = "User defined model used."
            if self.verbose:
                print("Using a model defined by the used.")
        else:
            self.model = self._model_chooser()

        # --- CHOOSE the acquisition optimizer_type
        # This states how the discrete variables are handled (exact search or rounding)
        self.acquisition_optimizer_type = acquisition_optimizer_type
        self.acquisition_optimizer = AcquisitionOptimizer(
            self.space, self.acquisition_optimizer_type, model=self.model)

        # --- CHOOSE acquisition function. If an instance of an acquisition is passed (possibly user defined), it is used.
        self.acquisition_type = acquisition_type
        if "acquisition" in self.kwargs and isinstance(
                kwargs["acquisition"], GPyOpt.acquisitions.AcquisitionBase):
            self.acquisition = kwargs["acquisition"]
            self.acquisition_type = "User defined acquisition used."
            if self.verbose:
                print("Using an acquisition defined by the used.")
        else:
            self.acquisition = self._acquisition_chooser()

        # --- CHOOSE evaluator method
        self.evaluator_type = evaluator_type
        self.evaluator = self._evaluator_chooser()

        # --- Create optimization space
        self.cost = CostModel(self.cost)
        self.normalization_type = "stats"  # not added in the API

        self.estimator = estimator
        self.cv = cv
        self.max_iter = max_iter
        self.refit = refit
        self.scoring = scoring
        self.verbose = verbose
        self.n_jobs = n_jobs
예제 #5
0
    def __init__(self,
                 fill_in_strategy,
                 f,
                 mix=0.5,
                 domain=None,
                 constraints=None,
                 cost_withGradients=None,
                 X=None,
                 Y=None,
                 subspace_dim_size=0,
                 model_type='GP',
                 initial_design_numdata=1,
                 initial_design_type='random',
                 acquisition_type='LCB',
                 normalize_Y=True,
                 exact_feval=False,
                 acquisition_optimizer_type='lbfgs',
                 model_update_interval=1,
                 evaluator_type='sequential',
                 batch_size=1,
                 maximize=False,
                 de_duplication=False):

        if model_type == 'input_warped_GP':
            raise NotImplementedError(
                'input_warped_GP model is not implemented')

        if acquisition_type in ['EI_MCMC', 'MPI_MCMC', 'LCB_MCMC']:
            raise NotImplementedError('MCMC is not implemented')

        if batch_size is not 1 or evaluator_type is not 'sequential':
            raise NotImplementedError(
                'only sequential evaluation is implemented')

        if fill_in_strategy not in ['random', 'copy', 'mix']:
            raise ValueError('fill_in_strategy has to be random, copy or mix')

        # private field
        self._arguments_mng = ArgumentsManager(kwargs=dict())

        self.fill_in_strategy = fill_in_strategy
        self.mix = mix
        self.subspace_dim_size = subspace_dim_size
        self.cost_withGradients = cost_withGradients
        self.initial_design_numdata = initial_design_numdata
        self.initial_design_type = initial_design_type
        self.model_type = model_type
        self.acquisition_type = acquisition_type
        self.evaluator_type = evaluator_type
        self.model_update_interval = model_update_interval
        self.maximize = maximize
        self.normalize_Y = normalize_Y
        self.de_duplication = de_duplication
        self.subspace_dim_size = subspace_dim_size

        # --- property injected in other methods.
        self.verbosity = False
        self.subspace_idx = None
        self.subspace = None
        self.max_time = None
        self.max_iter = None
        self.cum_time = None
        self.report_file = None
        self.evaluations_file = None
        self.models_file = None
        self.eps = None
        self.save_models_parameters = None
        # --- unnecessary property
        self.suggested_sample = None
        self.Y_new = None

        # --- BO class property in uncertain use
        self.num_cores = 1

        self.objective = SingleObjective(self._sign(f), batch_size,
                                         f.get_function_name())
        self.cost = CostModel(cost_withGradients=cost_withGradients)
        self.space = initialize_space(domain=domain, constraints=constraints)

        self.model = self._arguments_mng.model_creator(
            model_type=self.model_type,
            exact_feval=exact_feval,
            space=self.space)

        self.acquisition = self._arguments_mng.acquisition_creator(
            acquisition_type=self.acquisition_type,
            model=self.model,
            space=self.space,
            acquisition_optimizer=AcquisitionOptimizer(
                space=self.space, optimizer=acquisition_optimizer_type),
            cost_withGradients=self.cost_withGradients)

        self._choose_evaluator()

        self.X = X
        self.Y = Y
        self._set_initial_values()

        super().__init__(model=self.model,
                         space=self.space,
                         objective=self.objective,
                         acquisition=self.acquisition,
                         evaluator=self.evaluator,
                         X_init=self.X,
                         Y_init=self.Y,
                         cost=self.cost,
                         normalize_Y=self.normalize_Y,
                         model_update_interval=self.model_update_interval,
                         de_duplication=self.de_duplication)
예제 #6
0
class Dropout(BO):
    """

    Args:
        f (function): function to optimize.
        domain (list | None): the description of the inputs variables
            (See GpyOpt.core.space.Design_space class for details)
        constraints (list | None): the description of the problem constraints
            (See GpyOpt.core.space.Design_space class for details)


    Attributes:
        initial_design_numdata (int):
        initial_design_type (string):

        domain (dict | None):
        constraints (dict | None):
        space (Design_space):
        model (BOModel):
        acquisition (AcquisitionBase):
        cost (CostModel):
    """
    def __init__(self,
                 fill_in_strategy,
                 f,
                 mix=0.5,
                 domain=None,
                 constraints=None,
                 cost_withGradients=None,
                 X=None,
                 Y=None,
                 subspace_dim_size=0,
                 model_type='GP',
                 initial_design_numdata=1,
                 initial_design_type='random',
                 acquisition_type='LCB',
                 normalize_Y=True,
                 exact_feval=False,
                 acquisition_optimizer_type='lbfgs',
                 model_update_interval=1,
                 evaluator_type='sequential',
                 batch_size=1,
                 maximize=False,
                 de_duplication=False):

        if model_type == 'input_warped_GP':
            raise NotImplementedError(
                'input_warped_GP model is not implemented')

        if acquisition_type in ['EI_MCMC', 'MPI_MCMC', 'LCB_MCMC']:
            raise NotImplementedError('MCMC is not implemented')

        if batch_size is not 1 or evaluator_type is not 'sequential':
            raise NotImplementedError(
                'only sequential evaluation is implemented')

        if fill_in_strategy not in ['random', 'copy', 'mix']:
            raise ValueError('fill_in_strategy has to be random, copy or mix')

        # private field
        self._arguments_mng = ArgumentsManager(kwargs=dict())

        self.fill_in_strategy = fill_in_strategy
        self.mix = mix
        self.subspace_dim_size = subspace_dim_size
        self.cost_withGradients = cost_withGradients
        self.initial_design_numdata = initial_design_numdata
        self.initial_design_type = initial_design_type
        self.model_type = model_type
        self.acquisition_type = acquisition_type
        self.evaluator_type = evaluator_type
        self.model_update_interval = model_update_interval
        self.maximize = maximize
        self.normalize_Y = normalize_Y
        self.de_duplication = de_duplication
        self.subspace_dim_size = subspace_dim_size

        # --- property injected in other methods.
        self.verbosity = False
        self.subspace_idx = None
        self.subspace = None
        self.max_time = None
        self.max_iter = None
        self.cum_time = None
        self.report_file = None
        self.evaluations_file = None
        self.models_file = None
        self.eps = None
        self.save_models_parameters = None
        # --- unnecessary property
        self.suggested_sample = None
        self.Y_new = None

        # --- BO class property in uncertain use
        self.num_cores = 1

        self.objective = SingleObjective(self._sign(f), batch_size,
                                         f.get_function_name())
        self.cost = CostModel(cost_withGradients=cost_withGradients)
        self.space = initialize_space(domain=domain, constraints=constraints)

        self.model = self._arguments_mng.model_creator(
            model_type=self.model_type,
            exact_feval=exact_feval,
            space=self.space)

        self.acquisition = self._arguments_mng.acquisition_creator(
            acquisition_type=self.acquisition_type,
            model=self.model,
            space=self.space,
            acquisition_optimizer=AcquisitionOptimizer(
                space=self.space, optimizer=acquisition_optimizer_type),
            cost_withGradients=self.cost_withGradients)

        self._choose_evaluator()

        self.X = X
        self.Y = Y
        self._set_initial_values()

        super().__init__(model=self.model,
                         space=self.space,
                         objective=self.objective,
                         acquisition=self.acquisition,
                         evaluator=self.evaluator,
                         X_init=self.X,
                         Y_init=self.Y,
                         cost=self.cost,
                         normalize_Y=self.normalize_Y,
                         model_update_interval=self.model_update_interval,
                         de_duplication=self.de_duplication)

    @property
    def dimensionality(self):
        return self.space.objective_dimensionality

    @property
    def subspace_domain(self):
        return self.subspace.config_space

    @property
    def domain(self):
        return self.space.config_space

    @property
    def constraints(self):
        return self.space.constraints

    @property
    def f(self):
        return self.objective.func

    @property
    def cost_type(self):
        return self.cost.cost_withGradients

    @property
    def exact_feval(self):
        return self.model.exact_feval

    @property
    def acquisition_optimizer_type(self):
        return self.acquisition_optimizer.optimizer_name

    @property
    def acquisition_optimizer(self):
        return self.acquisition.optimizer

    @property
    def batch_size(self):
        return self.objective.n_procs

    @property
    def objective_name(self):
        return self.objective.objective_name

    def _choose_evaluator(self):
        self.evaluator = self._arguments_mng.evaluator_creator(
            evaluator_type=self.evaluator_type,
            acquisition=self.acquisition,
            batch_size=self.batch_size,
            model_type=self.model_type,
            model=self.model,
            space=self.space,
            acquisition_optimizer=self.acquisition_optimizer)

    def run_optimization(self,
                         max_iter=0,
                         max_time=np.inf,
                         eps=1e-8,
                         context=None,
                         verbosity=False,
                         save_models_parameters=True,
                         report_file=None,
                         evaluations_file=None,
                         models_file=None):

        if self.objective is None:
            raise ValueError(
                "Cannot run the optimization loop without the objective function"
            )

        # --- Save the options to print and save the results
        self.verbosity = verbosity
        self.save_models_parameters = save_models_parameters
        self.report_file = report_file
        self.evaluations_file = evaluations_file
        self.models_file = models_file
        self.model_parameters_iterations = None
        self.context = context

        # --- Check if we can save the model parameters in each iteration
        if self.save_models_parameters:
            if not (isinstance(self.model, GPModel)):
                print(
                    'Models printout after each iteration is only available for GP and GP_MCMC models'
                )
                self.save_models_parameters = False

                # --- Setting up stop conditions
            self.eps = eps
            if (max_iter is None) and (max_time is None):
                self.max_iter = 0
                self.max_time = np.inf
            elif (max_iter is None) and (max_time is not None):
                self.max_iter = np.inf
                self.max_time = max_time
            elif (max_iter is not None) and (max_time is None):
                self.max_iter = max_iter
                self.max_time = np.inf
            else:
                self.max_iter = max_iter
                self.max_time = max_time

        # --- Initialize iterations and running time
        stopwatch = StopWatch()
        self.num_acquisitions = self.initial_design_numdata
        self.suggested_sample = self.X
        self.Y_new = self.Y
        self._compute_results()

        self._run_optimization()

        self.cum_time = stopwatch.passed_time()

        # --- Stop messages and execution time
        self._compute_results()

        # --- Print the desired result in files
        if self.report_file is not None:
            self.save_report(self.report_file)
        if self.evaluations_file is not None:
            self.save_evaluations(self.evaluations_file)
        if self.models_file is not None:
            self.save_models(self.models_file)

        self._save()

    def _run_optimization(self):
        while True:
            print('.')

            # --- update model
            try:
                self.update()

            except np.linalg.LinAlgError:
                print('np.linalg.LinAlgError')
                break

            if self.num_acquisitions >= self.max_iter:
                break

            self.next_point()

            # --- Update current evaluation time and function evaluations
            self.num_acquisitions += 1

    def next_point(self):
        self.suggested_sample = self._compute_next_evaluations()

        # --- Augment X
        self.X = np.vstack((self.X, self.suggested_sample))

        # --- Evaluate *f* in X, augment Y and update cost function (if needed)
        self.evaluate_objective()

    def get_best_point(self):
        self._compute_results()
        return self.x_opt, self.fx_opt

    def update(self):
        self._update_model(self.normalization_type)
        self._update_acquisition()
        self._update_evaluator()

    def _dropout_random(self, embedded_idx):
        return initial_design(
            'random', get_subspace(space=self.space,
                                   subspace_idx=embedded_idx), 1)[0]

    def _dropout_copy(self, embedded_idx):
        x_opt, _ = self.get_best_point()
        return x_opt[embedded_idx]

    def _dropout_mix(self, embedded_idx):
        if np.random.rand() < self.mix:
            return self._dropout_random(embedded_idx=embedded_idx)
        else:
            return self._dropout_copy(embedded_idx=embedded_idx)

    def _sign(self, f):
        if self.maximize:
            f_copy = f

            def f(x):
                return -f_copy(x)

        return f

    def _set_initial_values(self):
        if self.X is None:
            self.X = initial_design(self.initial_design_type, self.space,
                                    self.initial_design_numdata)
            self.Y, _ = self.objective.evaluate(self.X)
        elif self.X is not None and self.Y is None:
            self.Y, _ = self.objective.evaluate(self.X)

        # save initial values
        self.initial_X = deepcopy(self.X)
        if self.maximize:
            self.initial_Y = -deepcopy(self.Y)
        else:
            self.initial_Y = deepcopy(self.Y)

    def _fill_in_strategy(self, embedded_idx):
        if self.fill_in_strategy == 'random':
            return self._dropout_random(embedded_idx=embedded_idx)
        elif self.fill_in_strategy == 'copy':
            return self._dropout_copy(embedded_idx=embedded_idx)
        elif self.fill_in_strategy == 'mix':
            return self._dropout_mix(embedded_idx=embedded_idx)

    def _fill_in_dimensions(self, samples):
        full_num = self.dimensionality
        subspace_idx = self.subspace_idx
        embedded_idx = [i for i in range(full_num) if i not in subspace_idx]

        samples_ = list()

        for sample in samples:

            if len(sample) > len(subspace_idx):
                raise ValueError(
                    'samples already have been full-dimensionality')

            embedded_sample = self._fill_in_strategy(embedded_idx=embedded_idx)

            sample_ = deepcopy(sample)
            for emb_idx, insert_idx in enumerate(embedded_idx):
                sample_ = np.insert(sample_, emb_idx, embedded_sample[emb_idx])

            samples_.append(sample_)

        return np.array(samples_)

    def _update_acquisition(self):
        self.acquisition = self._arguments_mng.acquisition_creator(
            acquisition_type=self.acquisition_type,
            model=self.model,
            space=self.subspace,
            acquisition_optimizer=AcquisitionOptimizer(
                space=self.subspace,
                optimizer=self.acquisition_optimizer_type),
            cost_withGradients=self.cost_withGradients)

    def _update_evaluator(self):
        self.evaluator.acquisition = self.acquisition

    def _update_model(self, normalization_type='stats'):
        if self.num_acquisitions % self.model_update_interval == 0:

            self.update_subspace()

            self.model = self._arguments_mng.model_creator(
                model_type=self.model_type,
                exact_feval=self.exact_feval,
                space=self.subspace)

            X_inmodel, Y_inmodel = self._input_data(
                normalization_type=normalization_type)

            self.model.updateModel(X_inmodel, Y_inmodel, None, None)
            self.X_inmodel = X_inmodel
            self.Y_inmodel = Y_inmodel

        # Save parameters of the model
        self._save_model_parameter_values()

    def _input_data(self, normalization_type):
        # input that goes into the model (is unziped in case there are categorical variables)
        X_inmodel = self.subspace.unzip_inputs(
            np.array([xi[self.subspace_idx] for xi in self.X]))

        # Y_inmodel is the output that goes into the model
        if self.normalize_Y:
            Y_inmodel = normalize(self.Y, normalization_type)
        else:
            Y_inmodel = self.Y

        return X_inmodel, Y_inmodel

    def update_subspace(self):
        self.subspace_idx = np.sort(
            np.random.choice(range(self.dimensionality),
                             self.subspace_dim_size,
                             replace=False))
        self.subspace = get_subspace(space=self.space,
                                     subspace_idx=self.subspace_idx)

    def _compute_next_evaluations(self,
                                  pending_zipped_X=None,
                                  ignored_zipped_X=None):
        context_manager, duplicate_manager = self._compute_setting(
            pending_zipped_X=pending_zipped_X,
            ignored_zipped_X=ignored_zipped_X)

        # We zip the value in case there are categorical variables
        suggested_ = self.subspace.zip_inputs(
            self.evaluator.compute_batch(duplicate_manager=duplicate_manager,
                                         context_manager=context_manager))

        return self._fill_in_dimensions(samples=suggested_)

    def _compute_setting(self, pending_zipped_X, ignored_zipped_X):
        context_manager = ContextManager(self.subspace, self.context)

        # --- Update the context if any
        self.acquisition.optimizer.context_manager = context_manager

        # --- Activate de_duplication
        if self.de_duplication:
            duplicate_manager = DuplicateManager(
                space=self.subspace,
                zipped_X=self.X,
                pending_zipped_X=pending_zipped_X,
                ignored_zipped_X=ignored_zipped_X)
        else:
            duplicate_manager = None

        return context_manager, duplicate_manager

    def _save(self):
        mkdir_when_not_exist(abs_path=definitions.ROOT_DIR + '/storage/' +
                             self.objective_name)

        dir_name = definitions.ROOT_DIR + '/storage/' + self.objective_name + '/' + now_str(
        ) + ' ' + str(self.dimensionality) + 'D ' + str(self.fill_in_strategy)
        mkdir_when_not_exist(abs_path=dir_name)

        self.save_report(report_file=dir_name + '/report.txt')
        self.save_evaluations(evaluations_file=dir_name + '/evaluation.csv')
        self.save_models(models_file=dir_name + '/model.csv')

    def save_report(self, report_file=None):
        with open(report_file, 'w') as file:
            import GPyOpt
            import time

            file.write('-----------------------------' +
                       ' GPyOpt Report file ' +
                       '-----------------------------------\n')
            file.write('GPyOpt Version ' + str(GPyOpt.__version__) + '\n')
            file.write('Date and time:               ' + time.strftime("%c") +
                       '\n')
            if self.num_acquisitions == self.max_iter:
                file.write('Optimization completed:      ' + 'YES, ' +
                           str(self.X.shape[0]).strip('[]') +
                           ' samples collected.\n')
                file.write('Number initial samples:      ' +
                           str(self.initial_design_numdata) + ' \n')
            else:
                file.write('Optimization completed:      ' + 'NO,' +
                           str(self.X.shape[0]).strip('[]') +
                           ' samples collected.\n')
                file.write('Number initial samples:      ' +
                           str(self.initial_design_numdata) + ' \n')

            file.write('Tolerance:                   ' + str(self.eps) + '.\n')
            file.write('Optimization time:           ' +
                       str(self.cum_time).strip('[]') + ' seconds.\n')

            file.write('\n')
            file.write('--------------------------------' +
                       ' Problem set up ' +
                       '------------------------------------\n')
            file.write('Problem name:                ' + self.objective_name +
                       '\n')
            file.write('Problem dimension:           ' +
                       str(self.dimensionality) + '\n')
            file.write('Number continuous variables  ' +
                       str(len(self.space.get_continuous_dims())) + '\n')
            file.write('Number discrete variables    ' +
                       str(len(self.space.get_discrete_dims())) + '\n')
            file.write('Number bandits               ' +
                       str(self.space.get_bandit().shape[0]) + '\n')
            file.write('Noiseless evaluations:       ' +
                       str(self.exact_feval) + '\n')
            file.write('Cost used:                   ' + self.cost.cost_type +
                       '\n')
            file.write('Constraints:                 ' +
                       str(self.constraints == True) + '\n')
            file.write('Subspace Dimension:          ' +
                       str(self.subspace_dim_size) + '\n')
            file.write('Fill in strategy:            ' +
                       str(self.fill_in_strategy) + '\n')

            file.write('\n')
            file.write('------------------------------' +
                       ' Optimization set up ' +
                       '---------------------------------\n')
            file.write('Normalized outputs:          ' +
                       str(self.normalize_Y) + '\n')
            file.write('Model type:                  ' +
                       str(self.model_type).strip('[]') + '\n')
            file.write('Model update interval:       ' +
                       str(self.model_update_interval) + '\n')
            file.write('Acquisition type:            ' +
                       str(self.acquisition_type).strip('[]') + '\n')
            file.write(
                'Acquisition optimizer:       ' +
                str(self.acquisition_optimizer.optimizer_name).strip('[]') +
                '\n')

            file.write('Acquisition type:            ' +
                       str(self.acquisition_type).strip('[]') + '\n')
            if hasattr(self, 'acquisition_optimizer') and hasattr(
                    self.acquisition_optimizer, 'optimizer_name'):
                file.write('Acquisition optimizer:       ' + str(
                    self.acquisition_optimizer.optimizer_name).strip('[]') +
                           '\n')
            else:
                file.write('Acquisition optimizer:       None\n')
            file.write('Evaluator type (batch size): ' +
                       str(self.evaluator_type).strip('[]') + ' (' +
                       str(self.batch_size) + ')' + '\n')
            file.write('Cores used:                  ' + str(self.num_cores) +
                       '\n')

            file.write('\n')
            file.write('---------------------------------' + ' Summary ' +
                       '------------------------------------------\n')
            file.write('Initial X:                       ' +
                       str(self.initial_X) + '\n')
            file.write('Initial Y:                       ' +
                       str(self.initial_Y) + '\n')

            if self.maximize:
                file.write('Value at maximum:            ' +
                           str(format(-min(self.Y)[0], '.20f')).strip('[]') +
                           '\n')
                file.write('Best found maximum location: ' +
                           str(self.X[np.argmin(self.Y), :]).strip('[]') +
                           '\n')
            else:
                file.write('Value at minimum:            ' +
                           str(format(min(self.Y)[0], '.20f')).strip('[]') +
                           '\n')
                file.write('Best found minimum location: ' +
                           str(self.X[np.argmin(self.Y), :]).strip('[]') +
                           '\n')

            file.write(
                '----------------------------------------------------------------------------------------------\n'
            )
            file.close()
예제 #7
0
class TestArgumentsManager(unittest.TestCase):
    '''
    The test just checks that the arguments are passed and handled, not that the model
    or the acquisition does the right thing with them.
    '''
    def setUp(self):
        kwargs  = {'n_samples':1000,
                    'n_burnin':100,
                    'subsample_interval':5,
                    'step_size': 1e-1,
                    'leapfrog_steps':20,
                    'optimize_restarts':10,
                    'num_inducing':15,
                    'acquisition_transformation':'softplus',
                    'acquisition_jitter':0.02,
                    'acquisition_weight':2.5,
                    'acquisition_transformation':'softplus'
                    }

        ## --- Defaults for some of the tests
        self.space = Design_space(space =[{'name': 'var1', 'type': 'continuous', 'domain': (-10,10),'dimensionality': 2}])
        self.cost = CostModel(None)
        self.arguments_manager = ArgumentsManager(kwargs)
        self.model = self.arguments_manager.model_creator(model_type = 'GP', exact_feval= True, space = self.space)
        self.acquisition_optimizer = AcquisitionOptimizer(self.space)
        self.acquisition = self.arguments_manager.acquisition_creator('EI', self.model, self.space, self.acquisition_optimizer, self.cost)


    def test_model_gp_mcmc_arguments(self):
        '''
        Testing the arguments of the GP model with MCMC
        '''
        model_type = 'GP_MCMC'
        exact_feval = True
        created_model = self.arguments_manager.model_creator(model_type, exact_feval, self.space)
        self.assertTrue(isinstance(created_model, GPModel_MCMC))
        self.assertEquals(created_model.n_samples, 1000)
        self.assertEquals(created_model.n_burnin, 100)
        self.assertEquals(created_model.subsample_interval, 5)
        self.assertEquals(created_model.step_size, 1e-1)
        self.assertEquals(created_model.leapfrog_steps, 20)

    def test_model_sparse_gp_arguments(self):
        '''
        Testing the arguments of the standard GP model
        '''
        model_type = 'sparseGP'
        exact_feval = True
        created_model = self.arguments_manager.model_creator(model_type, exact_feval, self.space)
        self.assertTrue(isinstance(created_model, GPModel))
        self.assertEquals(created_model.optimize_restarts,10)
        self.assertEquals(created_model.num_inducing,15)

    def test_model_rf_arguments(self):
        '''
        Testing the arguments of the Random Forrest
        '''
        model_type = 'RF'
        exact_feval = True
        created_model = self.arguments_manager.model_creator(model_type, exact_feval, self.space)
        self.assertTrue(isinstance(created_model, RFModel))

    def test_model_inputwarpedgp_arguments(self):
        '''
        Testing the arguments of the input warped GP
        '''
        model_type = 'input_warped_GP'
        exact_feval = True
        created_model = self.arguments_manager.model_creator(model_type, exact_feval, self.space)
        self.assertTrue(isinstance(created_model, InputWarpedGPModel))

    def test_model_warpedgo_arguments(self):
        '''
        Testing the arguments of the warped GP
        '''
        model_type = 'warpedGP'
        exact_feval = True
        created_model = self.arguments_manager.model_creator(model_type, exact_feval, self.space)
        self.assertTrue(isinstance(created_model, WarpedGPModel))

    def test_acquisition_ei_arguments(self):
        '''
        Testing the arguments of the Expected Improvement
        '''
        acquisition_type = 'EI'
        created_acquisition = self.arguments_manager.acquisition_creator(acquisition_type, self.model, self.space, self.acquisition_optimizer, self.cost)
        self.assertTrue(isinstance(created_acquisition, AcquisitionEI))
        self.assertEquals(created_acquisition.jitter,0.02)

    def test_acquisition_lcb_arguments(self):
        '''
        Testing the arguments of the Lower Confidence Bound
        '''
        acquisition_type = 'LCB'
        created_acquisition = self.arguments_manager.acquisition_creator(acquisition_type, self.model, self.space, self.acquisition_optimizer, self.cost)
        self.assertTrue(isinstance(created_acquisition, AcquisitionLCB))
        self.assertEquals(created_acquisition.exploration_weight,2.5)

    def test_evaluator_arguments(self):
        '''
        Testing the arguments of the local_penalization evaluator
        '''
        evaluator_type = 'local_penalization'
        batch_size = 2
        model_type = 'GP'
        created_evaluator = self.arguments_manager.evaluator_creator(evaluator_type, self.acquisition, batch_size, model_type, self.model, self.space, self.acquisition_optimizer)
        self.assertTrue(isinstance(created_evaluator, LocalPenalization))
        self.assertEquals(created_evaluator.acquisition.transform,'softplus')
예제 #8
0
    def __init__(self,
                 domain=None,
                 constraints=None,
                 cost_withGradients=None,
                 model_type='GP',
                 X=None,
                 Y=None,
                 initial_design_numdata=7,
                 initial_design_type='random',
                 acquisition_type='EI',
                 normalize_Y=True,
                 exact_feval=False,
                 acquisition_optimizer_type='lbfgs',
                 model_update_interval=1,
                 evaluator_type='sequential',
                 batch_size=1,
                 num_cores=1,
                 verbosity=False,
                 verbosity_model=False,
                 maximize=False,
                 de_duplication=False,
                 **kwargs):

        self.modular_optimization = False
        self.initial_iter = True
        self.verbosity = verbosity
        self.verbosity_model = verbosity_model
        self.model_update_interval = model_update_interval
        self.de_duplication = de_duplication
        self.kwargs = kwargs

        # --- Handle the arguments passed via kargs
        self.problem_config = ArgumentsManager(kwargs)

        # --- CHOOSE design space
        self.constraints = constraints
        self.domain = domain
        self.space = Design_space(self.domain, self.constraints)

        # --- CHOOSE objective function
        self.maximize = maximize
        self.batch_size = batch_size
        self.num_cores = num_cores

        # --- CHOOSE the cost model
        self.cost = CostModel(cost_withGradients)

        # --- CHOOSE initial design
        self.X = X
        self.Y = Y
        self.initial_design_type = initial_design_type
        self.initial_design_numdata = initial_design_numdata

        # --- CHOOSE the model type. If an instance of a GPyOpt model is passed (possibly user defined), it is used.
        self.model_type = model_type
        self.exact_feval = exact_feval  # note that this 2 options are not used with the predefined model
        self.normalize_Y = normalize_Y
        self.model = self._model_chooser()

        # --- CHOOSE the acquisition optimizer_type
        # This states how the discrete variables are handled (exact search or rounding)
        self.acquisition_optimizer_type = acquisition_optimizer_type
        self.acquisition_optimizer = AcquisitionOptimizer(
            self.space, self.acquisition_optimizer_type,
            model=self.model)  ## more arguments may come here

        # --- CHOOSE acquisition function. If an instance of an acquisition is passed (possibly user defined), it is used.
        self.acquisition_type = acquisition_type
        self.acquisition = self.acquisition = self._acquisition_chooser()

        # --- CHOOSE evaluator method
        self.evaluator_type = evaluator_type
        self.evaluator = self._evaluator_chooser()

        # --- Create optimization space
        super(RosBayesianOptimization, self).__init__(
            model=self.model,
            space=self.space,
            acquisition=self.acquisition,
            evaluator=self.evaluator,
            X_init=self.X,
            Y_init=self.Y,
            cost=self.cost,
            normalize_Y=self.normalize_Y,
            model_update_interval=self.model_update_interval,
            de_duplication=self.de_duplication,
            initial_design_numdata=self.initial_design_numdata)
예제 #9
0
class RosBayesianOptimization(RosBO):
    """
    Main class to initialize a Bayesian Optimization method.
    :param f: function to optimize. It should take 2-dimensional numpy arrays as input and return 2-dimensional outputs (one evaluation per row).
    :param domain: list of dictionaries containing the description of the inputs variables (See GPyOpt.core.space.Design_space class for details).
    :param constraints: list of dictionaries containing the description of the problem constraints (See GPyOpt.core.space.Design_space class for details).
    :cost_withGradients: cost function of the objective. The input can be:
        - a function that returns the cost and the derivatives and any set of points in the domain.
        - 'evaluation_time': a Gaussian process (mean) is used to handle the evaluation cost.
    :model_type: type of model to use as surrogate:
        - 'GP', standard Gaussian process.
        - 'GP_MCMC',  Gaussian process with prior in the hyper-parameters.
        - 'sparseGP', sparse Gaussian process.
        - 'warperdGP', warped Gaussian process.
        - 'InputWarpedGP', input warped Gaussian process
        - 'RF', random forest (scikit-learn).
    :param X: 2d numpy array containing the initial inputs (one per row) of the model.
    :param Y: 2d numpy array containing the initial outputs (one per row) of the model.
    :initial_design_numdata: number of initial points that are collected jointly before start running the optimization.
    :initial_design_type: type of initial design:
        - 'random', to collect points in random locations.
        - 'latin', to collect points in a Latin hypercube (discrete variables are sampled randomly.)
    :acquisition_type: type of acquisition function to use.
        - 'EI', expected improvement.
        - 'EI_MCMC', integrated expected improvement (requires GP_MCMC model).
        - 'MPI', maximum probability of improvement.
        - 'MPI_MCMC', maximum probability of improvement (requires GP_MCMC model).
        - 'LCB', GP-Lower confidence bound.
        - 'LCB_MCMC', integrated GP-Lower confidence bound (requires GP_MCMC model).
    :param normalize_Y: whether to normalize the outputs before performing any optimization (default, True).
    :exact_feval: whether the outputs are exact (default, False).
    :acquisition_optimizer_type: type of acquisition function to use.
        - 'lbfgs': L-BFGS.
        - 'DIRECT': Dividing Rectangles.
        - 'CMA': covariance matrix adaptation.
    :param model_update_interval: interval of collected observations after which the model is updated (default, 1).
    :param evaluator_type: determines the way the objective is evaluated (all methods are equivalent if the batch size is one)
        - 'sequential', sequential evaluations.
        - 'random': synchronous batch that selects the first element as in a sequential policy and the rest randomly.
        - 'local_penalization': batch method proposed in (Gonzalez et al. 2016).
        - 'thompson_sampling': batch method using Thompson sampling.
    :param batch_size: size of the batch in which the objective is evaluated (default, 1).
    :param num_cores: number of cores used to evaluate the objective (default, 1).
    :param verbosity: prints the models and other options during the optimization (default, False).
    :param maximize: when True -f maximization of f is done by minimizing -f (default, False).
    :param **kwargs: extra parameters. Can be used to tune the current optimization setup or to use deprecated options in this package release.


    .. Note::   The parameters bounds, kernel, numdata_initial_design, type_initial_design, model_optimize_interval, acquisition, acquisition_par
                model_optimize_restarts, sparseGP, num_inducing and normalize can still be used but will be deprecated in the next version.
    """
    def __init__(self,
                 domain=None,
                 constraints=None,
                 cost_withGradients=None,
                 model_type='GP',
                 X=None,
                 Y=None,
                 initial_design_numdata=7,
                 initial_design_type='random',
                 acquisition_type='EI',
                 normalize_Y=True,
                 exact_feval=False,
                 acquisition_optimizer_type='lbfgs',
                 model_update_interval=1,
                 evaluator_type='sequential',
                 batch_size=1,
                 num_cores=1,
                 verbosity=False,
                 verbosity_model=False,
                 maximize=False,
                 de_duplication=False,
                 **kwargs):

        self.modular_optimization = False
        self.initial_iter = True
        self.verbosity = verbosity
        self.verbosity_model = verbosity_model
        self.model_update_interval = model_update_interval
        self.de_duplication = de_duplication
        self.kwargs = kwargs

        # --- Handle the arguments passed via kargs
        self.problem_config = ArgumentsManager(kwargs)

        # --- CHOOSE design space
        self.constraints = constraints
        self.domain = domain
        self.space = Design_space(self.domain, self.constraints)

        # --- CHOOSE objective function
        self.maximize = maximize
        self.batch_size = batch_size
        self.num_cores = num_cores

        # --- CHOOSE the cost model
        self.cost = CostModel(cost_withGradients)

        # --- CHOOSE initial design
        self.X = X
        self.Y = Y
        self.initial_design_type = initial_design_type
        self.initial_design_numdata = initial_design_numdata

        # --- CHOOSE the model type. If an instance of a GPyOpt model is passed (possibly user defined), it is used.
        self.model_type = model_type
        self.exact_feval = exact_feval  # note that this 2 options are not used with the predefined model
        self.normalize_Y = normalize_Y
        self.model = self._model_chooser()

        # --- CHOOSE the acquisition optimizer_type
        # This states how the discrete variables are handled (exact search or rounding)
        self.acquisition_optimizer_type = acquisition_optimizer_type
        self.acquisition_optimizer = AcquisitionOptimizer(
            self.space, self.acquisition_optimizer_type,
            model=self.model)  ## more arguments may come here

        # --- CHOOSE acquisition function. If an instance of an acquisition is passed (possibly user defined), it is used.
        self.acquisition_type = acquisition_type
        self.acquisition = self.acquisition = self._acquisition_chooser()

        # --- CHOOSE evaluator method
        self.evaluator_type = evaluator_type
        self.evaluator = self._evaluator_chooser()

        # --- Create optimization space
        super(RosBayesianOptimization, self).__init__(
            model=self.model,
            space=self.space,
            acquisition=self.acquisition,
            evaluator=self.evaluator,
            X_init=self.X,
            Y_init=self.Y,
            cost=self.cost,
            normalize_Y=self.normalize_Y,
            model_update_interval=self.model_update_interval,
            de_duplication=self.de_duplication,
            initial_design_numdata=self.initial_design_numdata)

    def _model_chooser(self):
        return self.problem_config.model_creator(self.model_type,
                                                 self.exact_feval, self.space)

    def _acquisition_chooser(self):
        return self.problem_config.acquisition_creator(
            self.acquisition_type, self.model, self.space,
            self.acquisition_optimizer, self.cost.cost_withGradients)

    def _evaluator_chooser(self):
        return self.problem_config.evaluator_creator(
            self.evaluator_type, self.acquisition, self.batch_size,
            self.model_type, self.model, self.space,
            self.acquisition_optimizer)