Skip to content

Commit f4b3393

Browse files
authored
Merge pull request jungtaekkim#20 from jungtaekkim/0.4.2
0.4.2
2 parents 741eba7 + 5e8bc6c commit f4b3393

File tree

87 files changed

+2742
-1578
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+2742
-1578
lines changed

.readthedocs.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
version: 2
2+
3+
sphinx:
4+
builder: html
5+
configuration: docs/conf.py
6+
7+
formats:
8+
- pdf
9+
- htmlzip
10+
11+
python:
12+
version: 3.7
13+
install:
14+
- requirements: requirements.txt
15+
- requirements: requirements-optional.txt

.travis.yml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
language: python
22
dist: xenial
33
python:
4-
- "2.7"
5-
- "3.5"
6-
- "3.6"
7-
- "3.7"
4+
- '2.7'
5+
- '3.6'
6+
- '3.7'
7+
- '3.8'
88
install:
99
- pip install .
10+
- pip install tensorflow
11+
- pip install tensorflow-probability
12+
- pip install torch
13+
- pip install gpytorch
1014
script:
1115
- pip install coveralls
12-
- coverage run -m pytest
16+
- pip install pytest-timeout
17+
- coverage run -m pytest tests/common/
1318
- coveralls
1419
notifications:
1520
slack: bayeso:FWBoHH9TMqjKUJWkZxCaTNVE

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ The following `requirements` files include the package list, the purpose of whic
6565
We test our package in the following versions.
6666

6767
* Python 2.7 (It will be excluded due to the maintenance schedule for Python 2.7, but it is currently tested.)
68-
* Python 3.5
6968
* Python 3.6
7069
* Python 3.7
70+
* Python 3.8
7171

