Skip to content

Commit

Permalink
Merge pull request #21 from jungtaekkim/0.4.3
Browse files Browse the repository at this point in the history
0.4.3
  • Loading branch information
jungtaekkim committed Dec 3, 2020
2 parents f4b3393 + 4f0eac4 commit 05cec33
Show file tree
Hide file tree
Showing 97 changed files with 5,583 additions and 2,767 deletions.
604 changes: 604 additions & 0 deletions .pylintrc

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
language: python
dist: xenial
python:
- '2.7'
- '3.6'
- '3.7'
- '3.8'
Expand Down
4 changes: 4 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
include LICENSE
include CODE_OF_CONDUCT.md
include requirements.txt
include requirements-optional.txt
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<p align="center">
<img src="docs/_static/assets/logo_bayeso.svg" width="400" />
<img src="docs/_static/assets/logo_bayeso_capitalized.svg" width="400" />
</p>

# bayeso: A Bayesian optimization framework in Python
# BayesO: A Bayesian optimization framework in Python
[![Build Status](https://travis-ci.org/jungtaekkim/bayeso.svg?branch=master)](https://travis-ci.org/jungtaekkim/bayeso)
[![Coverage Status](https://coveralls.io/repos/github/jungtaekkim/bayeso/badge.svg?branch=master)](https://coveralls.io/github/jungtaekkim/bayeso?branch=master)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/bayeso)](https://pypi.org/project/bayeso/)
Expand Down Expand Up @@ -47,7 +47,7 @@ in the `bayeso` root.

* Uninstallation

If you would like to uninstall bayeso, command it.
If you would like to uninstall `bayeso`, command it.

```shell
$ pip uninstall bayeso
Expand All @@ -64,7 +64,6 @@ The following `requirements` files include the package list, the purpose of whic
## Supported Python Version
We test our package in the following versions.

* Python 2.7 (It will be excluded due to the maintenance schedule for Python 2.7, but it is currently tested.)
* Python 3.6
* Python 3.7
* Python 3.8
Expand All @@ -76,7 +75,7 @@ We test our package in the following versions.
```
@misc{KimJ2017bayeso,
author={Kim, Jungtaek and Choi, Seungjin},
title={{bayeso}: A {Bayesian} optimization framework in {Python}},
title={{BayesO}: A {Bayesian} optimization framework in {Python}},
howpublished={\url{http://bayeso.org}},
year={2017}
}
Expand Down
8 changes: 7 additions & 1 deletion bayeso/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
__version__ = '0.4.2'
#
# author: Jungtaek Kim (jtkim@postech.ac.kr)
# last updated: September 24, 2020
#
"""BayesO is a simple, but essential Bayesian optimization package, implemented in Python."""

__version__ = '0.4.3'
100 changes: 51 additions & 49 deletions bayeso/acquisition.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
# acquisition
#
# author: Jungtaek Kim (jtkim@postech.ac.kr)
# last updated: February 01, 2020
# last updated: September 24, 2020
#
"""It defines acquisition functions."""

import numpy as np
import scipy.stats

from bayeso import constants
from bayeso.utils import utils_common


def pi(pred_mean, pred_std, Y_train, jitter=constants.JITTER_ACQ):
@utils_common.validate_types
def pi(pred_mean: np.ndarray, pred_std: np.ndarray, Y_train: np.ndarray,
jitter: float=constants.JITTER_ACQ
) -> np.ndarray:
"""
It is a probability improvement criterion.
:param pred_mean: posterior predictive mean function over `X_test`. Shape: (l, ).
:param pred_mean: posterior predictive mean function over `X_test`.
Shape: (l, ).
:type pred_mean: numpy.ndarray
:param pred_std: posterior predictive standard deviation function over `X_test`. Shape: (l, ).
:param pred_std: posterior predictive standard deviation function over
`X_test`. Shape: (l, ).
:type pred_std: numpy.ndarray
:param Y_train: outputs of `X_train`. Shape: (n, 1).
:type Y_train: numpy.ndarray
Expand All @@ -41,7 +49,10 @@ def pi(pred_mean, pred_std, Y_train, jitter=constants.JITTER_ACQ):
val_z = (np.min(Y_train) - pred_mean) / (pred_std + jitter)
return scipy.stats.norm.cdf(val_z)

def ei(pred_mean, pred_std, Y_train, jitter=constants.JITTER_ACQ):
@utils_common.validate_types
def ei(pred_mean: np.ndarray, pred_std: np.ndarray, Y_train: np.ndarray,
jitter: float=constants.JITTER_ACQ
) -> np.ndarray:
"""
It is an expected improvement criterion.
Expand Down Expand Up @@ -72,22 +83,33 @@ def ei(pred_mean, pred_std, Y_train, jitter=constants.JITTER_ACQ):

with np.errstate(divide='ignore'):
val_z = (np.min(Y_train) - pred_mean) / (pred_std + jitter)
return (np.min(Y_train) - pred_mean) * scipy.stats.norm.cdf(val_z) + pred_std * scipy.stats.norm.pdf(val_z)

def ucb(pred_mean, pred_std, Y_train=None, kappa=2.0, is_increased=True):
return (np.min(Y_train) - pred_mean) * scipy.stats.norm.cdf(val_z) \
+ pred_std * scipy.stats.norm.pdf(val_z)

@utils_common.validate_types
def ucb(pred_mean: np.ndarray, pred_std: np.ndarray,
Y_train: constants.TYPING_UNION_ARRAY_NONE=None,
kappa: float=2.0,
increase_kappa: bool=True
) -> np.ndarray:
"""
It is a Gaussian process upper confidence bound criterion.
:param pred_mean: posterior predictive mean function over `X_test`. Shape: (l, ).
:param pred_mean: posterior predictive mean function over `X_test`.
Shape: (l, ).
:type pred_mean: numpy.ndarray
:param pred_std: posterior predictive standard deviation function over `X_test`. Shape: (l, ).
:param pred_std: posterior predictive standard deviation function over
`X_test`. Shape: (l, ).
:type pred_std: numpy.ndarray
:param Y_train: outputs of `X_train`. Shape: (n, 1).
:type Y_train: numpy.ndarray, optional
:param kappa: trade-off hyperparameter between exploration and exploitation.
:param kappa: trade-off hyperparameter between exploration and
exploitation.
:type kappa: float, optional
:param is_increased: flag for increasing a kappa value as `Y_train` grows. If `Y_train` is None, it is ignored, which means `kappa` is fixed.
:type is_increased: bool., optional
:param increase_kappa: flag for increasing a kappa value as `Y_train`
grows. If `Y_train` is None, it is ignored, which means `kappa` is
fixed.
:type increase_kappa: bool., optional
:returns: acquisition function values. Shape: (l, ).
:rtype: numpy.ndarray
Expand All @@ -98,24 +120,25 @@ def ucb(pred_mean, pred_std, Y_train=None, kappa=2.0, is_increased=True):

assert isinstance(pred_mean, np.ndarray)
assert isinstance(pred_std, np.ndarray)
assert isinstance(Y_train, np.ndarray) or Y_train is None
assert isinstance(Y_train, (np.ndarray, type(None)))
assert isinstance(kappa, float)
assert isinstance(is_increased, bool)
assert isinstance(increase_kappa, bool)
assert len(pred_mean.shape) == 1
assert len(pred_std.shape) == 1
if Y_train is not None:
assert len(Y_train.shape) == 2
assert pred_mean.shape[0] == pred_std.shape[0]

if is_increased and Y_train is not None:
if increase_kappa and Y_train is not None:
kappa_ = kappa * np.log(Y_train.shape[0])
else:
kappa_ = kappa
return -pred_mean + kappa_ * pred_std

def aei(pred_mean, pred_std, Y_train, noise,
jitter=constants.JITTER_ACQ
):
@utils_common.validate_types
def aei(pred_mean: np.ndarray, pred_std: np.ndarray, Y_train: np.ndarray, noise: float,
jitter: float=constants.JITTER_ACQ
) -> np.ndarray:
"""
It is an augmented expected improvement criterion.
Expand Down Expand Up @@ -149,21 +172,18 @@ def aei(pred_mean, pred_std, Y_train, noise,

with np.errstate(divide='ignore'):
val_z = (np.min(Y_train) - pred_mean) / (pred_std + jitter)
ei = (np.min(Y_train) - pred_mean) * scipy.stats.norm.cdf(val_z) + pred_std * scipy.stats.norm.pdf(val_z)
aei = ei * (1.0 - noise / np.sqrt(pred_std**2 + noise**2))
return aei
val_ei = (np.min(Y_train) - pred_mean) * scipy.stats.norm.cdf(val_z) \
+ pred_std * scipy.stats.norm.pdf(val_z)
val_aei = val_ei * (1.0 - noise / np.sqrt(pred_std**2 + noise**2))
return val_aei

# pred_std and Y_train are ignored.
def pure_exploit(pred_mean, pred_std=None, Y_train=None):
@utils_common.validate_types
def pure_exploit(pred_mean: np.ndarray) -> np.ndarray:
"""
It is a pure exploitation criterion.
:param pred_mean: posterior predictive mean function over `X_test`. Shape: (l, ).
:type pred_mean: numpy.ndarray
:param pred_std: posterior predictive standard deviation function over `X_test`. Shape: (l, ). It can be given, but it is ignored when it works.
:type pred_std: numpy.ndarray, optional
:param Y_train: outputs of `X_train`. Shape: (n, 1). It can be given, but it is ignored when it works.
:type Y_train: numpy.ndarray, optional
:returns: acquisition function values. Shape: (l, ).
:rtype: numpy.ndarray
Expand All @@ -173,28 +193,17 @@ def pure_exploit(pred_mean, pred_std=None, Y_train=None):
"""

assert isinstance(pred_mean, np.ndarray)
assert isinstance(pred_std, np.ndarray) or pred_std is None
assert isinstance(Y_train, np.ndarray) or Y_train is None
assert len(pred_mean.shape) == 1
if pred_std is not None:
assert len(pred_std.shape) == 1
assert pred_mean.shape[0] == pred_std.shape[0]
if Y_train is not None:
assert len(Y_train.shape) == 2

return -pred_mean

# pred_mean and Y_train are ignored.
def pure_explore(pred_std, pred_mean=None, Y_train=None):
@utils_common.validate_types
def pure_explore(pred_std: np.ndarray) -> np.ndarray:
"""
It is a pure exploration criterion.
:param pred_std: posterior predictive standard deviation function over `X_test`. Shape: (l, ).
:type pred_std: numpy.ndarray
:param pred_mean: posterior predictive mean function over `X_test`. Shape: (l, ). It can be given, but it is ignored when it works.
:type pred_mean: numpy.ndarray, optional
:param Y_train: outputs of `X_train`. Shape: (n, 1). It can be given, but it is ignored when it works.
:type Y_train: numpy.ndarray, optional
:returns: acquisition function values. Shape: (l, ).
:rtype: numpy.ndarray
Expand All @@ -203,14 +212,7 @@ def pure_explore(pred_std, pred_mean=None, Y_train=None):
"""

assert isinstance(pred_mean, np.ndarray) or pred_mean is None
assert isinstance(pred_std, np.ndarray)
assert isinstance(Y_train, np.ndarray) or Y_train is None
assert len(pred_std.shape) == 1
if pred_mean is not None:
assert len(pred_mean.shape) == 1
assert pred_mean.shape[0] == pred_std.shape[0]
if Y_train is not None:
assert len(Y_train.shape) == 2

return pred_std

0 comments on commit 05cec33

Please sign in to comment.