diff --git a/hyppopy/HyppopyProject.py b/hyppopy/HyppopyProject.py index ef5f22b..5f41feb 100644 --- a/hyppopy/HyppopyProject.py +++ b/hyppopy/HyppopyProject.py @@ -1,101 +1,111 @@ # 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 warnings from hyppopy.globals import * LOG = logging.getLogger(os.path.basename(__file__)) LOG.setLevel(DEBUGLEVEL) class HyppopyProject(object): def __init__(self, config=None): self._hyperparameter = {} self._settings = {} self._extmembers = [] if config is not None: self.set_config(config) def clear(self): self._hyperparameter = {} self._settings = {} for added in self._extmembers: if added in self.__dict__.keys(): del self.__dict__[added] self._extmembers = [] def set_config(self, config): self.clear() assert isinstance(config, dict), "Input Error, config of type {} not supported!".format(type(config)) assert HYPERPARAMETERPATH in config.keys(), "Missing hyperparameter section in config dict" #assert SETTINGSPATH in config.keys(), "Missing settings section in config dict" if not SETTINGSPATH in config.keys(): config[SETTINGSPATH] = {"solver": {"max_iterations": DEFAULTITERATIONS}} msg = "config dict had no section {0}/solver/max_iterations, set default value: {1}".format(SETTINGSPATH, DEFAULTITERATIONS) warnings.warn(msg) LOG.warning(msg) self._hyperparameter = config[HYPERPARAMETERPATH] self._settings = config[SETTINGSPATH] self.parse_members() - def add_hyperparameter(self, name, domain, data, dtype): + def add_hyperparameter(self, **kwargs): + assert 'name' in kwargs.keys(), "precondition violation, obligatory parameter name not found!" + assert 'domain' in kwargs.keys(), "precondition violation, obligatory parameter domain not found!" + assert 'data' in kwargs.keys(), "precondition violation, obligatory parameter data not found!" + assert 'dtype' in kwargs.keys(), "precondition violation, obligatory parameter dtype not found!" + name = kwargs['name']; del kwargs['name'] + domain = kwargs['domain']; del kwargs['domain'] + data = kwargs['data']; del kwargs['data'] + dtype = kwargs['dtype']; del kwargs['dtype'] assert isinstance(name, str), "precondition violation, name of type {} not allowed, expect str!".format(type(name)) assert isinstance(domain, str), "precondition violation, domain of type {} not allowed, expect str!".format(type(domain)) assert domain in SUPPORTED_DOMAINS, "domain {} not supported, expect {}!".format(domain, SUPPORTED_DOMAINS) assert isinstance(data, list) or isinstance(data, tuple), "precondition violation, data of type {} not allowed, expect list or tuple!".format(type(data)) if domain != "categorical": assert len(data) == 3 or len(data) == 2, "precondition violation, data must be a list of len 2 or 3" assert isinstance(dtype, str), "precondition violation, dtype of type {} not allowed, expect str!".format(type(dtype)) assert dtype in SUPPORTED_DTYPES, "precondition violation, dtype {} not supported, expect {}!".format(dtype, SUPPORTED_DTYPES) self._hyperparameter[name] = {"domain": domain, "data": data, "type": dtype} + for key, value in kwargs.items(): + self._hyperparameter[name][key] = value def add_settings(self, section, name, value): assert isinstance(section, str), "precondition violation, section of type {} not allowed, expect str!".format(type(section)) assert isinstance(name, str), "precondition violation, name of type {} not allowed, expect str!".format(type(name)) if section not in self._settings.keys(): self._settings[section] = {} self._settings[section][name] = value self.parse_members() def parse_members(self): for section_name, content in self.settings.items(): for name, value in content.items(): member_name = section_name + "_" + name if member_name not in self._extmembers: setattr(self, member_name, value) self._extmembers.append(member_name) else: self.__dict__[member_name] = value def get_typeof(self, hyperparametername): if not hyperparametername in self.hyperparameter.keys(): return None dtype = self.hyperparameter[hyperparametername]["type"] if dtype == 'str': return str if dtype == 'int': return int if dtype == 'float': return float @property def hyperparameter(self): return self._hyperparameter @property def settings(self): return self._settings diff --git a/hyppopy/tests/test_randomsearchsolver.py b/hyppopy/tests/test_randomsearchsolver.py index f914302..58417dc 100644 --- a/hyppopy/tests/test_randomsearchsolver.py +++ b/hyppopy/tests/test_randomsearchsolver.py @@ -1,175 +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_uniform(self): config = { "hyperparameter": { "axis_00": { "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": 10000}, + "solver": {"max_iterations": 300}, "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) + 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)) 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(570 <= best['axis_00'] <= 585) - self.assertTrue(0.2 <= best['axis_01'] <= 0.8) - self.assertTrue(4.5 <= best['axis_02'] <= 5.5) + self.assertTrue(500 <= best['axis_00'] <= 650) + self.assertTrue(0 <= best['axis_01'] <= 1) + self.assertTrue(4 <= best['axis_02'] <= 5) for status in df['status']: self.assertTrue(status) for loss in df['losses']: self.assertTrue(isinstance(loss, float)) if __name__ == '__main__': unittest.main()