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()
def build_posterior(specs, prior_idxs, prior_vals, obs_idxs, obs_vals, oloss_idxs, oloss_vals, oloss_gamma, prior_weight): """ This method clones a posterior inference graph by iterating forward in topological order, and replacing prior random-variables (prior_vals) with new posterior distributions that make use of observations (obs_vals). """ assert all(isinstance(arg, pyll.Apply) for arg in [oloss_idxs, oloss_vals, oloss_gamma]) expr = pyll.as_apply([specs, prior_idxs, prior_vals]) nodes = pyll.dfs(expr) # build the joint posterior distribution as the values in this memo memo = {} # map prior RVs to observations obs_memo = {} for nid in prior_vals: # construct the leading args for each call to adaptive_parzen_sampler # which will permit the "adaptive parzen samplers" to adapt to the # correct samples. obs_below, obs_above = scope.ap_filter_trials( obs_idxs[nid], obs_vals[nid], oloss_idxs, oloss_vals, oloss_gamma) obs_memo[prior_vals[nid]] = [obs_below, obs_above] for node in nodes: if node not in memo: new_inputs = [memo[arg] for arg in node.inputs()] if node in obs_memo: # -- this case corresponds to an observed Random Var # node.name is a distribution like "normal", "randint", etc. obs_below, obs_above = obs_memo[node] aa = [memo[a] for a in node.pos_args] fn = adaptive_parzen_samplers[node.name] b_args = [obs_below, prior_weight] + aa named_args = [[kw, memo[arg]] for (kw, arg) in node.named_args] b_post = fn(*b_args, **dict(named_args)) a_args = [obs_above, prior_weight] + aa a_post = fn(*a_args, **dict(named_args)) assert a_post.name == b_post.name fn_lpdf = getattr(scope, a_post.name + '_lpdf') #print fn_lpdf 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')]) # calculate the llik of b_post under both distributions below_llik = fn_lpdf(*([b_post] + b_post.pos_args), **b_kwargs) above_llik = fn_lpdf(*([b_post] + a_post.pos_args), **a_kwargs) #improvement = below_llik - above_llik #new_node = scope.broadcast_best(b_post, improvement) new_node = scope.broadcast_best(b_post, below_llik, above_llik) elif hasattr(node, 'obj'): # -- keep same literals in the graph new_node = node else: # -- this case is for all the other stuff in the graph new_node = node.clone_from_inputs(new_inputs) memo[node] = new_node post_specs = memo[specs] post_idxs = dict([(nid, memo[idxs]) for nid, idxs in prior_idxs.items()]) post_vals = dict([(nid, memo[vals]) for nid, vals in prior_vals.items()]) assert set(post_idxs.keys()) == set(post_vals.keys()) assert set(post_idxs.keys()) == set(prior_idxs.keys()) return post_specs, post_idxs, post_vals
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()