Skip to content

Commit 3707e62

Browse files
committed
restructure
1 parent 081d9f7 commit 3707e62

15 files changed

Lines changed: 332 additions & 227 deletions

.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
scratch/*
22
scripts/*
33
examples/*
4+
external/hyperopt/*
45
datasets/*
56
results/*
67

bore/benchmarks.py

Lines changed: 155 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import numpy as np
22
import ConfigSpace as CS
3+
import yaml
34

5+
from pathlib import Path
46
from collections import namedtuple
57
from abc import ABC, abstractmethod
68

@@ -19,6 +21,10 @@ class BenchmarkBase(ABC):
1921
def get_config_space(self):
2022
pass
2123

24+
@abstractmethod
25+
def get_minimum(self):
26+
pass
27+
2228

2329
class Benchmark(BenchmarkBase):
2430

@@ -56,6 +62,39 @@ def get_config_space(self):
5662
CS.UniformFloatHyperparameter("y", lower=0, upper=15))
5763
return cs
5864

65+
def get_minimum(self):
66+
return 0.397887
67+
68+
69+
class Ackley(Benchmark):
70+
71+
def __init__(self, dimensions, a=20, b=0.2, c=2*np.pi):
72+
self.dimensions = dimensions
73+
self.a = a
74+
self.b = b
75+
self.c = c
76+
77+
def __call__(self, kwargs, budget=None):
78+
x = np.hstack([kwargs.get(f"x{d}") for d in range(self.dimensions)])
79+
value = self.func(x, a=self.a, b=self.b, c=self.c)
80+
return Evaluation(value=value, duration=None)
81+
82+
@staticmethod
83+
def func(x, a=20, b=0.2, c=2*np.pi):
84+
p = a * np.exp(-b * np.sqrt(np.mean(np.square(x), axis=-1)))
85+
q = np.exp(np.mean(np.cos(c*x)))
86+
return - p - q + a + np.e
87+
88+
def get_minimum(self):
89+
return 0.
90+
91+
def get_config_space(self):
92+
cs = CS.ConfigurationSpace()
93+
for d in range(self.dimensions):
94+
cs.add_hyperparameter(
95+
CS.UniformFloatHyperparameter(f"x{d}", lower=-32.768, upper=32.768))
96+
return cs
97+
5998

6099
class StyblinskiTang(Benchmark):
61100

@@ -70,6 +109,9 @@ def __call__(self, kwargs, budget=None):
70109
def func(x):
71110
return 0.5 * np.sum(x**4 - 16 * x**2 + 5*x, axis=-1)
72111

112+
def get_minimum(self):
113+
return -39.16599 * self.dimensions
114+
73115
def get_config_space(self):
74116
cs = CS.ConfigurationSpace()
75117
for d in range(self.dimensions):
@@ -96,7 +138,6 @@ def func(x, m):
96138
a = np.sin(x)
97139
b = np.sin(n * x**2 / np.pi)
98140
b **= 2*m
99-
100141
return - np.sum(a * b, axis=-1)
101142

102143
def get_config_space(self):
@@ -106,6 +147,16 @@ def get_config_space(self):
106147
CS.UniformFloatHyperparameter(f"x{d}", lower=0., upper=np.pi))
107148
return cs
108149

150+
def get_minimum(self):
151+
minimums = {
152+
2: -1.8013,
153+
5: -4.687658,
154+
10: -9.66015
155+
}
156+
assert self.dimensions in minimums, \
157+
f"global minimum for dimensions={self.dimensions} not known"
158+
return minimums[self.dimensions]
159+
109160

110161
class Hartmann(Benchmark):
111162

@@ -146,6 +197,9 @@ def __init__(self):
146197
[381, 5743, 8828]])
147198
super(Hartmann3D, self).__init__(dimensions=3, A=A, P=P)
148199

200+
def get_minimum(self):
201+
return -3.86278
202+
149203

150204
class Hartmann6D(Hartmann):
151205

@@ -160,6 +214,9 @@ def __init__(self):
160214
[4047, 8828, 8732, 5743, 1091, 381]])
161215
super(Hartmann6D, self).__init__(dimensions=6, A=A, P=P)
162216

217+
def get_minimum(self):
218+
return -3.32237
219+
163220

164221
class FCNet(Benchmark):
165222

@@ -174,6 +231,8 @@ def __init__(self, dataset_name, data_dir):
174231
benchmark = FCNetParkinsonsTelemonitoringBenchmark(data_dir=data_dir)
175232
else:
176233
raise ValueError("dataset name not recognized!")
234+
self.dataset_name = dataset_name
235+
self.data_dir = data_dir
177236
self.benchmark = benchmark
178237

179238
def __call__(self, kwargs, budget=100):
@@ -185,6 +244,27 @@ def __call__(self, kwargs, budget=100):
185244
def get_config_space(self):
186245
return self.benchmark.get_configuration_space()
187246

247+
def get_minimum(self):
248+
249+
base_path = Path(self.data_dir).joinpath(self.dataset_name)
250+
path = base_path.joinpath("minimum.yaml")
251+
252+
if path.exists():
253+
with path.open('r') as f:
254+
val_error_min = yaml.safe_load(f).get("val_error_min")
255+
else:
256+
257+
config_dict, val_error_min, \
258+
test_error_min = self.benchmark.get_best_configuration()
259+
260+
d = dict(config_dict=config_dict,
261+
val_error_min=float(val_error_min),
262+
test_error_min=float(test_error_min))
263+
264+
with path.open('w') as f:
265+
yaml.dump(d, f)
266+
return float(val_error_min)
267+
188268

189269
class FCNetAlt(FCNet):
190270

@@ -216,13 +296,51 @@ def get_config_space(self):
216296
cs.add_hyperparameter(CS.UniformIntegerHyperparameter("batch_size", lower=0, upper=3))
217297
return cs
218298

219-
# def goldstein_price(x, y):
220299

221-
# a = 1 + (x + y + 1)**2 * (19 - 14*x + 3*x**2 - 14*y + 6*x*y + 3*y**2)
222-
# b = 30 + (2*x - 3*y)**2 * (18 - 32*x + 12*x**2 - 48*y + 36*x*y + 27*y**2)
300+
class GoldsteinPrice(Benchmark):
301+
302+
def __call__(self, kwargs, budget=None):
303+
value = self.func(**kwargs)
304+
return Evaluation(value=value, duration=None)
305+
306+
@staticmethod
307+
def func(x, y):
308+
a = 1 + (x + y + 1)**2 * (19 - 14*x + 3*x**2 - 14*y + 6*x*y + 3*y**2)
309+
b = 30 + (2*x - 3*y)**2 * (18 - 32*x + 12*x**2 + 48*y - 36*x*y + 27*y**2)
310+
return a * b
311+
312+
def get_config_space(self):
313+
cs = CS.ConfigurationSpace()
314+
cs.add_hyperparameter(
315+
CS.UniformFloatHyperparameter("x", lower=-2., upper=2.))
316+
cs.add_hyperparameter(
317+
CS.UniformFloatHyperparameter("y", lower=-2., upper=2.))
318+
return cs
319+
320+
def get_minimum(self):
321+
return 3
322+
223323

224-
# return a * b
324+
class SixHumpCamel(Benchmark):
225325

326+
def __call__(self, kwargs, budget=None):
327+
value = self.func(**kwargs)
328+
return Evaluation(value=value, duration=None)
329+
330+
@staticmethod
331+
def func(x, y):
332+
return (4 - 2.1 * x**2 + x**4/3) * x**2 + x*y + (-4 + 4 * y**2) * y**2
333+
334+
def get_config_space(self):
335+
cs = CS.ConfigurationSpace()
336+
cs.add_hyperparameter(
337+
CS.UniformFloatHyperparameter("x", lower=-3., upper=3.))
338+
cs.add_hyperparameter(
339+
CS.UniformFloatHyperparameter("y", lower=-2., upper=2.))
340+
return cs
341+
342+
def get_minimum(self):
343+
return -1.0316
226344

227345
# def borehole(rw, r, Tu, Hu, Tl, Hl, L, Kw):
228346

@@ -235,20 +353,6 @@ def get_config_space(self):
235353
# return ret
236354

237355

238-
# class GoldsteinPriceWorker(Worker):
239-
240-
# def compute(self, config, budget, **kwargs):
241-
# y = goldstein_price(**config)
242-
# return dict(loss=y, info=None)
243-
244-
# @staticmethod
245-
# def get_config_space():
246-
# cs = CS.ConfigurationSpace()
247-
# cs.add_hyperparameter(CS.UniformFloatHyperparameter("x", lower=0, upper=1))
248-
# cs.add_hyperparameter(CS.UniformFloatHyperparameter("y", lower=0, upper=1))
249-
# return cs
250-
251-
252356
# class BoreholeWorker(Worker):
253357

254358
# def compute(self, config, budget, **kwargs):
@@ -269,3 +373,35 @@ def get_config_space(self):
269373
# cs.add_hyperparameter(CS.UniformFloatHyperparameter("L", lower=1120, upper=1680))
270374
# cs.add_hyperparameter(CS.UniformFloatHyperparameter("Kw", lower=9855, upper=12045))
271375
# return cs
376+
# -309.5755876604079
377+
378+
benchmarks = dict(
379+
branin=Branin,
380+
goldstein_price=GoldsteinPrice,
381+
six_hump_camel=SixHumpCamel,
382+
styblinski_tang=StyblinskiTang,
383+
michalewicz=Michalewicz,
384+
hartmann3d=Hartmann3D,
385+
hartmann6d=Hartmann6D,
386+
fcnet=FCNet,
387+
fcnet_alt=FCNetAlt
388+
)
389+
390+
391+
def make_benchmark(benchmark_name, dimensions=None, dataset_name=None,
392+
data_dir=None):
393+
394+
Benchmark = benchmarks[benchmark_name]
395+
396+
kws = {}
397+
if benchmark_name.startswith("fcnet"):
398+
assert dataset_name is not None, "must specify dataset name"
399+
assert data_dir is not None, "must specify data directory"
400+
kws["dataset_name"] = dataset_name
401+
kws["data_dir"] = data_dir
402+
403+
if benchmark_name in ["michalewicz", "styblinski_tang"]:
404+
assert dimensions is not None, "must specify dimensions"
405+
kws["dimensions"] = dimensions
406+
407+
return Benchmark(**kws)

0 commit comments

Comments
 (0)