7272
## Contributor
7373
* [Jungtaek Kim](http://mlg.postech.ac.kr/~jtkim/) (POSTECH)

bayeso/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__version__ = '0.4.2'

bayeso/bo.py

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# bo
22
# author: Jungtaek Kim (jtkim@postech.ac.kr)
3-
# last updated: April 21, 2020
3+
# last updated: April 29, 2020
44

55
import numpy as np
66
import time
@@ -15,11 +15,15 @@
1515
cma = None
1616
import sobol_seq
1717

18-
from bayeso import gp
1918
from bayeso import acquisition
19+
from bayeso import constants
20+
from bayeso.gp import gp
21+
from bayeso.gp import gp_common
2022
from bayeso.utils import utils_common
2123
from bayeso.utils import utils_covariance
22-
from bayeso import constants
24+
from bayeso.utils import utils_logger
25+
26+
logger = utils_logger.get_logger('bo')
2327

2428

2529
def get_grids(arr_ranges, int_grids):
@@ -110,17 +114,14 @@ def _check_optimizer_method_bo(str_optimizer_method_bo, num_dim, debug):
110114
assert str_optimizer_method_bo in constants.ALLOWED_OPTIMIZER_METHOD_BO
111115

112116
if str_optimizer_method_bo == 'DIRECT' and directminimize is None: # pragma: no cover
113-
if debug:
114-
print('[DEBUG] _check_optimizer_method_bo in bo.py: DIRECT is selected, but it is not installed.')
117+
logger.warning('DIRECT is selected, but it is not installed.')
115118
str_optimizer_method_bo = 'L-BFGS-B'
116119
elif str_optimizer_method_bo == 'CMA-ES' and cma is None: # pragma: no cover
117-
if debug:
118-
print('[DEBUG] _check_optimizer_method_bo in bo.py: CMA-ES is selected, but it is not installed.')
120+
logger.warning('CMA-ES is selected, but it is not installed.')
119121
str_optimizer_method_bo = 'L-BFGS-B'
120122
# TODO: It should be checked.
121123
elif str_optimizer_method_bo == 'CMA-ES' and num_dim == 1: # pragma: no cover
122-
if debug:
123-
print('[DEBUG] _check_optimizer_method_bo in bo.py: CMA-ES is selected, but a dimension of bounds is 1.')
124+
logger.warning('CMA-ES is selected, but a dimension of bounds is 1.')
124125
str_optimizer_method_bo = 'L-BFGS-B'
125126
return str_optimizer_method_bo
126127

@@ -349,8 +350,7 @@ def _get_initial_sobol(self, int_samples, int_seed=None):
349350

350351
if int_seed is None:
351352
int_seed = np.random.randint(0, 10000)
352-
if self.debug:
353-
print('[DEBUG] _get_initial_sobol in bo.py: int_seed', int_seed)
353+
if self.debug: logger.debug('seed: {}'.format(int_seed))
354354
arr_samples = sobol_seq.i4_sobol_generate(self.num_dim, int_samples, int_seed)
355355
arr_samples = arr_samples * (self.arr_range[:, 1].flatten() - self.arr_range[:, 0].flatten()) + self.arr_range[:, 0].flatten()
356356
return arr_samples
@@ -404,8 +404,7 @@ def get_initial(self, str_initial_method,
404404

405405
if str_initial_method == 'grid':
406406
assert fun_objective is not None
407-
if self.debug:
408-
print('[DEBUG] get_initial in bo.py: int_samples is ignored, because grid is chosen.')
407+
if self.debug: logger.debug('int_samples is ignored, because grid is chosen.')
409408
arr_initials = self._get_initial_grid()
410409
arr_initials = get_best_acquisition(arr_initials, fun_objective)
411410
elif str_initial_method == 'uniform':
@@ -416,9 +415,9 @@ def get_initial(self, str_initial_method,
416415
raise NotImplementedError('get_initial: latin')
417416
else:
418417
raise NotImplementedError('get_initial: allowed str_initial_method, but it is not implemented.')
419-
if self.debug:
420-
print('[DEBUG] get_initial in bo.py: arr_initials')
421-
print(arr_initials)
418+
419+
if self.debug: logger.debug('arr_initials:\n{}'.format(utils_logger.get_str_array(arr_initials)))
420+
422421
return arr_initials
423422

424423
def _optimize_objective(self, fun_acquisition, X_train, Y_train, X_test, cov_X_X, inv_cov_X_X, hyps):
@@ -496,8 +495,7 @@ def _optimize(self, fun_negative_acquisition, str_initial_method, int_samples):
496495
)
497496
next_point_x = next_point.x
498497
list_next_point.append(next_point_x)
499-
if self.debug:
500-
print('[DEBUG] _optimize in bo.py: optimized point for acq', next_point_x)
498+
if self.debug: logger.debug('acquired sample: {}'.format(utils_logger.get_str_array(next_point_x)))
501499
elif self.str_optimizer_method_bo == 'DIRECT': # pragma: no cover
502500
list_bounds = self._get_bounds()
503501
next_point = directminimize(
@@ -542,8 +540,8 @@ def optimize(self, X_train, Y_train,
542540
:param str_mlm_method: the name of marginal likelihood maximization method for Gaussian process regression.
543541
:type str_mlm_method: str., optional
544542
545-
:returns: acquired example, candidates of acquired examples, acquisition function values over the candidates, covariance matrix by `hyps`, inverse matrix of the covariance matrix, hyperparameters optimized, and execution times. Shape: ((d, ), (`int_samples`, d), (`int_samples`, ), (n, n), (n, n), dict., dict.).
546-
:rtype: (numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray, dict., dict.)
543+
:returns: acquired example and dictionary of information. Shape: ((d, ), dict.).
544+
:rtype: (numpy.ndarray, dict.)
547545
548546
:raises: AssertionError
549547
@@ -565,7 +563,7 @@ def optimize(self, X_train, Y_train,
565563

566564
time_start = time.time()
567565

568-
if self.is_normalized:
566+
if self.is_normalized and not np.max(Y_train) == np.min(Y_train):
569567
Y_train = (Y_train - np.min(Y_train)) / (np.max(Y_train) - np.min(Y_train)) * constants.MULTIPLIER_RESPONSE
570568

571569
time_start_gp = time.time()
@@ -578,11 +576,9 @@ def optimize(self, X_train, Y_train,
578576
cov_X_X, inv_cov_X_X, hyps = gp.get_optimized_kernel(X_train, Y_train, self.prior_mu, self.str_cov, str_optimizer_method=self.str_optimizer_method_gp, str_modelselection_method=self.str_modelselection_method, debug=self.debug)
579577
self.is_optimize_hyps = not _check_hyps_convergence(self.historical_hyps, hyps, self.str_cov, is_fixed_noise)
580578
else: # pragma: no cover
581-
print('[DEBUG] optimize in bo.py: hyps are converged.')
579+
if self.debug: logger.debug('hyps converged.')
582580
hyps = self.historical_hyps[-1]
583-
cov_X_X, inv_cov_X_X, _ = gp.get_kernel_inverse(X_train, hyps, self.str_cov, is_fixed_noise=is_fixed_noise, debug=self.debug)
584-
elif str_mlm_method == 'probabilistic': # pragma: no cover
585-
raise NotImplementedError('optimize: it will be added.')
581+
cov_X_X, inv_cov_X_X, _ = gp_common.get_kernel_inverse(X_train, hyps, self.str_cov, is_fixed_noise=is_fixed_noise, debug=self.debug)
586582
else: # pragma: no cover
587583
raise ValueError('optimize: missing condition for str_mlm_method.')
588584
time_end_gp = time.time()
@@ -600,13 +596,17 @@ def optimize(self, X_train, Y_train,
600596

601597
time_end = time.time()
602598

603-
times = {
604-
'overall': time_end - time_start,
605-
'gp': time_end_gp - time_start_gp,
606-
'acq': time_end_acq - time_start_acq,
599+
dict_info = {
600+
'next_points': next_points,
601+
'acquisitions': acquisitions,
602+
'cov_X_X': cov_X_X,
603+
'inv_cov_X_X': inv_cov_X_X,
604+
'hyps': hyps,
605+
'time_overall': time_end - time_start,
606+
'time_gp': time_end_gp - time_start_gp,
607+
'time_acq': time_end_acq - time_start_acq,
607608
}
608609

609-
if self.debug:
610-
print('[DEBUG] optimize in bo.py: time consumed', time_end - time_start, 'sec.')
610+
if self.debug: logger.debug('overall time consumed to acquire: {:.4f} sec.'.format(time_end - time_start))
611611

612-
return next_point, next_points, acquisitions, cov_X_X, inv_cov_X_X, hyps, times
612+
return next_point, dict_info

bayeso/constants.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
JITTER_COV = 1e-5
1010
JITTER_LOG = 1e-7
1111

12-
STR_OPTIMIZER_METHOD_GP = 'BFGS'
12+
STR_OPTIMIZER_METHOD_GP = 'Nelder-Mead'
1313
STR_OPTIMIZER_METHOD_BO = 'L-BFGS-B'
1414
STR_GP_COV = 'matern52'
1515
STR_BO_ACQ = 'ei'
@@ -37,17 +37,18 @@
3737
TIME_PAUSE = 2.0
3838
RANGE_SHADE = 1.96
3939

40-
ALLOWED_OPTIMIZER_METHOD_GP = ['BFGS', 'L-BFGS-B', 'DIRECT', 'CMA-ES']
40+
ALLOWED_OPTIMIZER_METHOD_GP = ['BFGS', 'L-BFGS-B', 'Nelder-Mead', 'DIRECT']
4141
ALLOWED_OPTIMIZER_METHOD_BO = ['L-BFGS-B', 'DIRECT', 'CMA-ES']
4242
# INFO: Do not use _ (underscore) in base str_cov.
43-
ALLOWED_GP_COV_BASE = ['se', 'matern32', 'matern52']
43+
ALLOWED_GP_COV_BASE = ['eq', 'se', 'matern32', 'matern52']
4444
ALLOWED_GP_COV_SET = ['set_' + str_cov for str_cov in ALLOWED_GP_COV_BASE]
4545
ALLOWED_GP_COV = ALLOWED_GP_COV_BASE + ALLOWED_GP_COV_SET
4646
ALLOWED_BO_ACQ = ['pi', 'ei', 'ucb', 'aei', 'pure_exploit', 'pure_explore']
4747
ALLOWED_INITIALIZATIONS_BO = ['sobol', 'uniform', 'latin']
4848
ALLOWED_INITIALIZATIONS_AO = ALLOWED_INITIALIZATIONS_BO + ['grid']
4949
ALLOWED_MLM_METHOD = ['regular', 'converged']
5050
ALLOWED_MODELSELECTION_METHOD = ['ml', 'loocv']
51+
ALLOWED_FRAMEWORK_GP = ['scipy', 'tensorflow', 'gpytorch']
5152

5253
KEYS_INFO_BENCHMARK = ['dim_fun', 'bounds', 'global_minimum_X', 'global_minimum_y']
5354

bayeso/covariance.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def choose_fun_cov(str_cov, is_grad=False):
2828
assert isinstance(str_cov, str)
2929
assert isinstance(is_grad, bool)
3030

31-
if str_cov == 'se':
31+
if str_cov == 'eq' or str_cov == 'se':
3232
if is_grad:
3333
fun_cov = grad_cov_se
3434
else:
@@ -76,7 +76,7 @@ def cov_se(X, Xs, lengthscales, signal):
7676
if isinstance(lengthscales, np.ndarray):
7777
assert X.shape[1] == Xs.shape[1] == lengthscales.shape[0]
7878
else:
79-
assert X.shape[0] == Xs.shape[0]
79+
assert X.shape[1] == Xs.shape[1]
8080
dist = scisd.cdist(X / lengthscales, Xs / lengthscales, metric='euclidean')
8181
cov_ = signal**2 * np.exp(-0.5 * dist**2)
8282
return cov_
@@ -164,7 +164,7 @@ def cov_matern32(X, Xs, lengthscales, signal):
164164
if isinstance(lengthscales, np.ndarray):
165165
assert X.shape[1] == Xs.shape[1] == lengthscales.shape[0]
166166
else:
167-
assert X.shape[0] == Xs.shape[0]
167+
assert X.shape[1] == Xs.shape[1]
168168
assert isinstance(signal, float)
169169

170170
dist = scisd.cdist(X / lengthscales, Xs / lengthscales, metric='euclidean')
@@ -254,7 +254,7 @@ def cov_matern52(X, Xs, lengthscales, signal):
254254
if isinstance(lengthscales, np.ndarray):
255255
assert X.shape[1] == Xs.shape[1] == lengthscales.shape[0]
256256
else:
257-
assert X.shape[0] == Xs.shape[0]
257+
assert X.shape[1] == Xs.shape[1]
258258
assert isinstance(signal, float)
259259

260260
dist = scisd.cdist(X / lengthscales, Xs / lengthscales, metric='euclidean')
@@ -353,8 +353,6 @@ def cov_set(str_cov, X, Xs, lengthscales, signal):
353353
assert str_cov in constants.ALLOWED_GP_COV_BASE
354354
num_X = X.shape[0]
355355
num_Xs = Xs.shape[0]
356-
num_d_X = X.shape[1]
357-
num_d_Xs = Xs.shape[1]
358356

359357
fun_cov = choose_fun_cov(str_cov)
360358
cov_ = fun_cov(X, Xs, lengthscales, signal)
@@ -406,7 +404,7 @@ def cov_main(str_cov, X, Xs, hyps, same_X_Xs,
406404
assert num_X == num_Xs
407405
cov_ += np.eye(num_X) * jitter
408406

409-
if str_cov == 'se' or str_cov == 'matern32' or str_cov == 'matern52':
407+
if str_cov == 'eq' or str_cov == 'se' or str_cov == 'matern32' or str_cov == 'matern52':
410408
assert len(X.shape) == 2
411409
assert len(Xs.shape) == 2
412410
num_d_X = X.shape[1]

0 commit comments

Comments
 (0)