Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
5e5aadf
refactor
AntKirill Apr 8, 2022
7b31527
add a check on the feasibility of the inverse point
AntKirill Apr 8, 2022
6acfdbc
fix bug with the same initial solution for every acq function optimiz…
AntKirill Apr 9, 2022
96b766d
add consideration of local optimums of acq function
AntKirill Apr 9, 2022
b1aca9c
refactor
AntKirill Apr 9, 2022
0a94c81
add smart rule to refit the kernel
AntKirill Apr 9, 2022
8964822
add test on ordered container
AntKirill Apr 9, 2022
72fbcf0
add more strategies to optimize kernel parameter
AntKirill Apr 9, 2022
5cb80a2
refactor
AntKirill Apr 9, 2022
8d93781
fix test
AntKirill Apr 9, 2022
1932ff5
maybe better
AntKirill Apr 9, 2022
14618f8
maybe better
AntKirill Apr 9, 2022
5e9c87e
run_local_experiment.py
AntKirill Apr 9, 2022
2ffb5a7
add time logging of stages
AntKirill Apr 10, 2022
673e32a
update configuration for BO
AntKirill Apr 11, 2022
e9af5ce
change acq optimizer
AntKirill Apr 11, 2022
bee853f
updates
AntKirill Apr 11, 2022
03d27d7
update
AntKirill Apr 11, 2022
dfaf013
add verbose
AntKirill Apr 11, 2022
fbee4a5
erase matplotlib
AntKirill Apr 11, 2022
fbcb239
update
AntKirill Apr 11, 2022
ee9ef60
add MariaLauras BO
AntKirill Apr 11, 2022
0fab1c6
add random seed
AntKirill Apr 11, 2022
a434b36
change max size array
AntKirill Apr 11, 2022
66faf51
fix the GPR model
wangronin Apr 12, 2022
10fa998
remove breakpoint
AntKirill Apr 12, 2022
1192509
change BO in single experiment
AntKirill Apr 12, 2022
99fc746
fix
AntKirill Apr 12, 2022
0b2b25a
update
wangronin Apr 12, 2022
6fcdb1d
update
wangronin Apr 12, 2022
df3eb27
update
wangronin Apr 12, 2022
0e19976
update
wangronin Apr 12, 2022
2e3ad65
refactor
AntKirill Apr 12, 2022
28c5a94
modefy the liner-pcabo and kernel-pcabo
AntKirill Apr 12, 2022
29d163d
refactor
AntKirill Apr 12, 2022
36fd794
update kernelpcabo
AntKirill Apr 12, 2022
9acb093
changes for linear-pcabo
AntKirill Apr 12, 2022
770ff2f
update kpca
AntKirill Apr 15, 2022
d48fcb0
fix centring
AntKirill Apr 15, 2022
fcec22f
change total_budget
AntKirill Apr 15, 2022
840de03
remove verbose
AntKirill Apr 15, 2022
07c6891
change budget for 40D
AntKirill Apr 16, 2022
6d7a0f3
add pycma
AntKirill Apr 17, 2022
7851d36
pick bad point for cma
AntKirill Apr 17, 2022
21b7ea5
add logging of meta information on every iteration
AntKirill Apr 26, 2022
e6b6f07
add logging of doe to stdout
AntKirill Apr 26, 2022
bbe71b4
add initialization of the initial solution for CMAES as the best poin…
AntKirill May 2, 2022
2b5cbc5
add instance id
AntKirill May 2, 2022
b44f45a
update for CMA-ES
AntKirill May 3, 2022
423e3b2
add charts builing and lower the doe_size
AntKirill May 5, 2022
fa231e6
change mode
AntKirill May 6, 2022
85d4626
remove graphical
AntKirill May 6, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions bayes_optim/acquisition/acquisition_fun.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
from typing import Tuple, Union

import numpy as np
from bayes_optim.mylogging import eprintf
from numpy import exp, sqrt
from scipy.stats import norm
from bayes_optim.mylogging import eprintf

from ..surrogate import GaussianProcess, RandomForest

Expand Down Expand Up @@ -156,34 +156,44 @@ def __call__(
) -> Union[np.ndarray, Tuple[np.ndarray, np.ndarray]]:
X = self.check_X(X)
n_sample = X.shape[0]
y_hat, sd = self._predict(X)
xi = 0.0

if return_dx:
mu, std, mu_grad, std_grad = self._model.predict(
X, return_std=True, return_mean_grad=True, return_std_grad=True
)
else:
mu, std = self._model.predict(X, return_std=True)
# if the Kriging variance is to small
# TODO: check the rationale of 1e-6 and why the ratio if intended
if hasattr(self._model, "sigma2"):
if sd / np.sqrt(self._model.sigma2) < 1e-6:
if std / np.sqrt(self._model.sigma2) < 1e-6:
return (0, np.zeros((len(X[0]), 1))) if return_dx else 0
else:
# TODO: implement a counterpart of 'sigma2' for randomforest
# or simply put a try...except around the code below
if sd < 1e-10:
if std < 1e-10:
return (0, np.zeros((len(X[0]), 1))) if return_dx else 0
try:
xcr_ = self.plugin - y_hat
xcr = xcr_ / sd
xcr_prob, xcr_dens = norm.cdf(xcr), norm.pdf(xcr)
value = xcr_ * xcr_prob + sd * xcr_dens
impr = self.plugin - xi - mu
xcr = impr / std
cdf, pdf = norm.cdf(xcr), norm.pdf(xcr)
value = impr * cdf + std * pdf
if n_sample == 1:
value = sum(value)
except Exception: # in case of numerical errors
# IMPORTANT: always keep the output in the same type
value = 0

