diff --git a/hyppopy/globals.py b/hyppopy/globals.py index 4e701b0..313456d 100644 --- a/hyppopy/globals.py +++ b/hyppopy/globals.py @@ -1,35 +1,36 @@ # DKFZ # # # Copyright (c) German Cancer Research Center, # Division of Medical Image Computing. # All rights reserved. # # This software is distributed WITHOUT ANY WARRANTY; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. # # See LICENSE import os import sys import logging ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) sys.path.insert(0, ROOT) LIBNAME = "hyppopy" TESTDATA_DIR = os.path.join(ROOT, *(LIBNAME, "tests", "data")) HYPERPARAMETERPATH = "hyperparameter" SETTINGSPATH = "settings" VFUNCDATAPATH = os.path.join(os.path.join(ROOT, LIBNAME), "virtualparameterspace") SUPPORTED_DOMAINS = ["uniform", "normal", "loguniform", "categorical"] SUPPORTED_DTYPES = ["int", "float", "str"] DEFAULTITERATIONS = 500 +DEFAULTGRIDFREQUENCY = 10 LOGFILENAME = os.path.join(ROOT, '{}_log.log'.format(LIBNAME)) DEBUGLEVEL = logging.DEBUG logging.basicConfig(filename=LOGFILENAME, filemode='w', format='%(levelname)s: %(name)s - %(message)s') diff --git a/hyppopy/solvers/GridsearchSolver.py b/hyppopy/solvers/GridsearchSolver.py index 4364385..5061c48 100644 --- a/hyppopy/solvers/GridsearchSolver.py +++ b/hyppopy/solvers/GridsearchSolver.py @@ -1,180 +1,194 @@ # DKFZ # # # Copyright (c) German Cancer Research Center, # Division of Medical Image Computing. # All rights reserved. # # This software is distributed WITHOUT ANY WARRANTY; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. # # See LICENSE import os import logging +import warnings import numpy as np from pprint import pformat from scipy.stats import norm from itertools import product -from hyppopy.globals import DEBUGLEVEL +from hyppopy.globals import DEBUGLEVEL, DEFAULTGRIDFREQUENCY from hyppopy.solvers.HyppopySolver import HyppopySolver LOG = logging.getLogger(os.path.basename(__file__)) LOG.setLevel(DEBUGLEVEL) def get_uniform_axis_sample(a, b, N, dtype): """ returns a uniform sample x(n) in the range [a,b] sampled at N pojnts :param a: left value range bound :param b: right value range bound :param N: discretization of intervall [a,b] :param dtype: data type :return: [list] axis range """ assert a < b, "condition a < b violated!" assert isinstance(N, int), "condition N of type int violated!" assert isinstance(dtype, str), "condition type of type str violated!" if dtype == "int": return list(np.linspace(a, b, N).astype(int)) elif dtype == "float" or dtype == "double": return list(np.linspace(a, b, N)) else: raise AssertionError("dtype {} not supported for uniform sampling!".format(dtype)) def get_norm_cdf(N): """ returns a normed gaussian cdf (range [0,1]) with N sampling points :param N: sampling points :return: [ndarray] gaussian cdf function values """ assert isinstance(N, int), "condition N of type int violated!" even = True if N % 2 != 0: N -= 1 even = False N = int(N/2) sigma = 1/3 x = np.linspace(0, 1, N) y1 = norm.cdf(x, loc=0, scale=sigma)-0.5 if not even: y1 = np.append(y1, [0.5]) y2 = 1-(norm.cdf(x, loc=0, scale=sigma)-0.5) y2 = np.flip(y2, axis=0) y = np.concatenate((y1, y2), axis=0) return y def get_gaussian_axis_sample(a, b, N, dtype): """ returns a function value f(n) where f is a gaussian cdf in range [a, b] and N sampling points :param a: left value range bound :param b: right value range bound :param N: discretization of intervall [a,b] :param dtype: data type :return: [list] axis range """ assert a < b, "condition a < b violated!" assert isinstance(N, int), "condition N of type int violated!" assert isinstance(dtype, str), "condition type of type str violated!" data = [] for n in range(N): x = a + get_norm_cdf(N)[n]*(b-a) if dtype == "int": data.append(int(x)) elif dtype == "float" or dtype == "double": data.append(x) else: raise AssertionError("dtype {} not supported for uniform sampling!".format(dtype)) return data def get_logarithmic_axis_sample(a, b, N, dtype): """ returns a function value f(n) where f is logarithmic function e^x sampling the exponent range [log(a), log(b)] linear at N sampling points. The function values returned are in the range [a, b]. :param a: left value range bound :param b: right value range bound :param N: discretization of intervall [a,b] :param dtype: data type :return: [list] axis range """ assert a < b, "condition a < b violated!" assert a > 0, "condition a > 0 violated!" assert isinstance(N, int), "condition N of type int violated!" assert isinstance(dtype, str), "condition type of type str violated!" # convert input range into exponent range lexp = np.log(a) rexp = np.log(b) exp_range = np.linspace(lexp, rexp, N) data = [] for n in range(exp_range.shape[0]): x = np.exp(exp_range[n]) if dtype == "int": data.append(int(x)) elif dtype == "float" or dtype == "double": data.append(x) else: raise AssertionError("dtype {} not supported for uniform sampling!".format(dtype)) return data class GridsearchSolver(HyppopySolver): """ The GridsearchSolver class implements a gridsearch optimization. The gridsearch supports categorical, uniform, normal and loguniform sampling. To use the GridsearchSolver, besides a range, one must specifiy the number of samples in the domain, e.g. 'data': [0, 1, 100] """ def __init__(self, project=None): HyppopySolver.__init__(self, project) self._has_maxiteration_field = False def loss_function_call(self, params): loss = self.blackbox(**params) if loss is None: return np.nan return loss def execute_solver(self, searchspace): for x in product(*searchspace[1]): params = {} for name, value in zip(searchspace[0], x): params[name] = value try: self.loss_function(**params) except Exception as e: msg = "internal error in randomsearch execute_solver occured. {}".format(e) LOG.error(msg) raise BrokenPipeError(msg) self.best = self._trials.argmin def convert_searchspace(self, hyperparameter): """ the function converts the standard parameter input into a range list depending on the domain. These rangelists are later used with itertools product to create a paramater space sample of each combination. :param hyperparameter: [dict] hyperparameter space :return: [list] name and range for each parameter space axis """ LOG.debug("convert input parameter\n\n\t{}\n".format(pformat(hyperparameter))) searchspace = [[], []] for name, param in hyperparameter.items(): + if param["domain"] != "categorical" and "frequency" not in param.keys(): + param["frequency"] = DEFAULTGRIDFREQUENCY + warnings.warn("No frequency field found, used default gridsearch frequency {}".format(DEFAULTGRIDFREQUENCY)) + if param["domain"] == "categorical": searchspace[0].append(name) searchspace[1].append(param["data"]) elif param["domain"] == "uniform": searchspace[0].append(name) - searchspace[1].append(get_uniform_axis_sample(param["data"][0], param["data"][1], param["data"][2], param["type"])) + searchspace[1].append(get_uniform_axis_sample(param["data"][0], + param["data"][1], + param["frequency"], + param["type"])) elif param["domain"] == "normal": searchspace[0].append(name) - searchspace[1].append(get_gaussian_axis_sample(param["data"][0], param["data"][1], param["data"][2], param["type"])) + searchspace[1].append(get_gaussian_axis_sample(param["data"][0], + param["data"][1], + param["frequency"], + param["type"])) elif param["domain"] == "loguniform": searchspace[0].append(name) - searchspace[1].append(get_logarithmic_axis_sample(param["data"][0], param["data"][1], param["data"][2], param["type"])) + searchspace[1].append(get_logarithmic_axis_sample(param["data"][0], + param["data"][1], + param["frequency"], + param["type"])) return searchspace diff --git a/hyppopy/tests/test_bayesoptsolver.py b/hyppopy/tests/test_bayesoptsolver.py index f208468..07c91e8 100644 --- a/hyppopy/tests/test_bayesoptsolver.py +++ b/hyppopy/tests/test_bayesoptsolver.py @@ -1,69 +1,69 @@ # DKFZ # # # Copyright (c) German Cancer Research Center, # Division of Medical Image Computing. # All rights reserved. # # This software is distributed WITHOUT ANY WARRANTY; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. # # See LICENSE import unittest import matplotlib.pylab as plt from hyppopy.solvers.BayesOptSolver import * from hyppopy.VirtualFunction import VirtualFunction from hyppopy.HyppopyProject import HyppopyProject class BayesOptSolverTestSuite(unittest.TestCase): def setUp(self): pass def test_solver_complete(self): config = { "hyperparameter": { "axis_00": { "domain": "normal", - "data": [300, 800], + "data": [0, 800], "type": "float" }, "axis_01": { "domain": "uniform", "data": [-1, 1], "type": "float" }, "axis_02": { "domain": "uniform", "data": [0, 10], "type": "float" } }, "settings": { "solver": {"max_iterations": 10}, "custom": {} }} project = HyppopyProject(config) solver = BayesOptSolver(project) vfunc = VirtualFunction() vfunc.load_default() solver.blackbox = vfunc solver.run(print_stats=False) df, best = solver.get_results() - self.assertTrue(300 <= best['axis_00'] <= 800) + self.assertTrue(0 <= best['axis_00'] <= 800) self.assertTrue(-1 <= best['axis_01'] <= 1) self.assertTrue(0 <= best['axis_02'] <= 10) for status in df['status']: self.assertTrue(status) for loss in df['losses']: self.assertTrue(isinstance(loss, float)) if __name__ == '__main__': unittest.main() diff --git a/hyppopy/tests/test_gridsearchsolver.py b/hyppopy/tests/test_gridsearchsolver.py index 26d7773..dd5065b 100644 --- a/hyppopy/tests/test_gridsearchsolver.py +++ b/hyppopy/tests/test_gridsearchsolver.py @@ -1,209 +1,301 @@ # DKFZ # # # Copyright (c) German Cancer Research Center, # Division of Medical Image Computing. # All rights reserved. # # This software is distributed WITHOUT ANY WARRANTY; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. # # See LICENSE import unittest from hyppopy.solvers.GridsearchSolver import * from hyppopy.VirtualFunction import VirtualFunction from hyppopy.HyppopyProject import HyppopyProject class GridsearchTestSuite(unittest.TestCase): def setUp(self): pass def test_get_uniform_axis_sample(self): drange = [0, 10] N = 11 data = get_uniform_axis_sample(drange[0], drange[1], N, "float") for i in range(11): self.assertEqual(float(i), data[i]) drange = [-10, 10] N = 21 data = get_uniform_axis_sample(drange[0], drange[1], N, "int") self.assertEqual(data[0], -10) self.assertEqual(data[20], 10) self.assertEqual(data[10], 0) def test_get_norm_cdf(self): res = [0, 0.27337265, 0.4331928, 0.48777553, 0.4986501, 0.5013499, 0.51222447, 0.5668072, 0.72662735, 1] f = get_norm_cdf(10) for n, v in enumerate(res): self.assertAlmostEqual(v, f[n]) res = [0.0, 0.27337264762313174, 0.4331927987311419, 0.48777552734495533, 0.4986501019683699, 0.5, 0.5013498980316301, 0.5122244726550447, 0.5668072012688581, 0.7266273523768683, 1.0] f = get_norm_cdf(11) for n, v in enumerate(res): self.assertAlmostEqual(v, f[n]) def test_get_gaussian_axis_sampling(self): res = [-5.0, -2.2662735237686826, -0.6680720126885813, -0.12224472655044671, -0.013498980316301257, 0.013498980316301257, 0.12224472655044671, 0.6680720126885813, 2.2662735237686826, 5.0] bounds = (-5, 5) N = 10 data = get_gaussian_axis_sample(bounds[0], bounds[1], N, "float") for n in range(N): self.assertAlmostEqual(res[n], data[n]) res = [-5.0, -2.2662735237686826, -0.6680720126885813, -0.12224472655044671, -0.013498980316301257, 0.0, 0.013498980316301257, 0.12224472655044671, 0.6680720126885813, 2.2662735237686826, 5.0] bounds = (-5, 5) N = 11 data = get_gaussian_axis_sample(bounds[0], bounds[1], N, "float") for n in range(N): self.assertAlmostEqual(res[n], data[n]) def test_get_logarithmic_axis_sample(self): res = [0.0010000000000000002, 0.0035938136638046297, 0.012915496650148841, 0.046415888336127795, 0.1668100537200059, 0.5994842503189414, 2.154434690031884, 7.7426368268112675, 27.825594022071247, 100.00000000000004] bounds = (0.001, 1e2) N = 10 data = get_logarithmic_axis_sample(bounds[0], bounds[1], N, "float") for n in range(N): self.assertAlmostEqual(res[n], data[n]) res = [0.0010000000000000002, 0.003162277660168382, 0.010000000000000004, 0.03162277660168381, 0.10000000000000006, 0.31622776601683833, 1.0000000000000009, 3.1622776601683813, 10.00000000000001, 31.622776601683846, 100.00000000000004] bounds = (0.001, 1e2) N = 11 data = get_logarithmic_axis_sample(bounds[0], bounds[1], N, "float") for n in range(N): self.assertAlmostEqual(res[n], data[n]) def test_solver(self): config = { "hyperparameter": { "value 1": { "domain": "uniform", - "data": [0, 20, 11], - "type": "int" + "data": [0, 20], + "type": "int", + "frequency": 11 }, "value 2": { "domain": "normal", - "data": [0, 20.0, 11], - "type": "float" + "data": [0, 20.0], + "type": "float", + "frequency": 11 }, "value 3": { "domain": "loguniform", - "data": [1, 10000, 11], - "type": "float" + "data": [1, 10000], + "type": "float", + "frequency": 11 }, "categorical": { "domain": "categorical", "data": ["a", "b"], "type": "str" } }, "settings": { "solver": {}, "custom": {} }} res_labels = ['value 1', 'value 2', 'value 3', 'categorical'] res_values = [[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20], [0.0, 5.467452952462635, 8.663855974622837, 9.755510546899107, 9.973002039367397, 10.0, 10.026997960632603, 10.244489453100893, 11.336144025377163, 14.532547047537365, 20.0], [1.0, 2.51188643150958, 6.309573444801933, 15.848931924611136, 39.810717055349734, 100.00000000000004, 251.18864315095806, 630.9573444801938, 1584.8931924611143, 3981.071705534977, 10000.00000000001], ['a', 'b'] ] solver = GridsearchSolver(config) searchspace = solver.convert_searchspace(config["hyperparameter"]) for n in range(len(res_labels)): self.assertEqual(res_labels[n], searchspace[0][n]) for i in range(3): self.assertAlmostEqual(res_values[i], searchspace[1][i]) self.assertEqual(res_values[3], searchspace[1][3]) - def test_solver_complete(self): + def test_solver_uniform(self): config = { "hyperparameter": { "axis_00": { - "domain": "normal", - "data": [300, 800, 11], - "type": "float" + "domain": "uniform", + "data": [0, 800], + "type": "float", + "frequency": 11 }, "axis_01": { - "domain": "normal", - "data": [-1, 1, 11], - "type": "float" + "domain": "uniform", + "data": [-1, 1], + "type": "float", + "frequency": 11 }, "axis_02": { "domain": "uniform", - "data": [0, 10, 11], - "type": "float" + "data": [0, 10], + "type": "float", + "frequency": 11 } }, "settings": { "solver": {}, "custom": {} }} project = HyppopyProject(config) solver = GridsearchSolver(project) vfunc = VirtualFunction() vfunc.load_default() solver.blackbox = vfunc solver.run(print_stats=False) df, best = solver.get_results() - self.assertAlmostEqual(best['axis_00'], 583.40, places=1) - self.assertAlmostEqual(best['axis_01'], 0.45, places=1) + self.assertAlmostEqual(best['axis_00'], 240, places=1) + self.assertAlmostEqual(best['axis_01'], 0.2, places=1) self.assertAlmostEqual(best['axis_02'], 5.0, places=1) for status in df['status']: self.assertTrue(status) for loss in df['losses']: self.assertTrue(isinstance(loss, float)) + def test_solver_normal(self): + config = { + "hyperparameter": { + "axis_00": { + "domain": "normal", + "data": [100, 300], + "type": "float", + "frequency": 11 + }, + "axis_01": { + "domain": "normal", + "data": [0, 0.8], + "type": "float", + "frequency": 11 + }, + "axis_02": { + "domain": "normal", + "data": [4, 6], + "type": "float", + "frequency": 11 + } + }, + "settings": { + "solver": {}, + "custom": {} + }} + + project = HyppopyProject(config) + solver = GridsearchSolver(project) + vfunc = VirtualFunction() + vfunc.load_default() + solver.blackbox = vfunc + solver.run(print_stats=False) + df, best = solver.get_results() + self.assertAlmostEqual(best['axis_00'], 197.555, places=1) + self.assertAlmostEqual(best['axis_01'], 0.21869, places=1) + self.assertAlmostEqual(best['axis_02'], 5.13361, places=1) + + for status in df['status']: + self.assertTrue(status) + for loss in df['losses']: + self.assertTrue(isinstance(loss, float)) + + def test_solver_loguniform(self): + config = { + "hyperparameter": { + "axis_00": { + "domain": "loguniform", + "data": [0.00001, 300], + "type": "float", + "frequency": 21 + }, + "axis_01": { + "domain": "loguniform", + "data": [0.00001, 0.8], + "type": "float", + "frequency": 21 + }, + "axis_02": { + "domain": "loguniform", + "data": [4, 6], + "type": "float", + "frequency": 21 + } + }, + "settings": { + "solver": {}, + "custom": {} + }} + + project = HyppopyProject(config) + solver = GridsearchSolver(project) + vfunc = VirtualFunction() + vfunc.load_default() + solver.blackbox = vfunc + solver.run(print_stats=False) + df, best = solver.get_results() + self.assertAlmostEqual(best['axis_00'], 299.999, places=1) + self.assertAlmostEqual(best['axis_01'], 0.25869, places=1) + self.assertAlmostEqual(best['axis_02'], 5.10169, places=1) + + for status in df['status']: + self.assertTrue(status) + for loss in df['losses']: + self.assertTrue(isinstance(loss, float)) + if __name__ == '__main__': unittest.main() diff --git a/hyppopy/tests/test_hyperoptsolver.py b/hyppopy/tests/test_hyperoptsolver.py index 13aef57..67b2de8 100644 --- a/hyppopy/tests/test_hyperoptsolver.py +++ b/hyppopy/tests/test_hyperoptsolver.py @@ -1,69 +1,109 @@ # DKFZ # # # Copyright (c) German Cancer Research Center, # Division of Medical Image Computing. # All rights reserved. # # This software is distributed WITHOUT ANY WARRANTY; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. # # See LICENSE import unittest import matplotlib.pylab as plt from hyppopy.solvers.HyperoptSolver import * from hyppopy.VirtualFunction import VirtualFunction from hyppopy.HyppopyProject import HyppopyProject class HyperoptSolverTestSuite(unittest.TestCase): def setUp(self): pass def test_solver_complete(self): config = { "hyperparameter": { "axis_00": { - "domain": "normal", - "data": [300, 800], + "domain": "uniform", + "data": [300, 700], "type": "float" }, "axis_01": { "domain": "uniform", - "data": [-1, 1], + "data": [0, 0.8], "type": "float" }, "axis_02": { "domain": "uniform", - "data": [0, 10], + "data": [3.5, 6.5], + "type": "float" + } + }, + "settings": { + "solver": {"max_iterations": 500}, + "custom": {} + }} + + project = HyppopyProject(config) + solver = HyperoptSolver(project) + vfunc = VirtualFunction() + vfunc.load_default() + solver.blackbox = vfunc + solver.run(print_stats=False) + df, best = solver.get_results() + self.assertTrue(570 <= best['axis_00'] <= 585) + self.assertTrue(0.15 <= best['axis_01'] <= 0.8) + self.assertTrue(4.5 <= best['axis_02'] <= 5.5) + + for status in df['status']: + self.assertTrue(status) + for loss in df['losses']: + self.assertTrue(isinstance(loss, float)) + + def test_solver_normal(self): + config = { + "hyperparameter": { + "axis_00": { + "domain": "normal", + "data": [500, 650], + "type": "float" + }, + "axis_01": { + "domain": "normal", + "data": [0.1, 0.8], + "type": "float" + }, + "axis_02": { + "domain": "normal", + "data": [4.5, 5.5], "type": "float" } }, "settings": { - "solver": {"max_iterations": 100}, + "solver": {"max_iterations": 500}, "custom": {} }} project = HyppopyProject(config) solver = HyperoptSolver(project) vfunc = VirtualFunction() vfunc.load_default() solver.blackbox = vfunc solver.run(print_stats=False) df, best = solver.get_results() - self.assertTrue(300 <= best['axis_00'] <= 800) - self.assertTrue(-1 <= best['axis_01'] <= 1) - self.assertTrue(0 <= best['axis_02'] <= 10) + self.assertTrue(575 <= best['axis_00'] <= 585) + self.assertTrue(0.1 <= best['axis_01'] <= 0.8) + self.assertTrue(4.7 <= best['axis_02'] <= 5.3) for status in df['status']: self.assertTrue(status) for loss in df['losses']: self.assertTrue(isinstance(loss, float)) if __name__ == '__main__': unittest.main() diff --git a/hyppopy/tests/test_randomsearchsolver.py b/hyppopy/tests/test_randomsearchsolver.py index f4c6427..f914302 100644 --- a/hyppopy/tests/test_randomsearchsolver.py +++ b/hyppopy/tests/test_randomsearchsolver.py @@ -1,135 +1,175 @@ # DKFZ # # # Copyright (c) German Cancer Research Center, # Division of Medical Image Computing. # All rights reserved. # # This software is distributed WITHOUT ANY WARRANTY; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. # # See LICENSE import unittest import matplotlib.pylab as plt from hyppopy.solvers.RandomsearchSolver import * from hyppopy.VirtualFunction import VirtualFunction from hyppopy.HyppopyProject import HyppopyProject class RandomsearchTestSuite(unittest.TestCase): def setUp(self): pass def test_draw_uniform_sample(self): param = {"data": [0, 1, 10], "type": "float"} values = [] for i in range(10000): values.append(draw_uniform_sample(param)) self.assertTrue(0 <= values[-1] <= 1) self.assertTrue(isinstance(values[-1], float)) hist = plt.hist(values, bins=10, normed=True) std = np.std(hist[0]) mean = np.mean(hist[0]) self.assertTrue(std < 0.05) self.assertTrue(0.9 < mean < 1.1) param = {"data": [0, 10, 11], "type": "int"} values = [] for i in range(10000): values.append(draw_uniform_sample(param)) self.assertTrue(0 <= values[-1] <= 10) self.assertTrue(isinstance(values[-1], int)) hist = plt.hist(values, bins=11, normed=True) std = np.std(hist[0]) mean = np.mean(hist[0]) self.assertTrue(std < 0.05) self.assertTrue(0.09 < mean < 0.11) def test_draw_normal_sample(self): param = {"data": [0, 10, 11], "type": "int"} values = [] for i in range(10000): values.append(draw_normal_sample(param)) self.assertTrue(0 <= values[-1] <= 10) self.assertTrue(isinstance(values[-1], int)) hist = plt.hist(values, bins=11, normed=True) for i in range(1, 5): self.assertTrue(hist[0][i-1]-hist[0][i] < 0) for i in range(5, 10): self.assertTrue(hist[0][i] - hist[0][i+1] > 0) def test_draw_loguniform_sample(self): param = {"data": [1, 1000, 11], "type": "float"} values = [] for i in range(10000): values.append(draw_loguniform_sample(param)) self.assertTrue(1 <= values[-1] <= 1000) self.assertTrue(isinstance(values[-1], float)) hist = plt.hist(values, bins=11, normed=True) for i in range(4): self.assertTrue(hist[0][i] > hist[0][i+1]) self.assertTrue((hist[0][i] - hist[0][i+1]) > 0) def test_draw_categorical_sample(self): param = {"data": [1, 2, 3], "type": int} values = [] for i in range(10000): values.append(draw_categorical_sample(param)) self.assertTrue(values[-1] == 1 or values[-1] == 2 or values[-1] == 3) self.assertTrue(isinstance(values[-1], int)) hist = plt.hist(values, bins=3, normed=True) for i in range(3): self.assertTrue(0.45 < hist[0][i] < 0.55) - def test_solver_complete(self): + def test_solver_uniform(self): config = { "hyperparameter": { "axis_00": { - "domain": "normal", - "data": [300, 800], + "domain": "uniform", + "data": [0, 800], "type": "float" }, "axis_01": { "domain": "uniform", "data": [-1, 1], "type": "float" }, "axis_02": { "domain": "uniform", "data": [0, 10], "type": "float" } }, "settings": { - "solver": {"max_iterations": 100}, + "solver": {"max_iterations": 10000}, + "custom": {} + }} + + project = HyppopyProject(config) + solver = RandomsearchSolver(project) + vfunc = VirtualFunction() + vfunc.load_default() + solver.blackbox = vfunc + solver.run(print_stats=False) + df, best = solver.get_results() + self.assertTrue(570 <= best['axis_00'] <= 585) + self.assertTrue(0.2 <= best['axis_01'] <= 0.8) + self.assertTrue(4 <= best['axis_02'] <= 6) + + for status in df['status']: + self.assertTrue(status) + for loss in df['losses']: + self.assertTrue(isinstance(loss, float)) + + def test_solver_normal(self): + config = { + "hyperparameter": { + "axis_00": { + "domain": "normal", + "data": [500, 650], + "type": "float" + }, + "axis_01": { + "domain": "normal", + "data": [0, 1], + "type": "float" + }, + "axis_02": { + "domain": "normal", + "data": [4, 5], + "type": "float" + } + }, + "settings": { + "solver": {"max_iterations": 500}, "custom": {} }} project = HyppopyProject(config) solver = RandomsearchSolver(project) vfunc = VirtualFunction() vfunc.load_default() solver.blackbox = vfunc solver.run(print_stats=False) df, best = solver.get_results() - self.assertTrue(300 <= best['axis_00'] <= 800) - self.assertTrue(-1 <= best['axis_01'] <= 1) - self.assertTrue(0 <= best['axis_02'] <= 10) + self.assertTrue(570 <= best['axis_00'] <= 585) + self.assertTrue(0.2 <= best['axis_01'] <= 0.8) + self.assertTrue(4.5 <= best['axis_02'] <= 5.5) for status in df['status']: self.assertTrue(status) for loss in df['losses']: self.assertTrue(isinstance(loss, float)) if __name__ == '__main__': unittest.main()