def test_clone(): config = config0() config2 = clone(config) nodeset = set(dfs(config)) assert not any(n in nodeset for n in dfs(config2)) foo = recursive_set_rng_kwarg(config, scope.rng_from_seed(5)) r = rec_eval(foo) print r r2 = rec_eval(recursive_set_rng_kwarg(config2, scope.rng_from_seed(5))) print r2 assert r == r2
def test_clone(): config = config0() config2 = clone(config) nodeset = set(dfs(config)) assert not any(n in nodeset for n in dfs(config2)) foo = recursive_set_rng_kwarg( config, scope.rng_from_seed(5)) r = rec_eval(foo) print(r) r2 = rec_eval( recursive_set_rng_kwarg( config2, scope.rng_from_seed(5))) print(r2) assert r == r2
def memo_from_config(self, config): memo = {} for node in pyll.dfs(self.expr): if node.name == 'hyperopt_param': label = node.arg['label'].obj # -- hack because it's not really garbagecollected # this does have the desired effect of crashing the # function if rec_eval actually needs a value that # the the optimization algorithm thought to be unnecessary memo[node] = config.get(label, pyll.base.GarbageCollected) return memo
def work(self): """Test that all prior samplers are gone""" tpe_algo = TreeParzenEstimator(self.bandit) foo = pyll.as_apply( [tpe_algo.post_below['idxs'], tpe_algo.post_below['vals']]) prior_names = [ 'uniform', 'quniform', 'loguniform', 'qloguniform', 'normal', 'qnormal', 'lognormal', 'qlognormal', 'randint', ] for node in pyll.dfs(foo): assert node.name not in prior_names
def use_obj_for_literal_in_memo(expr, obj, lit, memo): """ Set `memo[node] = obj` for all nodes in expr such that `node.obj == lit` This is a useful routine for fmin-compatible functions that are searching domains that include some leaf nodes that are complicated runtime-generated objects. One option is to make such leaf nodes pyll functions, but it can be easier to construct those objects the normal Python way in the fmin function, and just stick them into the evaluation memo. The experiment ctrl object itself is inserted using this technique. """ for node in pyll.dfs(expr): try: if node.obj == lit: memo[node] = obj except AttributeError: # -- non-literal nodes don't have node.obj pass return memo
def work(self): """Test that all prior samplers are gone""" tpe_algo = TreeParzenEstimator(self.bandit) foo = pyll.as_apply([ tpe_algo.post_below['idxs'], tpe_algo.post_below['vals']]) prior_names = [ 'uniform', 'quniform', 'loguniform', 'qloguniform', 'normal', 'qnormal', 'lognormal', 'qlognormal', 'randint', ] for node in pyll.dfs(foo): assert node.name not in prior_names
def get_args(params): memo = {node: params[node.arg['label'].obj] for node in pyll.dfs(expr) if node.name == 'hyperopt_param'} return pyll.rec_eval(expr, memo=memo)
len(df_cuisine['cuisine_parent'].unique()), #'device_type':'gpu', #'max_bin': 63, 'num_threads': 0 } # get first level of parameters param_keys = list(params.keys()) # search through hyperopt distributions for choices dict_nodes = [] for k, v in params.items(): try: dict_nodes.extend( [node for node in pyll.dfs(v) if node.name == 'dict']) except: pass # in nodes that are dictionaries (i.e. the list of dictionary choices) for d in dict_nodes: for param in d.named_args: param_keys.append(param[0]) # use set to remove duplicates param_keys = sorted(list(set(param_keys))) N_FOLDS = 3 def objective(params, n_folds=N_FOLDS): """Objective function for Gradient Boosting Machine Hyperparameter Optimization"""
def __init__(self, fn, expr, workdir=None, pass_expr_memo_ctrl=None, name=None, loss_target=None, ): """ Paramaters ---------- fn : callable This stores the `fn` argument to `fmin`. (See `hyperopt.fmin.fmin`) expr : hyperopt.pyll.Apply This is the `space` argument to `fmin`. (See `hyperopt.fmin.fmin`) workdir : string (or None) If non-None, the current working directory will be `workdir`while `expr` and `fn` are evaluated. (XXX Currently only respected by jobs run via MongoWorker) pass_expr_memo_ctrl : bool If True, `fn` will be called like this: `fn(self.expr, memo, ctrl)`, where `memo` is a dictionary mapping `Apply` nodes to their computed values, and `ctrl` is a `Ctrl` instance for communicating with a Trials database. This lower-level calling convention is useful if you want to call e.g. `hyperopt.pyll.rec_eval` yourself in some customized way. name : string (or None) Label, used for pretty-printing. loss_target : float (or None) The actual or estimated minimum of `fn`. Some optimization algorithms may behave differently if their first objective is to find an input that achieves a certain value, rather than the more open-ended objective of pure minimization. XXX: Move this from Domain to be an fmin arg. """ self.fn = fn if pass_expr_memo_ctrl is None: self.pass_expr_memo_ctrl = getattr(fn, 'fmin_pass_expr_memo_ctrl', False) else: self.pass_expr_memo_ctrl = pass_expr_memo_ctrl self.expr = pyll.as_apply(expr) self.params = {} for node in pyll.dfs(self.expr): if node.name == 'hyperopt_param': label = node.arg['label'].obj if label in self.params: raise DuplicateLabel(label) self.params[label] = node.arg['obj'] self.loss_target = loss_target self.name = name self.workdir = workdir self.s_new_ids = pyll.Literal('new_ids') # -- list at eval-time before = pyll.dfs(self.expr) # -- raises exception if expr contains cycles pyll.toposort(self.expr) vh = self.vh = VectorizeHelper(self.expr, self.s_new_ids) # -- raises exception if v_expr contains cycles pyll.toposort(vh.v_expr) idxs_by_label = vh.idxs_by_label() vals_by_label = vh.vals_by_label() after = pyll.dfs(self.expr) # -- try to detect if VectorizeHelper screwed up anything inplace assert before == after assert set(idxs_by_label.keys()) == set(vals_by_label.keys()) assert set(idxs_by_label.keys()) == set(self.params.keys()) self.s_rng = pyll.Literal('rng-placeholder') # -- N.B. operates inplace: self.s_idxs_vals = recursive_set_rng_kwarg( pyll.scope.pos_args(idxs_by_label, vals_by_label), self.s_rng) # -- raises an exception if no topological ordering exists pyll.toposort(self.s_idxs_vals) # -- Protocol for serialization. # self.cmd indicates to e.g. MongoWorker how this domain # should be [un]serialized. # XXX This mechanism deserves review as support for ipython # workers improves. self.cmd = ('domain_attachment', 'FMinIter_Domain')