def draw_final_figure(sample_cost, vis_confs, inc_eq_loc_x, draw_improvement=True, draw_normals=True): fig, ax = draw_basic_figure_plus_zone() labels = [r'$\lambda_%d$' % (idx + 1) for idx in range(len(vis_confs))] boplot.highlight_configuration( x=np.array(vis_confs), label=labels, lloc='bottom', ax=ax, disable_ticks=True ) for label, conf in zip(labels, vis_confs): boplot.annotate_x_edge( label=label, xy=(conf + 0.6 * (ax.get_xlim()[1] - ax.get_xlim()[0]) / 10, ymin), ax=ax, align='bottom', offset_param=1.9 ) boplot.highlight_output( y=np.array([sample_cost, ymin]), label=['c', '$c_{inc}$'], lloc='left', ax=ax ) # boplot.annotate_y_edge(label=r'c', xy=(lambda, cost), align='left', ax=ax) if draw_improvement: ax.annotate(s='', xy=(inc_eq_loc_x, sample_cost), xytext=(inc_eq_loc_x, ymin), arrowprops={'arrowstyle': 'simple', }) ax.text(inc_eq_loc_x - 1.0, sample_cost - 1.0, r'$I_c=c_{inc}-c$', weight='heavy') if draw_normals: for idx in range(len(vis_confs)): conf = vis_confs[idx] draw_distribution_for_candidate(ax=ax, candidate=conf, target_cost=sample_cost) ax.annotate( s=r"$p(c|\lambda_%d)$" % (idx+1), xy=(conf, sample_cost), xytext=(conf-1.8, sample_cost - 1.5), arrowprops={'arrowstyle': 'fancy', 'shrinkA': 20.0}, weight='heavy', color='darkgreen', zorder=zorders['annotations_high'] ) return fig, ax
def run_bo(acquisition, max_iter, initial_design, acq_add, init=None): """ BO :param acquisition: type of acquisition function to be used :param max_iter: max number of function calls :param seed: seed used to keep experiments reproducible :param initial_design: Method for initializing the GP, choice between 'uniform', 'random', and 'presentation' :param acq_add: additional parameteres for acquisition function (e.g. kappa for LCB) :param init: Number of datapoints to initialize GP with. :return: all evaluated points. """ logging.debug("Running BO with Acquisition Function {0}, maximum iterations {1}, initial design {2}, " "acq_add {3} and init {4}".format(acquisition, max_iter, initial_design, acq_add, init)) x, y = initialize_dataset(initial_design=initial_design, init=init) logging.debug("Initialized dataset with:\nsamples {0}\nObservations {1}".format(x, y)) for i in range(1, max_iter): # BO loop logging.debug('Sample #%d' % (i)) # Fit GP to the currently available dataset gp = GPR(kernel=Matern()) logging.debug("Fitting GP to\nx: {}\ny:{}".format(x, y)) gp.fit(x, y) # fit the model # ----------Plotting calls--------------- fig, (ax1, ax2) = plt.subplots(2, 1, squeeze=True) fig.tight_layout() ax1.set_xlim(bounds["x"]) ax1.set_ylim(bounds["gp_y"]) ax1.grid() ax2.set_xlim(bounds["x"]) ax2.set_ylim(bounds["acq_y"]) ax2.grid() boplot.plot_objective_function(ax=ax1) boplot.plot_gp(model=gp, confidence_intervals=[1.0, 2.0], ax=ax1, custom_x=x) boplot.mark_observations(X_=x, Y_=y, ax=ax1) # --------------------------------------- # noinspection PyStringFormat logging.debug("Model fit to dataset.\nOriginal Inputs: {0}\nOriginal Observations: {1}\n" "Predicted Means: {2}\nPredicted STDs: {3}".format(x, y, *(gp.predict(x, return_std=True)))) # Partially initialize the acquisition function to work with the fmin interface # (only the x parameter is not specified) acqui = partial(acquisition, model=gp, eta=min(y), add=acq_add) boplot.plot_acquisition_function(acquisition, min(y), gp, acq_add, invert=True, ax=ax2) # optimize acquisition function, repeat 10 times, use best result x_ = None y_ = 10000 # Feel free to adjust the hyperparameters for j in range(NUM_ACQ_OPTS): opt_res = minimize(acqui, np.random.uniform(bounds["x"][0], bounds["x"][1]), #bounds=bounds["x"], options={'maxfun': 20, 'maxiter': 20}, method="L-BFGS-B") if opt_res.fun[0] < y_: x_ = opt_res.x y_ = opt_res.fun[0] # ----------Plotting calls--------------- boplot.highlight_configuration(x_, ax=ax1) boplot.highlight_configuration(x_, ax=ax2) # --------------------------------------- # Update dataset with new observation x.append(x_) y.append(f(x_)) logging.info("After {0}. loop iteration".format(i)) logging.info("x: {0:.3E}, y: {1:.3E}".format(x_[0], y_)) # ----------Plotting calls--------------- for ax in (ax1, ax2): ax.legend() ax.set_xlabel(labels['xlabel']) ax1.set_ylabel(labels['gp_ylabel']) ax1.set_title("Visualization of GP", loc='left') ax2.set_title("Visualization of Acquisition Function", loc='left') ax2.set_ylabel(labels['acq_ylabel']) if TOGGLE_PRINT: plt.savefig("plot_{}.pdf".format(i), dpi='figure') else: plt.show() # --------------------------------------- return y
def visualize_ei(initial_design, init=None): """ Visualize one-step of EI. :param initial_design: Method for initializing the GP, choice between 'uniform', 'random', and 'presentation' :param init: Number of datapoints to initialize GP with. :return: None """ # 1. Plot GP fit on initial dataset # 2. Mark current incumbent # 3. Mark Zone of Probable Improvement # 4. Mark Hypothetical Real cost of a random configuration # 5. Display I(lambda) # 6. Display Vertical Normal Distribution # boplot.set_rcparams(**{'legend.loc': 'lower left'}) logging.debug("Visualizing EI with initial design {} and init {}".format(initial_design, init)) # Initialize dummy dataset x, y = initialize_dataset(initial_design=initial_design, init=init) ymin_arg = np.argmin(y) ymin = y[ymin_arg] logging.debug("Initialized dataset with:\nsamples {0}\nObservations {1}".format(x, y)) # Fit GP to the currently available dataset gp = GPR(kernel=Matern()) logging.debug("Fitting GP to\nx: {}\ny:{}".format(x, y)) gp.fit(x, y) # fit the model mu_star_t_xy = get_mu_star(gp) logging.info("Mu-star at time t: {}".format(mu_star_t_xy)) # noinspection PyStringFormat logging.debug("Model fit to dataset.\nOriginal Inputs: {0}\nOriginal Observations: {1}\n" "Predicted Means: {2}\nPredicted STDs: {3}".format(x, y, *(gp.predict(x, return_std=True)))) # 1. Plot GP fit on initial dataset # -------------Plotting code ----------------- fig, ax = plt.subplots(1, 1, squeeze=True) ax.set_xlim(bounds["x"]) ax.set_ylim(bounds["gp_y"]) ax.grid() boplot.plot_gp(model=gp, confidence_intervals=[2.0], custom_x=x, ax=ax) boplot.plot_objective_function(ax=ax) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=False, highlight_datapoint=None, highlight_label=None, ax=ax) ax.legend().set_zorder(20) ax.set_xlabel(labels['xlabel']) ax.set_ylabel(labels['gp_ylabel']) ax.set_title(r"Visualization of $\mathcal{G}^{(t)}$", loc='left') plt.tight_layout() if TOGGLE_PRINT: plt.savefig("ei_1.pdf") else: plt.show() # ------------------------------------------- # 2. Mark current incumbent # -------------Plotting code ----------------- fig, ax = plt.subplots(1, 1, squeeze=True) ax.set_xlim(bounds["x"]) ax.set_ylim(bounds["gp_y"]) ax.grid() boplot.plot_gp(model=gp, confidence_intervals=[2.0], custom_x=x, ax=ax) boplot.plot_objective_function(ax=ax) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=True, highlight_datapoint=None, highlight_label=None, ax=ax) ax.legend().set_zorder(20) ax.set_xlabel(labels['xlabel']) ax.set_ylabel(labels['gp_ylabel']) ax.set_title(r"Visualization of $\mathcal{G}^{(t)}$", loc='left') plt.tight_layout() if TOGGLE_PRINT: plt.savefig("ei_2.pdf") else: plt.show() # ------------------------------------------- # 3. Mark Zone of Probable Improvement # -------------Plotting code ----------------- fig, ax = plt.subplots(1, 1, squeeze=True) ax.set_xlim(bounds["x"]) ax.set_ylim(bounds["gp_y"]) ax.grid() boplot.plot_gp(model=gp, confidence_intervals=[2.0], custom_x=x, ax=ax) boplot.plot_objective_function(ax=ax) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=True, highlight_datapoint=None, highlight_label=None, ax=ax) boplot.darken_graph(y=ymin, ax=ax) ax.legend().set_zorder(20) ax.set_xlabel(labels['xlabel']) ax.set_ylabel(labels['gp_ylabel']) ax.set_title(r"Visualization of $\mathcal{G}^{(t)}$", loc='left') ax.legend().remove() plt.tight_layout() if TOGGLE_PRINT: plt.savefig("ei_3.pdf") else: plt.show() # ------------------------------------------- # 4. Forget the underlying objective function # ------------------------------------------- fig, ax = plt.subplots(1, 1, squeeze=True) ax.set_xlim(bounds["x"]) ax.set_ylim(bounds["gp_y"]) ax.grid() boplot.plot_gp(model=gp, confidence_intervals=[2.0], custom_x=x, ax=ax) # boplot.plot_objective_function(ax=ax) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=True, highlight_datapoint=None, highlight_label=None, ax=ax) boplot.darken_graph(y=ymin, ax=ax) ax.set_xlabel(labels['xlabel']) ax.set_ylabel(labels['gp_ylabel']) ax.set_title(r"Visualization of $\mathcal{G}^{(t)}$", loc='left') plt.tight_layout() if TOGGLE_PRINT: plt.savefig("ei_4.pdf") else: plt.show() # ------------------------------------------- # 5. Mark Hypothetical Real cost of a random configuration # ------------------------------------------- fig, ax = plt.subplots(1, 1, squeeze=True) ax.set_xlim(bounds["x"]) ax.set_ylim(bounds["gp_y"]) ax.grid() boplot.plot_gp(model=gp, confidence_intervals=[2.0], custom_x=x, ax=ax) # boplot.plot_objective_function(ax=ax) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=True, highlight_datapoint=None, highlight_label=None, ax=ax) boplot.darken_graph(y=ymin, ax=ax) ax.legend().set_zorder(20) ax.set_xlabel(labels['xlabel']) ax.set_ylabel(labels['gp_ylabel']) ax.set_title(r"Visualization of $\mathcal{G}^{(t)}$", loc='left') candidate = 11.0 cost = -3.5 boplot.highlight_configuration(x=np.array([candidate]), label=r'$\lambda$', lloc='bottom', ax=ax) boplot.highlight_output(y=np.array([cost]), label='', lloc='left', ax=ax) boplot.annotate_y_edge(label=r'$c(\lambda)$', xy=(candidate, cost), align='left', ax=ax) ax.legend().remove() plt.tight_layout() if TOGGLE_PRINT: plt.savefig("ei_5.pdf") else: plt.show() # ------------------------------------------- # 6. Display I(lambda) # ------------------------------------------- fig, ax = plt.subplots(1, 1, squeeze=True) ax.set_xlim(bounds["x"]) ax.set_ylim(bounds["gp_y"]) ax.grid() boplot.plot_gp(model=gp, confidence_intervals=[2.0], custom_x=x, ax=ax) # boplot.plot_objective_function(ax=ax) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=True, highlight_datapoint=None, highlight_label=None, ax=ax) boplot.darken_graph(y=ymin, ax=ax) ax.legend().set_zorder(20) ax.set_xlabel(labels['xlabel']) ax.set_ylabel(labels['gp_ylabel']) ax.set_title(r"Visualization of $\mathcal{G}^{(t)}$", loc='left') boplot.highlight_configuration(x=np.array([candidate]), label=r'$\lambda$', lloc='bottom', ax=ax) boplot.highlight_output(y=np.array([cost]), label='', lloc='left', ax=ax) boplot.annotate_y_edge(label=r'$c(\lambda)$', xy=(candidate, cost), align='left', ax=ax) xmid = (x[ymin_arg][0] + candidate) / 2. ax.annotate(s='', xy=(xmid, cost), xytext=(xmid, ymin), arrowprops={'arrowstyle': '<|-|>',}) textx = xmid + (ax.get_xlim()[1] - ax.get_xlim()[0]) / 40 ax.text(textx, (ymin + cost) / 2, r'$I^{(t)}(\lambda)$', weight='heavy') ax.legend().remove() plt.tight_layout() if TOGGLE_PRINT: plt.savefig("ei_6.pdf") else: plt.show() # ------------------------------------------- # 7. Display Vertical Normal Distribution # ------------------------------------------- fig, ax = plt.subplots(1, 1, squeeze=True) ax.set_xlim(bounds["x"]) ax.set_ylim(bounds["gp_y"]) ax.grid() boplot.plot_gp(model=gp, confidence_intervals=[2.0], custom_x=x, ax=ax) # boplot.plot_objective_function(ax=ax) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=True, highlight_datapoint=None, highlight_label=None, ax=ax) boplot.darken_graph(y=ymin, ax=ax) ax.legend().set_zorder(20) ax.set_xlabel(labels['xlabel']) ax.set_ylabel(labels['gp_ylabel']) ax.set_title(r"Visualization of $\mathcal{G}^{(t)}$", loc='left') boplot.highlight_configuration(x=np.array([candidate]), label=r'$\lambda$', lloc='bottom', ax=ax) boplot.highlight_output(y=np.array([cost]), label='', lloc='left', ax=ax) boplot.annotate_y_edge(label=r'$c(\lambda)$', xy=(candidate, cost), align='left', ax=ax) xmid = (x[ymin_arg][0] + candidate) / 2. ax.annotate(s='', xy=(xmid, cost), xytext=(xmid, ymin), arrowprops={'arrowstyle': '<|-|>',}) textx = xmid + (ax.get_xlim()[1] - ax.get_xlim()[0]) / 40 ax.text(textx, (ymin + cost) / 2, r'$I^{(t)}(\lambda)$', weight='heavy') vcurve_x, vcurve_y, mu = boplot.draw_vertical_normal( gp=gp, incumbenty=ymin, ax=ax, xtest=candidate, xscale=2.0, yscale=1.0 ) ann_x = candidate + 0.3 * (np.max(vcurve_x) - candidate) / 2 ann_y = ymin - (mu - ymin) / 2 arrow_x = ann_x + 0.5 arrow_y = ann_y - 3.0 # label = "{:.2f}".format(candidate) label = '\lambda' ax.annotate( s=r'$PI^{(t)}(%s)$' % label, xy=(ann_x, ann_y), xytext=(arrow_x, arrow_y), arrowprops={'arrowstyle': 'fancy'}, weight='heavy', color='darkgreen', zorder=15 ) ax.legend().remove() plt.tight_layout() if TOGGLE_PRINT: plt.savefig("ei_7.pdf") else: plt.show()
def visualize_lcb(initial_design, init=None): """ Visualize one-step of LCB. :param initial_design: Method for initializing the GP, choice between 'uniform', 'random', and 'presentation' :param init: Number of datapoints to initialize GP with. :return: None """ # 1. Plot 3 different confidence envelopes # 2. Plot only LCB for one confidence envelope # 3. Mark next sample boplot.set_rcparams(**{'legend.loc': 'lower right'}) logging.debug("Visualizing PI with initial design {} and init {}".format( initial_design, init)) # Initialize dummy dataset x, y = initialize_dataset(initial_design=initial_design, init=init) logging.debug( "Initialized dataset with:\nsamples {0}\nObservations {1}".format( x, y)) # Fit GP to the currently available dataset gp = GPR(kernel=Matern()) logging.debug("Fitting GP to\nx: {}\ny:{}".format(x, y)) gp.fit(x, y) # fit the model # noinspection PyStringFormat logging.debug( "Model fit to dataset.\nOriginal Inputs: {0}\nOriginal Observations: {1}\n" "Predicted Means: {2}\nPredicted STDs: {3}".format( x, y, *(gp.predict(x, return_std=True)))) # 1. Plot 3 different confidence envelopes # -------------Plotting code ----------------- fig, ax = plt.subplots(1, 1, squeeze=True) ax.set_xlim(bounds["x"]) ax.set_ylim(bounds["gp_y"]) ax.grid() boplot.plot_gp(model=gp, confidence_intervals=[1.0, 2.0, 3.0], type='both', custom_x=x, ax=ax) boplot.plot_objective_function(ax=ax) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=False, highlight_datapoint=None, highlight_label=None, ax=ax) ax.legend().set_zorder(20) ax.set_xlabel(labels['xlabel']) ax.set_ylabel(labels['gp_ylabel']) ax.set_title(r"Visualization of $\mathcal{G}^{(t)}$", loc='left') plt.tight_layout() if TOGGLE_PRINT: plt.savefig("lcb_1.pdf") else: plt.show() # ------------------------------------------- # 2. Plot only LCB for one confidence envelope # -------------Plotting code ----------------- boplot.set_rcparams(**{'legend.loc': 'upper left'}) kappa = 3.0 fig, ax = plt.subplots(1, 1, squeeze=True) ax.set_xlim(bounds["x"]) ax.set_ylim(bounds["gp_y"]) ax.grid() boplot.plot_gp(model=gp, confidence_intervals=[kappa], type='lower', custom_x=x, ax=ax) boplot.plot_objective_function(ax=ax) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=True, highlight_datapoint=None, highlight_label=None, ax=ax) ax.legend().set_zorder(20) ax.set_xlabel(labels['xlabel']) ax.set_ylabel(labels['gp_ylabel']) ax.set_title(r"Visualization of $\mathcal{G}^{(t)}$", loc='left') plt.tight_layout() if TOGGLE_PRINT: plt.savefig("lcb_2.pdf") else: plt.show() # ------------------------------------------- # 3. Show LCB in parallel # -------------Plotting code ----------------- if TOGGLE_PRINT: fig, (ax1, ax2) = plt.subplots(2, 1, squeeze=True, figsize=(18, 9)) else: fig, (ax1, ax2) = plt.subplots(2, 1, squeeze=True) ax1.set_xlim(bounds["x"]) ax1.set_ylim(bounds["gp_y"]) ax1.grid() boplot.plot_gp(model=gp, confidence_intervals=[kappa], type='lower', custom_x=x, ax=ax1) boplot.plot_objective_function(ax=ax1) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=True, highlight_datapoint=None, highlight_label=None, ax=ax1) lcb_max = get_lcb_maximum(gp, kappa) logging.info("LCB Maximum at:{}".format(lcb_max)) boplot.highlight_configuration(x=lcb_max[0], label=None, lloc='bottom', ax=ax1) ax1.set_xlabel(labels['xlabel']) ax1.set_ylabel(labels['gp_ylabel']) ax1.set_title(r"Visualization of $\mathcal{G}^{(t)}$", loc='left') ax2.set_xlim(bounds["x"]) ax2.set_ylim(bounds["acq_y"]) ax2.grid() ax2.set_xlabel(labels['xlabel']) ax2.set_ylabel(labels['acq_ylabel']) ax2.set_title(r"Visualization of $LCB$", loc='left') boplot.highlight_configuration(x=lcb_max[0], label=None, lloc='bottom', ax=ax2) boplot.plot_acquisition_function(acquisition_functions['LCB'], 0.0, gp, kappa, ax=ax2) plt.tight_layout() if TOGGLE_PRINT: plt.savefig("lcb_3.pdf") else: plt.show() # ------------------------------------------- # 4. Mark next sample # -------------Plotting code ----------------- fig, ax = plt.subplots(1, 1, squeeze=True) ax.set_xlim(bounds["x"]) ax.set_ylim(bounds["gp_y"]) ax.grid() boplot.plot_gp(model=gp, confidence_intervals=[3.0], type='lower', custom_x=x, ax=ax) boplot.plot_objective_function(ax=ax) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=True, highlight_datapoint=None, highlight_label=None, ax=ax) lcb_max = get_lcb_maximum(gp, 3.0) logging.info("LCB Maximum at:{}".format(lcb_max)) boplot.highlight_configuration(x=lcb_max[0], label=None, lloc='bottom', ax=ax) boplot.highlight_output(y=lcb_max[1], label='', lloc='left', ax=ax) boplot.annotate_y_edge(label=r'${\hat{c}}^{(t)}(%.2f)$' % lcb_max[0], xy=lcb_max, align='left', ax=ax) ax.legend().set_zorder(20) ax.set_xlabel(labels['xlabel']) ax.set_ylabel(labels['gp_ylabel']) ax.set_title(r"Visualization of $\mathcal{G}^{(t)}$", loc='left') ax.legend().remove() plt.tight_layout() if TOGGLE_PRINT: plt.savefig("lcb_4.pdf") else: plt.show()
def visualize_es(initial_design, init=None): """ Visualize one-step of ES. :param initial_design: Method for initializing the GP, choice between 'uniform', 'random', and 'presentation' :param init: Number of datapoints to initialize GP with. :return: None """ # 1. Show GP fit on initial dataset, 0 samples, histogram # 2. Show GP fit on initial dataset, 1 sample, histogram # 3. Show GP fit on initial dataset, 3 samples, histogram # 4. Show GP fit on initial dataset, 50 samples, histogram # 5. Show PDF derived from the histogram at 50 samples # 6. Mark maximum of the PDF as next configuration to be evaluated # a. Plot GP # b. Sample GP, mark minima, update histogram of lambda* # c. Repeat 2 for each sample. # d. Show results after multiple iterations boplot.set_rcparams(**{'figure.figsize': (22, 11)}) # Initial setup # ------------------------------------------- logging.debug("Visualizing ES with initial design {} and init {}".format( initial_design, init)) # Initialize dummy dataset x, y = initialize_dataset(initial_design=initial_design, init=init) logging.debug( "Initialized dataset with:\nsamples {0}\nObservations {1}".format( x, y)) # Fit GP to the currently available dataset gp = GPR(kernel=Matern()) logging.debug("Fitting GP to\nx: {}\ny:{}".format(x, y)) gp.fit(x, y) # fit the model histogram_precision = 20 X_ = boplot.get_plot_domain(precision=histogram_precision) nbins = X_.shape[0] logging.info("Creating histograms with {} bins".format(nbins)) bin_range = (bounds['x'][0], bounds['x'][1] + 1 / histogram_precision) # ------------------------------------------- def draw_samples(nsamples, ax1, ax2, show_min=False, return_pdf=False): if not nsamples: return seed2 = 1256 seed3 = 65 mu = gp.sample_y(X=X_, n_samples=nsamples, random_state=seed3) boplot.plot_gp_samples(mu=mu, nsamples=nsamples, precision=histogram_precision, custom_x=X_, show_min=show_min, ax=ax1, seed=seed2) data_h = X_[np.argmin(mu, axis=0), 0] logging.info("Shape of data_h is {}".format(data_h.shape)) logging.debug("data_h is: {}".format(data_h)) bins = ax2.hist(data_h, bins=nbins, range=bin_range, density=return_pdf, color='lightgreen', edgecolor='black', alpha=0.0 if return_pdf else 1.0) return bins # 1. Show GP fit on initial dataset, 0 samples, histogram # ------------------------------------------- ax2_title = r'$p_{min}=P(\lambda=\lambda^*)$' bounds['acq_y'] = (0.0, 1.0) fig, (ax1, ax2) = plt.subplots(2, 1, squeeze=True) ax1.set_xlim(bounds['x']) ax1.set_ylim(bounds['gp_y']) ax2.set_xlim(bounds['x']) ax2.set_ylim(bounds['acq_y']) ax1.grid() ax2.grid() boplot.plot_objective_function(ax=ax1) boplot.plot_gp(model=gp, confidence_intervals=[3.0], ax=ax1, custom_x=x) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=False, ax=ax1) nsamples = 0 draw_samples(nsamples=nsamples, ax1=ax1, ax2=ax2, show_min=True) # Plot uniform prior for p_min xplot = boplot.get_plot_domain() ylims = ax2.get_ylim() xlims = ax2.get_xlim() yupper = [(ylims[1] - ylims[0]) / (xlims[1] - xlims[0])] * xplot.shape[0] ax2.plot(xplot[:, 0], yupper, color='green', linewidth=2.0) ax2.fill_between(xplot[:, 0], ylims[0], yupper, color='lightgreen') ax1.legend().set_zorder(20) ax1.set_xlabel(labels['xlabel']) ax1.set_ylabel(labels['gp_ylabel']) ax1.set_title(r"Visualization of $\mathcal{G}^t$", loc='left') ax2.set_xlabel(labels['xlabel']) ax2.set_ylabel(r'$p_{min}$') ax2.set_title(ax2_title, loc='left') plt.tight_layout() if TOGGLE_PRINT: plt.savefig('es_1') else: plt.show() # ------------------------------------------- # 2. Show GP fit on initial dataset, 1 sample, histogram # ------------------------------------------- bounds['acq_y'] = (0.0, 5.0) ax2_title = r'Frequency of $\lambda=\hat{\lambda}^*$' fig, (ax1, ax2) = plt.subplots(2, 1, squeeze=True) ax1.set_xlim(bounds['x']) ax1.set_ylim(bounds['gp_y']) ax2.set_xlim(bounds['x']) ax2.set_ylim(bounds['acq_y']) ax1.grid() ax2.grid() boplot.plot_objective_function(ax=ax1) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=False, ax=ax1) nsamples = 1 draw_samples(nsamples=nsamples, ax1=ax1, ax2=ax2, show_min=True) ax1.legend().set_zorder(20) ax1.set_xlabel(labels['xlabel']) ax1.set_ylabel(labels['gp_ylabel']) ax1.set_title(r"One sample from $\mathcal{G}^t$", loc='left') ax2.set_xlabel(labels['xlabel']) # ax2.set_ylabel(r'$p_{min}$') ax2.set_ylabel(r'Frequency') ax2.set_title(ax2_title, loc='left') plt.tight_layout() if TOGGLE_PRINT: plt.savefig('es_2') else: plt.show() # 3. Show GP fit on initial dataset, 10 samples, histogram # ------------------------------------------- bounds['acq_y'] = (0.0, 10.0) ax2_title = r'Frequency of $\lambda=\hat{\lambda}^*$' fig, (ax1, ax2) = plt.subplots(2, 1, squeeze=True) ax1.set_xlim(bounds['x']) ax1.set_ylim(bounds['gp_y']) ax2.set_xlim(bounds['x']) ax2.set_ylim(bounds['acq_y']) ax1.grid() ax2.grid() boplot.plot_objective_function(ax=ax1) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=False, ax=ax1) nsamples = 10 draw_samples(nsamples=nsamples, ax1=ax1, ax2=ax2) ax1.set_xlabel(labels['xlabel']) ax1.set_ylabel(labels['gp_ylabel']) ax1.set_title(r"Ten samples from $\mathcal{G}^t$", loc='left') ax2.set_xlabel(labels['xlabel']) # ax2.set_ylabel(r'$p_{min}$') ax2.set_ylabel(r'Frequency') ax2.set_title(ax2_title, loc='left') plt.tight_layout() if TOGGLE_PRINT: plt.savefig('es_3') else: plt.show() # ------------------------------------------- # 4. Show GP fit on initial dataset, 200 samples, histogram # ------------------------------------------- bounds["acq_y"] = (0.0, 20.0) ax2_title = r'Frequency of $\lambda=\hat{\lambda}^*$' fig, (ax1, ax2) = plt.subplots(2, 1, squeeze=True) ax1.set_xlim(bounds['x']) ax1.set_ylim(bounds['gp_y']) ax2.set_xlim(bounds['x']) ax2.set_ylim(bounds['acq_y']) ax1.grid() ax2.grid() boplot.plot_objective_function(ax=ax1) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=False, ax=ax1) nsamples = 200 draw_samples(nsamples=nsamples, ax1=ax1, ax2=ax2) ax1.set_xlabel(labels['xlabel']) ax1.set_ylabel(labels['gp_ylabel']) ax1.set_title(r"200 samples from $\mathcal{G}^t$", loc='left') ax2.set_xlabel(labels['xlabel']) # ax2.set_ylabel(r'$p_{min}$') ax2.set_ylabel(r'Frequency') ax2.set_title(ax2_title, loc='left') plt.tight_layout() if TOGGLE_PRINT: plt.savefig('es_4') else: plt.show() # ------------------------------------------- # 5. Show PDF derived from the histogram at 200 samples # ------------------------------------------- ax2_title = "$\hat{P}(\lambda=\lambda^*)$" bounds["acq_y"] = (0.0, 1.0) fig, (ax1, ax2) = plt.subplots(2, 1, squeeze=True) ax1.set_xlim(bounds['x']) ax1.set_ylim(bounds['gp_y']) ax2.set_xlim(bounds['x']) ax2.set_ylim(bounds["acq_y"]) ax1.grid() ax2.grid() boplot.plot_objective_function(ax=ax1) boplot.plot_gp(model=gp, confidence_intervals=[3.0], ax=ax1, custom_x=x) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=False, ax=ax1) nsamples = 200 seed3 = 65 mu = gp.sample_y(X=X_, n_samples=nsamples, random_state=seed3) data_h = X_[np.argmin(mu, axis=0), 0] kde = kd(kernel='gaussian', bandwidth=0.75).fit(data_h.reshape(-1, 1)) xplot = boplot.get_plot_domain() ys = np.exp(kde.score_samples(xplot)) ax2.plot(xplot, ys, color='green', lw=2.) ax2.fill_between(xplot[:, 0], ax2.get_ylim()[0], ys, color='lightgreen') ax1.set_xlabel(labels['xlabel']) ax1.set_ylabel(labels['gp_ylabel']) ax1.set_title(r"Visualization of $\mathcal{G}^t$", loc='left') ax2.set_xlabel(labels['xlabel']) ax2.set_ylabel(r'$p_{min}$') ax2.set_title(ax2_title, loc='left') plt.tight_layout() if TOGGLE_PRINT: plt.savefig('es_5') else: plt.show() # ------------------------------------------- # 6. Mark maximum of the PDF as next configuration to be evaluated # ------------------------------------------- ax2_title = "$\hat{P}(\lambda=\lambda^*)$" bounds["acq_y"] = (0.0, 1.0) fig, (ax1, ax2) = plt.subplots(2, 1, squeeze=True) ax1.set_xlim(bounds['x']) ax1.set_ylim(bounds['gp_y']) ax2.set_xlim(bounds['x']) ax2.set_ylim(bounds["acq_y"]) ax1.grid() ax2.grid() boplot.plot_objective_function(ax=ax1) boplot.plot_gp(model=gp, confidence_intervals=[3.0], ax=ax1, custom_x=x) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=False, ax=ax1) nsamples = 200 seed3 = 65 mu = gp.sample_y(X=X_, n_samples=nsamples, random_state=seed3) data_h = X_[np.argmin(mu, axis=0), 0] kde = kd(kernel='gaussian', bandwidth=0.75).fit(data_h.reshape(-1, 1)) xplot = boplot.get_plot_domain() ys = np.exp(kde.score_samples(xplot)) idx_umax = np.argmax(ys) boplot.highlight_configuration(x=xplot[idx_umax], label='', ax=ax1, disable_ticks=True) boplot.annotate_x_edge(label=r'$\lambda^{(t)}$', xy=(xplot[idx_umax], ax1.get_ylim()[0]), ax=ax1, align='top', offset_param=1.5) boplot.highlight_configuration(x=xplot[idx_umax], label='', ax=ax2, disable_ticks=True) boplot.annotate_x_edge(label=r'$\lambda^{(t)}$', xy=(xplot[idx_umax], ys[idx_umax]), ax=ax2, align='top', offset_param=1.0) ax2.plot(xplot, ys, color='green', lw=2.) ax2.fill_between(xplot[:, 0], ax2.get_ylim()[0], ys, color='lightgreen') ax1.set_xlabel(labels['xlabel']) ax1.set_ylabel(labels['gp_ylabel']) ax1.set_title(r"Visualization of $\mathcal{G}^t$", loc='left') ax2.set_xlabel(labels['xlabel']) ax2.set_ylabel(r'$p_{min}$') ax2.set_title(ax2_title, loc='left') plt.tight_layout() if TOGGLE_PRINT: plt.savefig('es_6') else: plt.show()
def visualize_look_ahead(initial_design, init=None): """ Visualize one-step of look-ahead. :param initial_design: Method for initializing the GP, choice between 'uniform', 'random', and 'presentation' :param init: Number of datapoints to initialize GP with. :return: None """ # boplot.set_rcparams(**{'legend.loc': 'lower left'}) logging.debug( "Visualizing Look-Ahead with initial design {} and init {}".format( initial_design, init)) # Initialize dummy dataset x, y = initialize_dataset(initial_design=initial_design, init=init) logging.debug( "Initialized dataset with:\nsamples {0}\nObservations {1}".format( x, y)) # Fit GP to the currently available dataset gp = GPR(kernel=Matern()) logging.debug("Fitting GP to\nx: {}\ny:{}".format(x, y)) gp.fit(x, y) # fit the model mu_star_t_xy = get_mu_star(gp) logging.info("Mu-star at time t: {}".format(mu_star_t_xy)) # noinspection PyStringFormat logging.debug( "Model fit to dataset.\nOriginal Inputs: {0}\nOriginal Observations: {1}\n" "Predicted Means: {2}\nPredicted STDs: {3}".format( x, y, *(gp.predict(x, return_std=True)))) # Assume next evaluation location x_ = np.array([[5.0]]) print(x_) y_ = f(x_[0]) # Update dataset with new observation X2_ = np.append(x, x_, axis=0) Y2_ = y + [y_] logging.info("x: {}, y: {}".format(x_, y_)) # Fit GP to the updated dataset gp2 = GPR(kernel=Matern()) logging.debug("Fitting GP to\nx: {}\ny:{}".format(X2_, Y2_)) gp2.fit(X2_, Y2_) # fit the model mu_star_t1_xy = get_mu_star(gp2) logging.info("Mu-star at time t+1: {}".format(mu_star_t1_xy)) # -------------------------Plotting madness begins--------------------------- def draw_basic_figure(tgp=gp, tx=x, tX_=x, tY_=y, title='', highlight_datapoint=None, highlight_label="", ax=None): if ax is None: fig, ax = plt.subplots(1, 1, squeeze=True) plt.subplots_adjust(0.05, 0.15, 0.95, 0.85) figflag = True else: figflag = False ax.set_xlim(bounds["x"]) ax.set_ylim(bounds["gp_y"]) if title: ax.set_title(title, loc='left') ax.grid() boplot.plot_objective_function(ax=ax) boplot.plot_gp(model=tgp, confidence_intervals=[1.0, 2.0, 3.0], ax=ax, custom_x=tx) if highlight_datapoint: boplot.mark_observations(X_=tX_, Y_=tY_, mark_incumbent=False, ax=ax, highlight_datapoint=highlight_datapoint, highlight_label=highlight_label) else: boplot.mark_observations(X_=tX_, Y_=tY_, mark_incumbent=False, ax=ax) if figflag: return fig, ax else: return ax def perform_finishing_tasks(ax, filename="", remove_legend=True): ax.legend().set_zorder(zorders['legend']) ax.set_xlabel(labels['xlabel']) if remove_legend: ax.legend().remove() # plt.tight_layout() if TOGGLE_PRINT: # plt.savefig(f"{OUTPUT_DIR}/{filename}", bbox_inches='tight') plt.savefig(f"{OUTPUT_DIR}/{filename}") else: plt.show() # --------------------------------------- # Draw look ahead 1. labels['gp_mean'] = r'Mean: $\mu^{(t)}(\cdot)$' fig, ax = draw_basic_figure(title="") perform_finishing_tasks(ax=ax, filename="look_ahead_1.pdf", remove_legend=False) # --------------------------------------- # Draw look ahead 2 fig, ax = draw_basic_figure(title="") logging.debug("Placing vertical on configuration: {}".format(x_)) # boplot.highlight_configuration(x=x_, label='', lloc='bottom', ax=ax, ha='center') boplot.highlight_configuration(x=x_, label='', lloc='bottom', ax=ax, disable_ticks=True) boplot.annotate_x_edge(label=r'$\lambda$', xy=(x_, y_), align='bottom', ax=ax) perform_finishing_tasks(ax=ax, filename="look_ahead_2.pdf", remove_legend=True) # --------------------------------------- # Draw look ahead 3 fig, ax = draw_basic_figure(title="") boplot.highlight_configuration(x=x_, label='', lloc='bottom', ax=ax, ha='right') boplot.annotate_x_edge(label=r'$\lambda$', xy=(x_, y_), align='bottom', ax=ax) boplot.highlight_output(y_, label='', lloc='right', ax=ax, fontsize=28) boplot.annotate_y_edge(label=r'$c(\lambda)$', xy=(x_, y_), align='right', ax=ax) ax.scatter(x_, y_, color=colors['highlighted_observations'], marker='X', label=r"Hypothetical Observation $<\lambda, c(\lambda)>$", zorder=zorders['annotations_normal']) perform_finishing_tasks(ax=ax, filename="look_ahead_3.pdf", remove_legend=True) # --------------------------------------- # Draw look ahead 4. labels['gp_mean'] = r'Mean: $\mu^{(t+1)}(\cdot)|_\lambda$' fig, ax = draw_basic_figure( tgp=gp2, tx=x, tX_=X2_, tY_=Y2_, title='', highlight_datapoint=np.where(np.isclose(X2_, x_))[0], highlight_label=r"Hypothetical Observation $<\lambda, c(\lambda)>$") perform_finishing_tasks(ax=ax, filename="look_ahead_4.pdf", remove_legend=False) # --------------------------------------- # Vertical comparison of look-ahead at any given x def draw_vertical_comparison(imaginary_lambda, ax1, ax2): tx_ = np.array([[imaginary_lambda]]) ty_ = f(tx_[0]) # Update dataset with new observation tX_ = np.append(x, tx_, axis=0) tY_ = y + [ty_] logging.info("x: {}, y: {}".format(tx_, ty_)) # Fit GP to the updated dataset tgp = GPR(kernel=Matern()) logging.debug("Fitting GP to\nx: {}\ny:{}".format(tX_, tY_)) tgp.fit(tX_, tY_) # fit the model tmu_star_t1_xy = get_mu_star(tgp) # Draw the left hand figure using the old gp on ax1 draw_basic_figure(tgp=gp, title=r"$\hat{c}^{(t)}$", ax=ax1) logging.debug("Placing vertical on configuration: {}".format(tx_)) ax1.scatter(tx_, ty_, color=colors['highlighted_observations'], marker='X', label=r"Hypothetical Observation $<\lambda, c(\lambda)>$", zorder=zorders["annotations_normal"]) ax1.legend().remove() # Draw the right hand figure using the hypothetical gp tgp on ax2 draw_basic_figure( tgp=tgp, tx=tX_, tX_=tX_, tY_=tY_, title=r"$\hat{c}^{(t+1)}|_\lambda$", highlight_datapoint=np.where(np.isclose(tX_, tx_))[0], highlight_label=r"Hypothetical Observation $<\lambda, c(\lambda)>$", ax=ax2) def finishing_touches_parallel(ax1, ax2, filename=""): ax1.set_xlabel(labels['xlabel']) ax2.set_xlabel(labels['xlabel']) plt.tight_layout() if TOGGLE_PRINT: plt.savefig(f"{OUTPUT_DIR}/{filename}") else: plt.show() # --------------------------------------- # Draw look ahead 5 fig, (ax1, ax2) = plt.subplots(1, 2, squeeze=True, figsize=(22, 9)) draw_vertical_comparison(imaginary_lambda=5.0, ax1=ax1, ax2=ax2) finishing_touches_parallel(ax1=ax1, ax2=ax2, filename="look_ahead_5.pdf") # --------------------------------------- # Draw look ahead 6 fig, (ax1, ax2) = plt.subplots(1, 2, squeeze=True, figsize=(22, 9)) draw_vertical_comparison(imaginary_lambda=5.5, ax1=ax1, ax2=ax2) finishing_touches_parallel(ax1=ax1, ax2=ax2, filename="look_ahead_6.pdf") # --------------------------------------- # Draw look ahead 5 fig, (ax1, ax2) = plt.subplots(1, 2, squeeze=True, figsize=(22, 9)) draw_vertical_comparison(imaginary_lambda=3.5, ax1=ax1, ax2=ax2) finishing_touches_parallel(ax1=ax1, ax2=ax2, filename="look_ahead_7.pdf") # --------------------------------------- # Draw KG 1 labels['gp_mean'] = r'Mean: $\mu^{(t)}(\cdot)$' fig, ax = draw_basic_figure(title="") perform_finishing_tasks(ax=ax, filename="kg_1.pdf", remove_legend=False) # --------------------------------------- # Draw kg 2 fig, ax = draw_basic_figure(title="") boplot.highlight_configuration(mu_star_t_xy[0], lloc='bottom', ax=ax, disable_ticks=True) boplot.annotate_x_edge(label="%.2f" % mu_star_t_xy[0], xy=mu_star_t_xy, ax=ax, align='bottom', offset_param=1.5) boplot.highlight_output(mu_star_t_xy[1], label='', lloc='right', ax=ax, fontsize=30, disable_ticks=True) boplot.annotate_y_edge(label=r'${(\mu^*)}^{(t)}$', xy=mu_star_t_xy, align='right', ax=ax, yoffset=1.5) perform_finishing_tasks(ax=ax, filename="kg_2.pdf", remove_legend=True) # --------------------------------------- # Draw kg 3 fig, ax = draw_basic_figure( tgp=gp2, tx=x, tX_=X2_, tY_=Y2_, title='', highlight_datapoint=np.where(np.isclose(X2_, x_))[0], highlight_label=r"Hypothetical Observation $<\lambda, c(\lambda)>$") perform_finishing_tasks(ax=ax, filename="kg_3.pdf", remove_legend=True) # --------------------------------------- # Draw kg 4 fig, ax = draw_basic_figure( tgp=gp2, tx=x, tX_=X2_, tY_=Y2_, title='', highlight_datapoint=np.where(np.isclose(X2_, x_))[0], highlight_label=r"Hypothetical Observation $<\lambda, c(\lambda)>$") boplot.highlight_configuration(mu_star_t1_xy[0], lloc='bottom', ax=ax, disable_ticks=True) boplot.annotate_x_edge(label="%.2f" % mu_star_t1_xy[0], xy=mu_star_t1_xy, ax=ax, align='bottom', offset_param=1.5) boplot.highlight_output(mu_star_t1_xy[1], label='', lloc='right', ax=ax, fontsize=28) boplot.annotate_y_edge(label=r'${(\mu^*)}^{(t+1)}|_\lambda$', xy=mu_star_t1_xy, align='right', ax=ax, yoffset=1.5) perform_finishing_tasks(ax=ax, filename="kg_4.pdf", remove_legend=True) # --------------------------------------- # Draw kg 5 fig, (ax1, ax2) = plt.subplots(1, 2, squeeze=True, figsize=(22, 9)) draw_vertical_comparison(imaginary_lambda=x_.squeeze(), ax1=ax1, ax2=ax2) boplot.highlight_output(mu_star_t_xy[1], label='', lloc='right', ax=ax1, fontsize=30) boplot.annotate_y_edge(label='${(\mu^*)}^{(t)}$', xy=mu_star_t_xy, align='right', ax=ax1, yoffset=1.5) boplot.highlight_output(mu_star_t1_xy[1], label='', lloc='right', ax=ax2, fontsize=28) boplot.annotate_y_edge(label='${(\mu^*)}^{(t+1)}|_\lambda$', xy=mu_star_t1_xy, align='left', ax=ax2, yoffset=1.5) finishing_touches_parallel(ax1=ax1, ax2=ax2, filename="kg_5.pdf") return
def visualize_es(initial_design, init=None): """ Visualize one-step of ES. :param initial_design: Method for initializing the GP, choice between 'uniform', 'random', and 'presentation' :param init: Number of datapoints to initialize GP with. :return: None """ # 1. Show GP fit on initial dataset, 0 samples, histogram # 2. Show GP fit on initial dataset, 1 sample, histogram # 3. Show GP fit on initial dataset, 3 samples, histogram # 4. Show GP fit on initial dataset, 50 samples, histogram # 5. Show PDF derived from the histogram at 10e9 samples # 6. Mark maximum of the PDF as next configuration to be evaluated # a. Plot GP # b. Sample GP, mark minima, update histogram of lambda* # c. Repeat 2 for each sample. # d. Show results after multiple iterations boplot.set_rc('figure', figsize=(22, 11)) # Initial setup # ------------------------------------------- logging.debug("Visualizing ES with initial design {} and init {}".format( initial_design, init)) # Initialize dummy dataset x, y = initialize_dataset(initial_design=initial_design, init=init) logging.debug( "Initialized dataset with:\nsamples {0}\nObservations {1}".format( x, y)) # Fit GP to the currently available dataset gp = GPR(kernel=Matern()) logging.debug("Fitting GP to\nx: {}\ny:{}".format(x, y)) gp.fit(x, y) # fit the model histogram_precision = 20 X_ = boplot.get_plot_domain(precision=histogram_precision) nbins = X_.shape[0] logging.info("Creating histograms with {} bins".format(nbins)) bin_range = (bounds['x'][0], bounds['x'][1] + 1 / histogram_precision) # ------------------------------------------- def bin_large_sample_size(nsamples, seed, return_pdf=False, batch_size=1280000): # Used for plotting a histogram when a large number of samples are to be generated. logging.info( f"Generating batch-wise histogram data for {nsamples} samples {batch_size} samples at at time." ) rng = np.random.RandomState(seed=seed) counts = np.zeros_like(X_.flatten()) bin_edges = np.zeros(shape=(counts.shape[0] + 1)) # Smoothen out the batches - we don't care about missing out a small overflow number of samples. nsamples = (nsamples // batch_size) * batch_size for idx in range(0, nsamples, batch_size): # # Iterate in increments of batch_size samples, but check for an uneven batch in the last iteration # batch_nsamples = batch_size if (nsamples - idx) % batch_size == 0 else nsamples - idx if idx % (batch_size * 10) == 0: logging.info( f"Generated {idx} samples out of an expected {nsamples}" f"[{idx * 100.0 / nsamples}%].") batch_nsamples = batch_size mu = gp.sample_y(X=X_, n_samples=batch_nsamples, random_state=rng) minima = X_[np.argmin(mu, axis=0), 0] hist, bin_edges = np.histogram( minima, bins=nbins, range=bin_range, density=return_pdf, ) counts += hist logging.info(f"Finished generating {nsamples} samples.") return counts, bin_edges def draw_samples(nsamples, ax1, ax2, show_min=False, return_pdf=False, show_samples=True, show_hist=True, data=None): if not nsamples: raise RuntimeError( f"Number of samples must be a positive integer, received " f"{nsamples} of type {type(nsamples)}") # If data is not None, assume that it contains pre-computed histogram data logging.debug("Recieved histogram data of shape %s." % str(np.array(data).shape)) if data: logging.debug( "Histogram data contained %d counts and %d bins." % (np.array(data[0]).shape[0], np.array(data[1]).shape[0])) counts = data[0] bins = data[1] return ax2.hist(bins[:-1], bins=bins, density=return_pdf, weights=counts, color='lightgreen', edgecolor='black', alpha=0.0 if return_pdf else 1.0) mu = gp.sample_y(X=X_, n_samples=nsamples, random_state=GP_SAMPLE_SEED) if show_samples: boplot.plot_gp_samples(mu=mu, nsamples=nsamples, precision=histogram_precision, custom_x=X_, show_min=show_min, ax=ax1, seed=GP_SAMPLE_COLOR_SEED) minima = X_[np.argmin(mu, axis=0), 0] logging.info("Shape of minima is {}".format(minima.shape)) # logging.debug("minima is: {}".format(minima)) bins = None if show_hist: bins = ax2.hist(minima, bins=nbins, range=bin_range, density=return_pdf, color='lightgreen', edgecolor='black', alpha=0.0 if return_pdf else 1.0) return bins def draw_basic_plot(ax2_sci_not=False): fig, (ax1, ax2) = plt.subplots(2, 1, squeeze=True) ax1.set_xlim(bounds['x']) ax1.set_ylim(bounds['gp_y']) ax2.set_xlim(bounds['x']) ax2.set_ylim(bounds['acq_y']) if ax2_sci_not: f = mtick.ScalarFormatter(useOffset=False, useMathText=True) g = lambda x, pos: "${}$".format(f._formatSciNotation('%1.10e' % x) ) ax2.yaxis.set_major_formatter(mtick.FuncFormatter(g)) ax1.grid() ax2.grid() boplot.plot_objective_function(ax=ax1) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=False, ax=ax1) return fig, (ax1, ax2) def draw_freq_plots(nsamples): fig, (ax1, ax2) = draw_basic_plot() if nsamples == 1: show_min = True else: show_min = False draw_samples(nsamples=nsamples, ax1=ax1, ax2=ax2, show_min=show_min) return fig, (ax1, ax2) def finishing_touches(ax1, ax2, ax1_title, ax2_title, show_legend=False, figname="es.pdf"): ax1.set_xlabel(labels['xlabel']) # ax1.set_ylabel(labels['gp_ylabel']) # ax1.set_title(ax1_title, loc='left') ax2.set_xlabel(labels['xlabel']) ax2.set_ylabel(r'Frequency') ax2.set_title(ax2_title, loc='left') if show_legend: ax1.legend().set_zorder(zorders["legend"]) else: ax1.legend().remove() # plt.tight_layout() plt.subplots_adjust(hspace=1.0) if TOGGLE_PRINT: plt.savefig(f"{OUTPUT_DIR}/{figname}") else: plt.show() # 1. Show GP fit on initial dataset, 0 samples, histogram # ------------------------------------------- ax2_title = r'$p_{min}=P(\lambda=\lambda^*)$' bounds['acq_y'] = (0.0, 1.0) fig, (ax1, ax2) = draw_basic_plot() boplot.plot_gp(model=gp, confidence_intervals=[1.0, 2.0, 3.0], ax=ax1, custom_x=x) # Plot uniform prior for p_min xplot = boplot.get_plot_domain() ylims = ax2.get_ylim() xlims = ax2.get_xlim() yupper = [(ylims[1] - ylims[0]) / (xlims[1] - xlims[0])] * xplot.shape[0] ax2.plot(xplot[:, 0], yupper, color='green', linewidth=2.0) ax2.fill_between(xplot[:, 0], ylims[0], yupper, color='lightgreen') # ax1.legend().set_zorder(zorders["legend"]) ax1.set_xlabel(labels['xlabel']) # ax1.set_ylabel(labels['gp_ylabel']) # ax1.set_title(r"Visualization of $\mathcal{G}^t$", loc='left') ax2.set_xlabel(labels['xlabel']) ax2.set_ylabel(r'$p_{min}$') ax2.set_title(ax2_title, loc='left') plt.tight_layout() if TOGGLE_PRINT: plt.savefig(f"{OUTPUT_DIR}/es_1.pdf") else: plt.show() # ------------------------------------------- # 2. Show GP fit on initial dataset, 1 sample, histogram # ------------------------------------------- nsamples = 1 bounds['acq_y'] = (0.0, 5.0) ax1_title = r"One sample$" ax2_title = r'Frequency of $\lambda=\hat{\lambda}^*$' figname = "es_2.pdf" fig, (ax1, ax2) = draw_freq_plots(nsamples=nsamples) finishing_touches(ax1=ax1, ax2=ax2, ax1_title=ax1_title, ax2_title=ax2_title, show_legend=False, figname=figname) # 3. Show GP fit on initial dataset, 10 samples, histogram # ------------------------------------------- nsamples = 10 bounds['acq_y'] = (0.0, 10.0) ax1_title = r"Ten samples$" ax2_title = r'Frequency of $\lambda=\hat{\lambda}^*$' figname = "es_3.pdf" fig, (ax1, ax2) = draw_freq_plots(nsamples=nsamples) finishing_touches(ax1=ax1, ax2=ax2, ax1_title=ax1_title, ax2_title=ax2_title, show_legend=False, figname=figname) # ------------------------------------------- # 4. Show GP fit on initial dataset, 200 samples, histogram # ------------------------------------------- nsamples = 100 bounds["acq_y"] = (0.0, 20.0) ax1_title = r"200 samples$" ax2_title = r'Frequency of $\lambda=\hat{\lambda}^*$' figname = "es_4.pdf" fig, (ax1, ax2) = draw_freq_plots(nsamples=nsamples) finishing_touches(ax1=ax1, ax2=ax2, ax1_title=ax1_title, ax2_title=ax2_title, show_legend=False, figname=figname) # ------------------------------------------- # 5. Show PDF derived from the histogram at 10e9 samples # ------------------------------------------- nsamples = int(1e9) # Generate ~1 Billion samples bounds["acq_y"] = (0.0, nsamples / 10.0) # ax1_title = r"200 samples from $\mathcal{G}^t$" # ax2_title = "$\hat{P}(\lambda=\lambda^*)$" ax1_title = r"A very large number of samples" ax2_title = r'Frequency of $\lambda=\hat{\lambda}^*$' figname = "es_5.pdf" fig, (ax1, ax2) = draw_basic_plot(ax2_sci_not=True) # Draw only a limited number of samples draw_samples(nsamples=200, ax1=ax1, ax2=ax2, show_min=False, show_samples=True, show_hist=False) # Use an alternate procedure to generate the histogram data counts, bins = bin_large_sample_size(nsamples, seed=GP_SAMPLE_SEED, return_pdf=False, batch_size=1280000) hist_data = (counts, bins) # Draw histogram only for a large number of samples draw_samples(nsamples=nsamples, ax1=ax1, ax2=ax2, show_min=False, show_samples=False, show_hist=True, data=hist_data) finishing_touches(ax1=ax1, ax2=ax2, ax1_title=ax1_title, ax2_title=ax2_title, show_legend=False, figname=figname) # ------------------------------------------- # 6. Mark maximum of the PDF as next configuration to be evaluated # ------------------------------------------- figname = "es_6.pdf" fig, (ax1, ax2) = draw_basic_plot(ax2_sci_not=True) # Draw only a limited number of samples draw_samples(nsamples=200, ax1=ax1, ax2=ax2, show_min=False, show_samples=True, show_hist=False) # Draw histogram only for a large number of samples using previously generated histogram data draw_samples(nsamples=nsamples, ax1=ax1, ax2=ax2, show_min=False, show_samples=False, show_hist=True, data=hist_data) xplot = boplot.get_plot_domain() idx_umax = np.argmax(counts) xmax = (bins[idx_umax] + bins[idx_umax + 1]) / 2.0 logging.info( f"Highlighting xmax as configuration at index {idx_umax} with count {counts[idx_umax]}, " f"at configuration {xmax}.") boplot.highlight_configuration(x=xmax, label=r'$\lambda^{(t)}$', ax=ax1, disable_ticks=False) # boplot.annotate_x_edge(label=r'$\lambda^{(t)}$', xy=(xplot[idx_umax], ax1.get_ylim()[0]), # ax=ax1, align='top', offset_param=1.5) boplot.highlight_configuration(x=xmax, label=r'$\lambda^{(t)}$', ax=ax2, disable_ticks=False) # boplot.annotate_x_edge(label=r'$\lambda^{(t)}$', xy=(xplot[idx_umax], ys[idx_umax]), # ax=ax2, align='top', offset_param=1.0) finishing_touches(ax1=ax1, ax2=ax2, ax1_title=ax1_title, ax2_title=ax2_title, show_legend=False, figname=figname)
def visualize_ts(initial_design, init=None): """ Visualize one-step of TS. :param initial_design: Method for initializing the GP, choice between 'uniform', 'random', and 'presentation' :param init: Number of datapoints to initialize GP with. :return: None """ # 1. Plot GP fit on initial dataset # 2. Plot one sample # 3. Mark minimum of sample boplot.set_rcparams(**{'legend.loc': 'upper left'}) logging.debug("Visualizing EI with initial design {} and init {}".format( initial_design, init)) # Initialize dummy dataset x, y = initialize_dataset(initial_design=initial_design, init=init) ymin_arg = np.argmin(y) ymin = y[ymin_arg] logging.debug( "Initialized dataset with:\nsamples {0}\nObservations {1}".format( x, y)) # Fit GP to the currently available dataset gp = GPR(kernel=Matern()) logging.debug("Fitting GP to\nx: {}\ny:{}".format(x, y)) gp.fit(x, y) # fit the model # noinspection PyStringFormat logging.debug( "Model fit to dataset.\nOriginal Inputs: {0}\nOriginal Observations: {1}\n" "Predicted Means: {2}\nPredicted STDs: {3}".format( x, y, *(gp.predict(x, return_std=True)))) # 1. Plot GP fit on initial dataset # -------------Plotting code ----------------- fig, ax = plt.subplots(1, 1, squeeze=True) ax.set_xlim(bounds["x"]) ax.set_ylim(bounds["gp_y"]) ax.grid() boplot.plot_gp(model=gp, confidence_intervals=[1.0, 2.0, 3.0], custom_x=x, ax=ax) boplot.plot_objective_function(ax=ax) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=False, highlight_datapoint=None, highlight_label=None, ax=ax) ax.legend().set_zorder(zorders['legend']) ax.set_xlabel(labels['xlabel']) plt.tight_layout() if TOGGLE_PRINT: plt.savefig(f"{OUTPUT_DIR}/ts_1.pdf") else: plt.show() # ------------------------------------------- # 2. Plot one sample # -------------Plotting code ----------------- fig, ax = plt.subplots(1, 1, squeeze=True) ax.set_xlim(bounds["x"]) ax.set_ylim(bounds["gp_y"]) ax.grid() boplot.plot_gp(model=gp, confidence_intervals=[1.0, 2.0, 3.0], custom_x=x, ax=ax) boplot.plot_objective_function(ax=ax) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=False, highlight_datapoint=None, highlight_label=None, ax=ax) # Sample from the GP nsamples = 1 seed2 = 2 seed3 = 1375 X_ = boplot.get_plot_domain(precision=None) mu = gp.sample_y(X=X_, n_samples=nsamples, random_state=seed3) boplot.plot_gp_samples(mu=mu, nsamples=nsamples, precision=None, custom_x=X_, show_min=False, ax=ax, seed=seed2) ax.legend().set_zorder(zorders['legend']) ax.set_xlabel(labels['xlabel']) plt.tight_layout() if TOGGLE_PRINT: plt.savefig(f"{OUTPUT_DIR}/ts_2.pdf") else: plt.show() # ------------------------------------------- # 3. Mark minimum of sample # -------------Plotting code ----------------- fig, ax = plt.subplots(1, 1, squeeze=True) ax.set_xlim(bounds["x"]) ax.set_ylim(bounds["gp_y"]) ax.grid() # boplot.plot_gp(model=gp, confidence_intervals=[2.0], custom_x=x, ax=ax) boplot.plot_objective_function(ax=ax) boplot.mark_observations(X_=x, Y_=y, mark_incumbent=False, highlight_datapoint=None, highlight_label=None, ax=ax) # Sample from the GP nsamples = 1 X_ = boplot.get_plot_domain(precision=None) mu = gp.sample_y(X=X_, n_samples=nsamples, random_state=seed3) colors['highlighted_observations'] = 'red' # Special for Thompson Sampling boplot.plot_gp_samples(mu=mu, nsamples=nsamples, precision=None, custom_x=X_, show_min=True, ax=ax, seed=seed2) min_idx = np.argmin(mu, axis=0) candidate = X_[min_idx] cost = mu[min_idx] boplot.highlight_configuration(x=np.array([candidate]), label='', lloc='bottom', disable_ticks=True, ax=ax) boplot.annotate_x_edge(label=r'$\lambda^{(t)}$', xy=(candidate, cost), align='top', ax=ax) boplot.highlight_output(y=np.array([cost]), label='', lloc='left', disable_ticks=True, ax=ax) boplot.annotate_y_edge(label=r'$g(\lambda^{(t)})$', xy=(candidate, cost), align='left', ax=ax) ax.legend().set_zorder(zorders['legend']) ax.set_xlabel(labels['xlabel']) plt.tight_layout() if TOGGLE_PRINT: plt.savefig(f"{OUTPUT_DIR}/ts_3.pdf") else: plt.show()