def __init__(self, bandit, seed=seed, cmd=None, workdir=None): self.bandit = bandit self.seed = seed self.rng = np.random.RandomState(self.seed) self.cmd = cmd self.workdir = workdir self.s_new_ids = pyll.Literal('new_ids') # -- list at eval-time before = pyll.dfs(self.bandit.expr) # -- raises exception if expr contains cycles pyll.toposort(self.bandit.expr) vh = self.vh = VectorizeHelper(self.bandit.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.bandit.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.bandit.params.keys()) # -- make the graph runnable and SON-encodable # N.B. operates inplace self.s_idxs_vals = recursive_set_rng_kwarg( scope.pos_args(idxs_by_label, vals_by_label), pyll.as_apply(self.rng)) # -- raises an exception if no topological ordering exists pyll.toposort(self.s_idxs_vals)
def __init__(self, fn, expr, workdir=None, pass_expr_memo_ctrl=None, **bandit_kwargs): self.cmd = ('domain_attachment', 'FMinIter_Domain') 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 Bandit.__init__(self, expr, do_checks=False, **bandit_kwargs) # -- This code was stolen from base.BanditAlgo, a class which may soon # be gone 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)
def tpe_transform(domain, prior_weight, gamma): s_prior_weight = pyll.Literal(float(prior_weight)) # -- these dummy values will be replaced in suggest1() and never used observed = dict( idxs=pyll.Literal(), vals=pyll.Literal()) observed_loss = dict( idxs=pyll.Literal(), vals=pyll.Literal()) specs, idxs, vals = build_posterior( # -- vectorized clone of bandit template domain.vh.v_expr, # -- this dict and next represent prior dists domain.vh.idxs_by_label(), domain.vh.vals_by_label(), observed['idxs'], observed['vals'], observed_loss['idxs'], observed_loss['vals'], pyll.Literal(gamma), s_prior_weight ) return (s_prior_weight, observed, observed_loss, specs, idxs, vals)
def __init__(self, bandit, gamma=gamma, prior_weight=prior_weight, n_EI_candidates=n_EI_candidates, n_startup_jobs=n_startup_jobs, linear_forgetting=linear_forgetting, **kwargs): BanditAlgo.__init__(self, bandit, **kwargs) self.gamma = gamma self.prior_weight = prior_weight self.n_EI_candidates = n_EI_candidates self.n_startup_jobs = n_startup_jobs self.linear_forgetting = linear_forgetting if linear_forgetting != DEFAULT_LF: raise NotImplementedError( 'linear_forgetting is not passed around properly') self.s_prior_weight = pyll.Literal(float(self.prior_weight)) # -- these dummy values will be replaced in suggest1() and never used self.observed = dict( idxs=pyll.Literal(), vals=pyll.Literal()) self.observed_loss = dict( idxs=pyll.Literal(), vals=pyll.Literal()) specs, idxs, vals = build_posterior( # -- vectorized clone of bandit template self.vh.v_expr, # -- this dict and next represent prior dists self.vh.idxs_by_label(), self.vh.vals_by_label(), self.observed['idxs'], self.observed['vals'], self.observed_loss['idxs'], self.observed_loss['vals'], pyll.Literal(self.gamma), self.s_prior_weight ) self.opt_specs = specs self.opt_idxs = idxs self.opt_vals = vals
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')
def work(self, **kwargs): self.__dict__.update(kwargs) bandit = opt_q_uniform(self.target) prior_weight = 2.5 gamma = 0.20 algo = TreeParzenEstimator(bandit, prior_weight=prior_weight, n_startup_jobs=2, n_EI_candidates=128, gamma=gamma) print algo.opt_idxs['x'] print algo.opt_vals['x'] trials = Trials() experiment = Experiment(trials, algo) experiment.run(self.LEN) if self.show_vars: import hyperopt.plotting hyperopt.plotting.main_plot_vars(trials, bandit, do_show=1) idxs, vals = miscs_to_idxs_vals(trials.miscs) idxs = idxs['x'] vals = vals['x'] print "VALS", vals losses = trials.losses() from hyperopt.tpe import ap_filter_trials from hyperopt.tpe import adaptive_parzen_samplers qu = scope.quniform(1.01, 10, 1) fn = adaptive_parzen_samplers['quniform'] fn_kwargs = dict(size=(4, ), rng=np.random) s_below = pyll.Literal() s_above = pyll.Literal() b_args = [s_below, prior_weight] + qu.pos_args b_post = fn(*b_args, **fn_kwargs) a_args = [s_above, prior_weight] + qu.pos_args a_post = fn(*a_args, **fn_kwargs) #print b_post #print a_post fn_lpdf = getattr(scope, a_post.name + '_lpdf') print fn_lpdf # calculate the llik of b_post under both distributions a_kwargs = dict([(n, a) for n, a in a_post.named_args if n not in ('rng', 'size')]) b_kwargs = dict([(n, a) for n, a in b_post.named_args if n not in ('rng', 'size')]) below_llik = fn_lpdf(*([b_post] + b_post.pos_args), **b_kwargs) above_llik = fn_lpdf(*([b_post] + a_post.pos_args), **a_kwargs) new_node = scope.broadcast_best(b_post, below_llik, above_llik) print '=' * 80 do_show = self.show_steps import matplotlib.pyplot as plt for ii in range(2, 9): if ii > len(idxs): break print '-' * 80 print 'ROUND', ii print '-' * 80 all_vals = [2, 3, 4, 5, 6, 7, 8, 9, 10] below, above = ap_filter_trials(idxs[:ii], vals[:ii], idxs[:ii], losses[:ii], gamma) below = below.astype('int') above = above.astype('int') print 'BB0', below print 'BB1', above #print 'BELOW', zip(range(100), np.bincount(below, minlength=11)) #print 'ABOVE', zip(range(100), np.bincount(above, minlength=11)) memo = {b_post: all_vals, s_below: below, s_above: above} bl, al, nv = pyll.rec_eval([below_llik, above_llik, new_node], memo=memo) #print bl - al print 'BB2', dict(zip(all_vals, bl - al)) print 'BB3', dict(zip(all_vals, bl)) print 'BB4', dict(zip(all_vals, al)) print 'ORIG PICKED', vals[ii] print 'PROPER OPT PICKS:', nv #assert np.allclose(below, [3, 3, 9]) #assert len(below) + len(above) == len(vals) if do_show: plt.subplot(8, 1, ii) #plt.scatter(all_vals, # np.bincount(below, minlength=11)[2:], c='b') #plt.scatter(all_vals, # np.bincount(above, minlength=11)[2:], c='c') plt.scatter(all_vals, bl, c='g') plt.scatter(all_vals, al, c='r') if do_show: plt.show()