def convert_search_space(spec: Dict, prefix: str = "") -> Dict: spec = copy.deepcopy(spec) resolved_vars, domain_vars, grid_vars = parse_spec_vars(spec) if not domain_vars and not grid_vars: return {} if grid_vars: raise ValueError( "Grid search parameters cannot be automatically converted " "to a HyperOpt search space.") def resolve_value(par: str, domain: Domain) -> Any: quantize = None sampler = domain.get_sampler() if isinstance(sampler, Quantized): quantize = sampler.q sampler = sampler.sampler if isinstance(domain, Float): if isinstance(sampler, LogUniform): if quantize: return hpo.hp.qloguniform(par, np.log(domain.lower), np.log(domain.upper), quantize) return hpo.hp.loguniform(par, np.log(domain.lower), np.log(domain.upper)) elif isinstance(sampler, Uniform): if quantize: return hpo.hp.quniform(par, domain.lower, domain.upper, quantize) return hpo.hp.uniform(par, domain.lower, domain.upper) elif isinstance(sampler, Normal): if quantize: return hpo.hp.qnormal(par, sampler.mean, sampler.sd, quantize) return hpo.hp.normal(par, sampler.mean, sampler.sd) elif isinstance(domain, Integer): if isinstance(sampler, LogUniform): if quantize: return hpo.base.pyll.scope.int( hpo.hp.qloguniform( par, np.log(domain.lower), np.log(domain.upper), quantize, )) return hpo.base.pyll.scope.int( hpo.hp.qloguniform(par, np.log(domain.lower), np.log(domain.upper - 1), 1.0)) elif isinstance(sampler, Uniform): if quantize: return hpo.base.pyll.scope.int( hpo.hp.quniform(par, domain.lower, domain.upper - 1, quantize)) return hpo.hp.uniformint(par, domain.lower, high=domain.upper - 1) elif isinstance(domain, Categorical): if isinstance(sampler, Uniform): return hpo.hp.choice( par, [ HyperOptSearch.convert_search_space(category, prefix=par) if isinstance(category, dict) else HyperOptSearch.convert_search_space( dict(enumerate(category)), prefix=f"{par}/{i}") if isinstance(category, list) else resolve_value(f"{par}/{i}", category) if isinstance(category, Domain) else category for i, category in enumerate(domain.categories) ], ) raise ValueError("HyperOpt does not support parameters of type " "`{}` with samplers of type `{}`".format( type(domain).__name__, type(domain.sampler).__name__)) for path, domain in domain_vars: par = "/".join( [str(p) for p in ((prefix, ) + path if prefix else path)]) value = resolve_value(par, domain) assign_value(spec, path, value) return spec
def convert_search_space(spec: Dict, prefix: str = "") -> Dict: spec = copy.deepcopy(spec) resolved_vars, domain_vars, grid_vars = parse_spec_vars(spec) if not domain_vars and not grid_vars: return {} if grid_vars: raise ValueError( "Grid search parameters cannot be automatically converted " "to a HyperOpt search space.") def resolve_value(par: str, domain: Domain) -> Any: quantize = None sampler = domain.get_sampler() if isinstance(sampler, Quantized): quantize = sampler.q sampler = sampler.sampler if isinstance(domain, Float): if isinstance(sampler, LogUniform): if quantize: return hpo.hp.qloguniform(par, domain.lower, domain.upper, quantize) return hpo.hp.loguniform(par, np.log(domain.lower), np.log(domain.upper)) elif isinstance(sampler, Uniform): if quantize: return hpo.hp.quniform(par, domain.lower, domain.upper, quantize) return hpo.hp.uniform(par, domain.lower, domain.upper) elif isinstance(sampler, Normal): if quantize: return hpo.hp.qnormal(par, sampler.mean, sampler.sd, quantize) return hpo.hp.normal(par, sampler.mean, sampler.sd) elif isinstance(domain, Integer): if isinstance(sampler, Uniform): if quantize: logger.warning( "HyperOpt does not support quantization for " "integer values. Reverting back to 'randint'.") if domain.lower != 0: raise ValueError( "HyperOpt only allows integer sampling with " f"lower bound 0. Got: {domain.lower}.") if domain.upper < 1: raise ValueError( "HyperOpt does not support integer sampling " "of values lower than 0. Set your maximum range " "to something above 0 (currently {})".format( domain.upper)) return hpo.hp.randint(par, domain.upper) elif isinstance(domain, Categorical): if isinstance(sampler, Uniform): return hpo.hp.choice(par, [ HyperOptSearch.convert_search_space(category, prefix=par) if isinstance(category, dict) else HyperOptSearch.convert_search_space( dict(enumerate(category)), prefix=f"{par}/{i}") if isinstance(category, list) else resolve_value(f"{par}/{i}", category) if isinstance( category, Domain) else category for i, category in enumerate(domain.categories) ]) raise ValueError("HyperOpt does not support parameters of type " "`{}` with samplers of type `{}`".format( type(domain).__name__, type(domain.sampler).__name__)) for path, domain in domain_vars: par = "/".join( [str(p) for p in ((prefix, ) + path if prefix else path)]) value = resolve_value(par, domain) assign_value(spec, path, value) return spec