mirror of
https://github.com/wassname/pyrobolearn.git
synced 2026-09-22 13:30:55 +08:00
142 lines
5.9 KiB
Python
142 lines
5.9 KiB
Python
#!/usr/bin/env python
|
|
"""Provide a wrapper around the GPyOpt optimizers for Bayesian Optimization (BO).
|
|
|
|
References:
|
|
[1] https://sheffieldml.github.io/GPyOpt/
|
|
"""
|
|
|
|
import time
|
|
import numpy as np
|
|
|
|
# Bayesian optimization
|
|
try:
|
|
import GPy
|
|
import GPyOpt
|
|
except ImportError as e:
|
|
raise ImportError(e.__str__() + "\n HINT: you can install GPy/GPyOpt directly via 'pip install GPy' and "
|
|
"'pip install GPyOpt'.")
|
|
|
|
from pyrobolearn.optimizers import Optimizer
|
|
|
|
|
|
__author__ = "Brian Delhaisse"
|
|
__copyright__ = "Copyright 2018, PyRoboLearn"
|
|
__credits__ = ["Brian Delhaisse"]
|
|
__license__ = "GNU GPLv3"
|
|
__version__ = "1.0.0"
|
|
__maintainer__ = "Brian Delhaisse"
|
|
__email__ = "briandelhaisse@gmail.com"
|
|
__status__ = "Development"
|
|
|
|
|
|
class BayesianOptimizer(Optimizer):
|
|
r"""Bayesian Optimization
|
|
|
|
Bayesian Optimization is a global (gradient-free), probabilistic, non-parametric, model-based, optimization of
|
|
black-box functions.
|
|
|
|
Bayesian optimization can be formulated as an optimization problem:
|
|
|
|
.. math:: \theta^* = arg\,max_{\theta} f(\theta)
|
|
|
|
where :math:`\theta` are the parameters of the model we are trying to optimize, and :math:`f` is the unknown
|
|
objective function which is modeled using a probabilistic model such as a Gaussian Process (GP). By samp
|
|
|
|
Popular acquisition functions which specify which parameters to test next by making a trade-off between
|
|
exploitation and exploration, include:
|
|
* Probability of Improvement (PI) [7]:
|
|
* Expected Improvement (EI) [8]:
|
|
* Upper Confidence Bound (UCB) [9]:
|
|
|
|
Pseudo-Algo (from [3]):
|
|
D <-- if available: {\theta, f(\theta)}
|
|
Prior <-- if available: prior of the response surface
|
|
while optimize:
|
|
train a response surface from D
|
|
|
|
References:
|
|
[1] "Bayesian Approach to Global Optimization: Theory and Applications", Mockus, 1989
|
|
[2] "A Tutorial on Bayesian Optimization of Expensive Cost Functions, with Application to Active User Modeling
|
|
and Hierarchical Reinforcement Learning", Brochu et al., 2010
|
|
[3] "Taking the Human Out of the Loop: a Review of Bayesian Optimization", Shahriari et al., 2016
|
|
[4] "Bayesian Optimization for Learning Gaits under Uncertainty: An Experimental Comparison on a Dynamic
|
|
Bipedal Walker", Calandra et al., 2015
|
|
[5] "Gaussian Processes for Machine Learning", Rasmussen and Williams, 2006
|
|
[6] "GPyOpt: A Bayesian Optimization framework in python" (2016), https://github.com/SheffieldML/GPyOpt
|
|
[7] "A New Method of Locating the Maximum Point of an Arbitrary Multipeak Curve in the Presence of Noise",
|
|
Kushner, 1964
|
|
[8] "The Application of Bayesian Methods for Seeking the Extremum", Mockus et al., 1978
|
|
[9] "A Statistical Method for Global Optimization", Cox et al., 1997
|
|
"""
|
|
|
|
def __init__(self, num_workers=1, *args, **kwargs):
|
|
"""
|
|
Initialize the Bayesian optimizer.
|
|
"""
|
|
super(BayesianOptimizer, self).__init__(*args, **kwargs)
|
|
self.num_workers = num_workers
|
|
|
|
###########
|
|
# Methods #
|
|
###########
|
|
|
|
def optimize(self, parameters, loss, max_iters=1, verbose=False, *args, **kwargs):
|
|
"""
|
|
Optimize the given loss function with respect to the given parameters.
|
|
|
|
Args:
|
|
parameters: parameters.
|
|
loss: callable objective / loss function to minimize.
|
|
max_iters (int): number of maximum iterations.
|
|
verbose (bool): if True, it will display information during the optimization process.
|
|
*args: list of arguments to give to the loss function if callable.
|
|
**kwargs: dictionary of arguments to give to the loss function if callable.
|
|
|
|
Returns:
|
|
float, torch.Tensor, np.array: loss scalar value.
|
|
object: best parameters
|
|
"""
|
|
# define domain
|
|
# domain = [{'name': 'params', 'type': 'continuous', 'domain': self.domain, 'dimensionality': len(parameters)}]
|
|
|
|
# Solve the optimization
|
|
self.optimizer = GPyOpt.methods.BayesianOptimization(f=loss,
|
|
# domain=domain,
|
|
# constraints=constraints,
|
|
model_type='GP', # 'sparseGP'
|
|
acquisition_type='EI', # 'UCB'/'LCB', 'EI', 'MPI'
|
|
acquisition_optimizer_type='lbfgs', # 'DIRECT', 'CMA'
|
|
num_cores=self.num_workers,
|
|
verbosity=verbose,
|
|
maximize=self.is_maximizing,
|
|
verbosity_model=False, # True
|
|
kernel=GPy.kern.RBF(input_dim=1))
|
|
|
|
# print(opt.model.kernel.name)
|
|
|
|
# Run the optimization
|
|
max_iter = max_iters if max_iters < 5 else max_iters - 5 # evaluation budget (min=5)
|
|
# max_time = max_time # time budget
|
|
eps = 1.e-6 # Minimum allows distance between the last two observations
|
|
|
|
if verbose:
|
|
print('Optimizing...')
|
|
|
|
# optimize
|
|
start = time.time()
|
|
self.optimizer.run_optimization(max_iter, max_time, eps)
|
|
end = time.time()
|
|
|
|
if verbose:
|
|
print('Done with total time: {}'.format(end - start))
|
|
|
|
# save best parameters and reward
|
|
self.best_parameters = self.optimizer.x_opt
|
|
self.best_result = self.optimizer.fx_opt
|
|
|
|
# print best reward
|
|
if verbose:
|
|
print("\nBest loss value found: {}".format(self.best_result))
|
|
|
|
return self.best_result, self.best_parameters
|