if return_dx:
y_dx, sd2_dx = self._gradient(X)
sd_dx = sd2_dx / (2.0 * sd)
try:
dx = -y_dx * xcr_prob + sd_dx * xcr_dens
improve_grad = -mu_grad * std - std_grad * impr
improve_grad /= std**2
cdf_grad = improve_grad * pdf
pdf_grad = -impr * cdf_grad
exploit_grad = -mu_grad * cdf - pdf_grad
explore_grad = std_grad * pdf + pdf_grad
dx = exploit_grad + explore_grad
except Exception:
dx = np.zeros((len(X[0]), 1))
return value, dx
Expand Down
38 changes: 30 additions & 8 deletions bayes_optim/acquisition/optim/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
import time
from abc import ABC, abstractmethod
from typing import Callable, List, Tuple

import numpy as np
Expand All @@ -19,6 +20,7 @@
"default_AQ_max_FEs",
"default_AQ_n_restart",
"default_AQ_wait_iter",
"OptimizationListener",
]


Expand Down Expand Up @@ -52,16 +54,24 @@ def __call__(self, x: np.ndarray) -> Tuple[float, np.ndarray]:
return f, fg


class OptimizationListener(ABC):
@abstractmethod
def on_optimum_found(self, fopt, xopt):
pass


def argmax_restart(
obj_func: Callable,
search_space,
obj_func_: Callable = None,
h: Callable = None,
g: Callable = None,
eval_budget: int = 100,
n_restart: int = 10,
wait_iter: int = 3,
optimizer: str = "BFGS",
logger: logging.Logger = None,
listener: OptimizationListener = None,
):
# lists of the best solutions and acquisition values from each restart
xopt, fopt = [], []
Expand All @@ -71,16 +81,25 @@ def argmax_restart(
optimizer = "MIES"
logger.warning("L-BFGS-B can only be applied on continuous search space")

X = search_space.sample(int(2e2 * search_space.dim), method="uniform")
if obj_func_ is not None:
af_value = [obj_func_(x) for x in X]
else:
af_value = [obj_func(x)[0] for x in X]

idx = np.argsort(af_value)[::-1]
X = X[idx, :]

for iteration in range(n_restart):
x0 = search_space.sample(N=1, method="uniform")[0]
x0 = X[iteration]
if optimizer == "BFGS":
bounds = np.array(search_space.bounds)
# TODO: this is still subject to testing
xopt_, fopt_, stop_dict = fmin_l_bfgs_b(
Penalized(obj_func, h, g),
x0,
pgtol=1e-8,
factr=1e6,
factr=1e5,
approx_grad=False,
bounds=bounds,
maxfun=eval_budget,
)
Expand All @@ -90,7 +109,7 @@ def argmax_restart(
fopt_ = -fopt_

if logger is not None and stop_dict["warnflag"] != 0:
logger.debug("L-BFGS-B terminated abnormally with the state: %s" % stop_dict)
logger.info("L-BFGS-B terminated abnormally with the state: %s" % stop_dict)

elif optimizer == "OnePlusOne_Cholesky_CMA":
opt = OnePlusOne_Cholesky_CMA(
Expand Down Expand Up @@ -132,9 +151,8 @@ def argmax_restart(
wait_count = 0

if logger is not None:
logger.debug(
"restart : %d - funcalls : %d - Fopt : %f"
% (iteration + 1, stop_dict["funcalls"], fopt_)
logger.info(
f"restart : {iteration + 1} - funcalls : {stop_dict['funcalls']} - Fopt : {fopt_:.8e}"
)
else:
wait_count += 1
Expand All @@ -143,7 +161,11 @@ def argmax_restart(
xopt.append(xopt_)
fopt.append(fopt_)

if eval_budget <= 0 or wait_count >= wait_iter:
if listener is not None:
listener.on_optimum_found(fopt_, xopt_)

if eval_budget <= 0:
# or wait_count >= wait_iter:
break

if len(xopt) == 0:
Expand Down
5 changes: 4 additions & 1 deletion bayes_optim/acquisition/optim/one_plus_one_cma_es.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

from ...search_space import RealSpace, SearchSpace
from ...utils import dynamic_penalty, get_logger, handle_box_constraint, set_bounds
from bayes_optim.mylogging import eprintf
import random

Vector = List[float]
Matrix = List[Vector]
Expand Down Expand Up @@ -182,6 +184,7 @@ def random_seed(self, seed):
self._random_seed = int(seed)
if self._random_seed:
np.random.seed(self._random_seed)
random.seed(self._random_seed)

@property
def C(self):
Expand Down Expand Up @@ -213,7 +216,7 @@ def x(self, x):
else:
# sample `x` u.a.r. in `[lb, ub]`
assert all(~np.isinf(self.lb)) & all(~np.isinf(self.ub))
x = (self.ub - self.lb) * np.random.rand(self.dim) + self.lb
x = np.array([random.uniform(self.lb[i], self.ub[i]) for i in range(self.dim)])

self._x = x
y = self.evaluate(x)
Expand Down
4 changes: 2 additions & 2 deletions bayes_optim/acquisition/optim/option.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"MIES": lambda dim: int(1e3 * dim),
"BFGS": lambda dim: int(1e2 * dim),
"OnePlusOne_Cholesky_CMA": lambda dim: int(1e3 * dim),
"DE": lambda dim: int(1e3 * dim)
"DE": lambda dim: int(1e3 * dim),
}

default_AQ_n_restart: Callable = lambda dim: int(5 * dim)
default_AQ_n_restart: Callable = lambda dim: max(5, int(dim / 2))
default_AQ_wait_iter: int = 3
Loading