def augment_the_new_data(self,x_max): # store X self.X = np.vstack((self.X, x_max.reshape((1, -1)))) # compute X in original scale temp_X_new_original=x_max*self.max_min_gap+self.bounds[:,0] self.X_original=np.vstack((self.X_original, temp_X_new_original)) # evaluate Y using original X #self.Y = np.append(self.Y, self.f(temp_X_new_original)) self.Y_original = np.append(self.Y_original, self.f(temp_X_new_original)) # update Y after change Y_original self.Y=(self.Y_original-np.mean(self.Y_original))/np.std(self.Y_original) # find the maximizer in the GP mean function try: len(self.gp) x_mu_max=[] for j in range(self.J): x_mu_max_temp=acq_max_with_name(gp=self.gp[j],scalebounds=self.scalebounds[self.featIdx[j]],acq_name="mu") x_mu_max=np.hstack((x_mu_max,x_mu_max_temp)) except: x_mu_max=acq_max_with_name(gp=self.gp,scalebounds=self.scalebounds,acq_name="mu") x_mu_max_original=x_mu_max*self.max_min_gap+self.bounds[:,0] # set y_max = mu_max #mu_max=acq_mu.acq_kind(x_mu_max,gp=self.gp) self.Y_original_maxGP = np.append(self.Y_original_maxGP, self.f(x_mu_max_original)) self.X_original_maxGP = np.vstack((self.X_original_maxGP, x_mu_max_original))
def acq_utility_cost(self): # generate a set of x* at T=MaxIter # instead of running optimization on the whole space, we will only operate on the region of interest # the region of interest in DRL is where the MaxEpisode # we find maximum of EI acq = {} acq['name'] = self.acq_name acq['dim'] = self.scaleSearchSpace.shape[0] acq['scaleSearchSpace'] = self.scaleSearchSpace if self.acq_name == 'ei_mu_max': # using max of mean(x) as the incumbent # optimie the GP predictive mean function to find the max of mu x_mu_max, mu_max_val = acq_max_with_name( gp=self.gp, scaleSearchSpace=self.scaleSearchSpace, acq_name='mu', IsReturnY=True) acq['mu_max'] = mu_max_val myacq = AcquisitionFunction(acq) x_min = acq_min_scipy_kwargs(myfunc=self.utility_cost_evaluation, SearchSpace=self.scaleSearchSpace, acq_func=myacq, isDebug=False) if self.verbose == True: acq_val = self.utility_cost_evaluation(x_min, myacq, isDebug=False) print("selected point from acq func:", np.round(x_min, decimals=4), "acq val=log(Utility/Cost)=", (-1) * np.round( acq_val, decimals=4)) # since we minimize the acq func if np.round(acq_val, decimals=4) == 0: print("acq value =0") return x_min
def suggest_nextpoint(self): # logistic, time-cost, virtual """ Main optimization method. Input parameters ---------- gp_params: parameter for Gaussian Process Returns ------- x: recommented point for evaluation """ if self.acq_name == 'random': x_max = [ np.random.uniform(x[0], x[1], size=1) for x in self.SearchSpace ] x_max = np.asarray(x_max) x_max = x_max.T self.X_original = np.vstack((self.X_original, x_max)) # evaluate Y using original X self.Y_original = np.append(self.Y_original, self.f(x_max)) # update Y after change Y_original self.Y = (self.Y_original - np.mean(self.Y_original)) / np.std( self.Y_original) self.time_opt = np.hstack((self.time_opt, 0)) return # init a new Gaussian Process #self.gp=ProductGaussianProcess(self.gp_params) self.gp = ProductGaussianProcess(self.scaleSearchSpace, verbose=self.verbose) self.gp.fit(self.X, self.T, self.Y, self.Y_curves) # optimize GP parameters after 3*d iterations if len(self.Y) % (3 * self.dim) == 0: hyper=[self.gp.hyper['lengthscale_x'],self.gp.hyper['lengthscale_t'], \ self.gp.logistic_hyper['midpoint'],self.gp.logistic_hyper['growth']] newlengthscale_x, newlengthscale_t, new_midpoint, new_growth = self.gp.optimize_lengthscale_logistic_hyper( hyper, self.gp.noise_delta) self.gp.hyper['lengthscale_x'] = newlengthscale_x self.gp.hyper['lengthscale_t'] = self.gp.hyper['lengthscale_t'] self.gp.logistic_hyper['midpoint'] = new_midpoint self.gp.logistic_hyper['growth'] = new_growth if self.verbose: print("estimated lengthscale_x={}, estimated lengthscale_t={}". format(newlengthscale_x, newlengthscale_t)) # Set acquisition function start_opt = time.time() # linear regression is used to fit the cost - alternatively we can use GP acq = {} acq['name'] = self.acq_name acq['dim'] = self.scaleSearchSpace.shape[0] acq['scaleSearchSpace'] = self.scaleSearchSpace if self.acq_name == 'ei_mu_max': # using max of mean(x) as the incumbent # optimie the GP predictive mean function to find the max of mu x_mu_max, mu_max_val = acq_max_with_name( gp=self.gp, scaleSearchSpace=self.scaleSearchSpace, acq_name='mu', IsReturnY=True) acq['mu_max'] = mu_max_val scaleSearchSpace = np.copy(self.scaleSearchSpace) scaleSearchSpace[-1, 0] = scaleSearchSpace[ -1, 1] # last dimension, set it to MaxIter #x_max_temp=acq_max_with_name(gp=self.gp,scaleSearchSpace=scaleSearchSpace,acq_name=self.acq_name) myacq = AcquisitionFunction(acq) #x_max = acq_max(ac=self.acq_func.acq_kind,gp=self.gp,bounds=self.scaleSearchSpace,opt_toolbox=self.opt_toolbox,seeds=self.xstars) x_max_temp = acq_max(ac=myacq.acq_kind, gp=self.gp, bounds=self.scaleSearchSpace) # x_max_temp = acq_min_scipy_kwargs(myfunc=myacq.acq_kind,bounds=self.scaleSearchSpace, # acq_func=myacq, isDebug=False) #x_max_temp=self.acq_utility_cost() x_max = x_max_temp[:-1] x_max_t = x_max_temp[-1] # record the optimization time finished_opt = time.time() elapse_opt = finished_opt - start_opt self.time_opt = np.hstack((self.time_opt, elapse_opt)) # store X self.X = np.vstack((self.X, x_max.reshape((1, -1)))) self.T = np.vstack((self.T, x_max_t.reshape((1, -1)))) # compute X in original scale temp_X_new_original = x_max * self.max_min_gap[: -1] + self.SearchSpace[: -1, 0] self.X_original = np.vstack((self.X_original, temp_X_new_original)) temp_T_new_original = x_max_t * self.max_min_gap[ -1] + self.SearchSpace[-1, 0] self.T_original = np.vstack((self.T_original, temp_T_new_original)) # evaluate Y using original X x_original_to_test = x_max_temp * self.max_min_gap + self.SearchSpace[:, 0] y_original_curves, y_cost_original = self.f(x_original_to_test) #y_original_curves= self.f(x_original_to_test) #y_cost_original=y_original_curves y_original=transform_logistic(y_original_curves,self.gp.logistic_hyper['midpoint'],\ self.gp.logistic_hyper['growth'],self.SearchSpace[-1,1]) #y_original=y_original_curves self.Y_curves.append(y_original_curves) self.Y_original = np.append(self.Y_original, y_original) self.Y_cost_original = np.append(self.Y_cost_original, y_cost_original) # update Y after change Y_original self.Y = (self.Y_original - np.mean(self.Y_original)) / np.std( self.Y_original) #self.Y_cost=(self.Y_cost_original-np.mean(self.Y_cost_original))/np.std(self.Y_cost_original) if self.verbose: print("x={} t={} current y={:.4f}, ybest={:.4f}".format( self.X_original[-1], self.T_original[-1], self.Y_original[-1], self.Y_original.max()))
def maximize_pvrs(self): """ Main optimization method. Input parameters ---------- gp_params: parameter for Gaussian Process Returns ------- x: recommented point for evaluation """ if self.stop_flag == 1: return if 'n_xstars' in self.acq: numXstar = self.acq['n_xstars'] else: numXstar = 10 * self.dim # Set acquisition function start_opt = time.time() y_max = self.Y.max() # run the acquisition function for the first time to get xstar self.xstars = [] # finding the xt of UCB numTheta = len(self.theta_vector) temp = [] # finding the xt of Thompson Sampling for ii in range(numXstar): if self.theta_vector != []: # since the numXstar > len(theta_vector) index = np.random.randint(numTheta) #print index gp_params['theta'] = self.theta_vector[index] # init a new Gaussian Process self.gp = GaussianProcess(self.gp_params) # Find unique rows of X to avoid GP from breaking ur = unique_rows(self.X) self.gp.fit(self.X[ur], self.Y[ur]) xt_TS, y_xt_TS = acq_max_with_name(gp=self.gp, scalebounds=self.scalebounds, acq_name="thompson", IsReturnY=True) temp.append(xt_TS) # check if f* > y^max and ignore xt_TS otherwise #if y_xt_TS>=y_max: #self.xstars.append(xt_TS) if self.xstars == []: #print 'xt_suggestion is empty' # again perform TS and take all of them self.xstars = temp # check predictive variance before adding a new data points var_before = self.gp.compute_var(self.gp.X, self.xstars) var_before = np.mean(var_before) if self.xstar_accumulate == []: self.xstar_accumulate = np.asarray(self.xstars) else: self.xstar_accumulate = np.vstack( (self.xstar_accumulate, np.asarray(self.xstars))) accum_var_before = [ self.gp.compute_var(self.gp.X, val) for idx, val in enumerate(self.xstar_accumulate) ] accum_var_before = np.mean(accum_var_before) self.gp.lengthscale_vector = self.theta_vector self.acq['xstars'] = self.xstars self.acq_func = AcquisitionFunction(self.acq) x_max = acq_max(ac=self.acq_func.acq_kind, gp=self.gp, bounds=self.scalebounds, opt_toolbox=self.opt_toolbox, seeds=self.xstars) #xstars_array=np.asarray(self.acq_func.object.xstars) val_acq = -self.acq_func.acq_kind(x_max, self.gp) # check predictive variance after temp = np.vstack((self.gp.X, x_max)) var_after = self.gp.compute_var(temp, self.xstars) var_after = np.mean(var_after) accum_var_after = [ self.gp.compute_var(temp, val) for idx, val in enumerate(self.xstar_accumulate) ] accum_var_after = np.mean(accum_var_after) if self.PVRS_before_after == []: self.PVRS_before_after = np.asarray([var_before, var_after]) self.accummulate_PVRS_before_after = np.asarray( [accum_var_before, accum_var_after]) else: self.PVRS_before_after = np.vstack( (self.PVRS_before_after, np.asarray([var_before, var_after]))) self.accummulate_PVRS_before_after = np.vstack( (self.accummulate_PVRS_before_after, np.asarray([accum_var_before, accum_var_after]))) #print "predictive variance before={:.12f} after={:.12f} val_acq={:.12f}".format(var_before,var_after,np.asscalar(val_acq)) # check maximum variance var_acq = {} var_acq['name'] = 'pure_exploration' var_acq['dim'] = self.dim var_acq['scalebounds'] = self.scalebounds acq_var = AcquisitionFunction(var_acq) temp = acq_max(ac=acq_var.acq_kind, gp=self.gp, bounds=self.scalebounds, opt_toolbox='scipy') # get the value f* #max_var_after=acq_var.acq_kind(temp,self.gp,y_max=y_max) #print "max predictive variance ={:.8f}".format(np.asscalar(max_var_after)) if self.stopping_criteria != 0 and val_acq < self.stopping_criteria: val_acq = self.acq_func.acq_kind(x_max, self.gp) self.stop_flag = 1 print( "Stopping Criteria is violated. Stopping Criteria is {:.15f}". format(self.stopping_criteria)) #mean,var=self.gp.predict(x_max, eval_MSE=True) #var.flags['WRITEABLE']=True #var[var<1e-20]=0 #self.Tau_Xt= np.append(self.Tau_Xt,val_acq/var) # record the optimization time finished_opt = time.time() elapse_opt = finished_opt - start_opt self.time_opt = np.hstack((self.time_opt, elapse_opt)) super(BayesOpt, self).augment_the_new_data(x_max)
def maximize_e3i(self): """ Main optimization method. Input parameters ---------- gp_params: parameter for Gaussian Process Returns ------- x: recommented point for evaluation """ if self.stop_flag == 1: return # Set acquisition function start_opt = time.time() y_max = self.Y.max() # run the acquisition function for the first time to get xstar self.xstars = [] # finding the xt of UCB y_max = np.max(self.Y) numXtar = 50 * self.dim #numXtar=20 y_stars = [] temp = [] # finding the xt of Thompson Sampling for ii in range(numXtar): xt_TS, y_xt_TS = acq_max_with_name(gp=self.gp, scalebounds=self.scalebounds, acq_name="thompson", IsReturnY=True) y_stars.append(y_xt_TS) temp.append(xt_TS) # check if f* > y^max and ignore xt_TS otherwise #if y_xt_TS>=y_max: self.xstars.append(xt_TS) #y_stars=y_stars*np.std(self.Y_original)+np.mean(self.Y_original) #print "{:.5f} {:.6f}".format(np.mean(y_stars),np.std(y_stars)) #print "ymax={:.5f}".format(np.max(self.Y)) if self.acq['debug'] == 1: print('mean y*={:.4f}({:.8f}) y+={:.4f}'.format( np.mean(y_xt_TS), np.std(y_xt_TS), y_max)) if self.xstars == []: #print 'xt_suggestion is empty' # again perform TS and take all of them self.xstars = temp self.acq['xstars'] = self.xstars self.acq['ystars'] = y_stars self.acq_func = AcquisitionFunction(self.acq) x_max = acq_max(ac=self.acq_func.acq_kind, gp=self.gp, bounds=self.scalebounds, opt_toolbox=self.opt_toolbox, seeds=self.xstars) #xstars_array=np.asarray(self.acq_func.object.xstars) val_acq = self.acq_func.acq_kind(x_max, self.gp) if self.stopping_criteria != 0 and val_acq < self.stopping_criteria: val_acq = self.acq_func.acq_kind(x_max, self.gp) self.stop_flag = 1 print( "Stopping Criteria is violated. Stopping Criteria is {:.15f}". format(self.stopping_criteria)) # record the optimization time finished_opt = time.time() elapse_opt = finished_opt - start_opt self.time_opt = np.hstack((self.time_opt, elapse_opt)) super(BayesOpt, self).augment_the_new_data(x_max)
def maximize(self): """ Main optimization method. Input parameters ---------- gp_params: parameter for Gaussian Process Returns ------- x: recommented point for evaluation """ if self.stop_flag == 1: return if self.acq['name'] == 'random': super(BayesOpt, self).generate_random_point() return # init a new Gaussian Process self.gp = GaussianProcess(self.gp_params) if self.gp.KK_x_x_inv == []: # Find unique rows of X to avoid GP from breaking ur = unique_rows(self.X) self.gp.fit(self.X[ur], self.Y[ur]) acq = self.acq # optimize GP parameters after 10 iterations if len(self.Y) % (2 * self.dim) == 0: self.gp, self.gp_params = super(BayesOpt, self).optimize_gp_hyperparameter() if self.acq['name'] == 'mes': self.maximize_mes() return if self.acq['name'] == 'pvrs': self.maximize_pvrs() return if self.acq['name'] == 'e3i': self.maximize_e3i() return if self.acq['name'] == 'ei_kov' or self.acq[ 'name'] == 'poi_kov' or self.acq['name'] == 'ei_fstar': self.acq['fstar_scaled'] = (self.acq['fstar'] - np.mean( self.Y_original)) / np.std(self.Y_original) # Set acquisition function start_opt = time.time() #y_max = self.Y.max() if 'xstars' not in globals(): xstars = [] self.xstars = xstars self.acq['xstars'] = xstars self.acq_func = AcquisitionFunction(self.acq) if acq['name'] == "ei_mu": #find the maximum in the predictive mean x_mu_max, y_max = acq_max_with_name(gp=self.gp, scalebounds=self.scalebounds, acq_name='mu', IsReturnY=True) x_max = acq_max(ac=self.acq_func.acq_kind, gp=self.gp, bounds=self.scalebounds, opt_toolbox=self.opt_toolbox, seeds=self.xstars) val_acq = self.acq_func.acq_kind(x_max, self.gp) if self.stopping_criteria != 0 and val_acq < self.stopping_criteria: #val_acq=self.acq_func.acq_kind(x_max,self.gp) self.stop_flag = 1 #print "Stopping Criteria is violated. Stopping Criteria is {:.15f}".format(self.stopping_criteria) self.alpha_Xt = np.append(self.alpha_Xt, val_acq) mean, var = self.gp.predict(x_max, eval_MSE=True) var.flags['WRITEABLE'] = True var[var < 1e-20] = 0 #self.Tau_Xt= np.append(self.Tau_Xt,val_acq/var) # record the optimization time finished_opt = time.time() elapse_opt = finished_opt - start_opt self.time_opt = np.hstack((self.time_opt, elapse_opt)) super(BayesOpt, self).augment_the_new_data(x_max)
def maximize_with_lengthscale_derived_by_fstar(self, gp_params): """ Main optimization method. Input parameters ---------- gp_params: parameter for Gaussian Process Returns ------- x: recommented point for evaluation """ if self.stop_flag == 1: return if self.acq['name'] == 'random': x_max = [ np.random.uniform(x[0], x[1], size=1) for x in self.bounds ] x_max = np.asarray(x_max) x_max = x_max.T self.X_original = np.vstack((self.X_original, x_max)) # evaluate Y using original X #self.Y = np.append(self.Y, self.f(temp_X_new_original)) self.Y_original = np.append(self.Y_original, self.f(x_max)) # update Y after change Y_original self.Y = (self.Y_original - np.mean(self.Y_original)) / np.std( self.Y_original) self.time_opt = np.hstack((self.time_opt, 0)) return # init a new Gaussian Process self.gp = GaussianProcess(gp_params) if self.gp.KK_x_x_inv == []: # Find unique rows of X to avoid GP from breaking ur = unique_rows(self.X) self.gp.fit(self.X[ur], self.Y[ur]) acq = self.acq # optimize GP parameters after 10 iterations if len(self.Y) % (3 * self.dim) == 0: fstar_scaled = (self.acq['fstar'] - np.mean(self.Y_original)) / np.std(self.Y_original) newlengthscale = self.gp.optimize_lengthscale_SE_fstar( self.gp_params['lengthscale'], self.gp_params['noise_delta'], fstar_scaled) self.gp_params['lengthscale'] = newlengthscale print("estimated lengthscale =", newlengthscale) # init a new Gaussian Process after optimizing hyper-parameter self.gp = GaussianProcess(gp_params) # Find unique rows of X to avoid GP from breaking ur = unique_rows(self.X) self.gp.fit(self.X[ur], self.Y[ur]) if self.acq['name'] == 'mes': self.maximize_mes(gp_params) return if self.acq['name'] == 'pvrs': self.maximize_pvrs(gp_params) return if self.acq['name'] == 'e3i': self.maximize_e3i(gp_params) return if self.acq['name'] == 'ei_kov' or self.acq[ 'name'] == 'poi_kov' or self.acq['name'] == 'ei_fstar': self.acq['fstar_scaled'] = (self.acq['fstar'] - np.mean( self.Y_original)) / np.std(self.Y_original) # Set acquisition function start_opt = time.time() y_max = self.Y.max() if 'xstars' not in globals(): xstars = [] self.xstars = xstars self.acq['xstars'] = xstars self.acq_func = AcquisitionFunction(self.acq) if acq['name'] == "ei_mu": #find the maximum in the predictive mean x_mu_max, y_max = acq_max_with_name(gp=self.gp, scalebounds=self.scalebounds, acq_name='mu', IsReturnY=True) x_max = acq_max(ac=self.acq_func.acq_kind, gp=self.gp, bounds=self.scalebounds, opt_toolbox=self.opt_toolbox, seeds=self.xstars) val_acq = self.acq_func.acq_kind(x_max, self.gp) if self.stopping_criteria != 0 and val_acq < self.stopping_criteria: val_acq = self.acq_func.acq_kind(x_max, self.gp) self.stop_flag = 1 #print "Stopping Criteria is violated. Stopping Criteria is {:.15f}".format(self.stopping_criteria) self.alpha_Xt = np.append(self.alpha_Xt, val_acq) mean, var = self.gp.predict(x_max, eval_MSE=True) var.flags['WRITEABLE'] = True var[var < 1e-20] = 0 #self.Tau_Xt= np.append(self.Tau_Xt,val_acq/var) # record the optimization time finished_opt = time.time() elapse_opt = finished_opt - start_opt self.time_opt = np.hstack((self.time_opt, elapse_opt)) # store X self.X = np.vstack((self.X, x_max.reshape((1, -1)))) # compute X in original scale temp_X_new_original = x_max * self.max_min_gap + self.bounds[:, 0] self.X_original = np.vstack((self.X_original, temp_X_new_original)) # evaluate Y using original X #self.Y = np.append(self.Y, self.f(temp_X_new_original)) self.Y_original = np.append(self.Y_original, self.f(temp_X_new_original)) # update Y after change Y_original self.Y = (self.Y_original - np.mean(self.Y_original)) / np.std( self.Y_original) if self.gp.flagIncremental == 1: self.gp.fit_incremental(x_max, self.Y[-1])
def maximize_batch_greedy_PVRS(self,B=5): """ Finding a batch of points using Peak Suppression / Constant Liar approach Input Parameters ---------- gp_params: Parameters to be passed to the Gaussian Process class kappa: constant value in UCB Returns ------- X: a batch of [x_1..x_Nt] """ y_max = self.Y.max() # Set parameters if any was passed self.gp=GaussianProcess(self.gp_params) # Find unique rows of X to avoid GP from breaking ur = unique_rows(self.X) self.gp.fit(self.X[ur], self.Y[ur]) start_opt=time.time() if 'n_xstars' in self.acq: numXtar=self.acq['n_xstars'] else: numXtar=30*self.dim #temp=[] # finding the xt of Thompson Sampling xstars=[] for ii in range(numXtar): mu_acq={} mu_acq['name']='thompson' mu_acq['dim']=self.dim mu_acq['scalebounds']=self.scalebounds acq_mu=AcquisitionFunction(mu_acq) xt_TS = acq_max(ac=acq_mu.acq_kind,gp=self.gp,bounds=self.scalebounds,opt_toolbox='scipy') #temp.append(xt_TS) xstars.append(xt_TS) self.xstars=xstars # Set acquisition function myacq={} myacq['name']='pvrs' myacq['dim']=self.acq['dim'] myacq['xstars']=xstars acq_func = AcquisitionFunction(myacq) # copy GP, X and Y temp_gp=copy.deepcopy(self.gp) temp_X=copy.deepcopy(self.X) temp_Y=copy.deepcopy(self.Y) #temp_Y_original=self.Y_original start_batch=time.time() # check predictive variance before adding a new data points var_before=self.gp.compute_var(temp_X,xstars) var_before=np.mean(var_before) #store new_x new_X=np.empty((0,self.dim),float) for ii in range(B): # Finding argmax of the acquisition function. x_max = acq_max(ac=acq_func.acq_kind,gp=temp_gp, bounds=self.scalebounds) new_X= np.vstack((new_X, x_max.reshape((1, -1)))) temp_X = np.vstack((temp_X, x_max.reshape((1, -1)))) # check predictive variance after var_after=self.gp.compute_var(temp_X,xstars) var_after=np.mean(var_after) if self.PVRS_before_after==[]: self.PVRS_before_after=np.asarray([var_before,var_after]) else: temp_var=np.asarray([var_before,var_after]) self.PVRS_before_after=np.vstack((self.PVRS_before_after, temp_var)) var_before=var_after const_liar,const_liar_variance=temp_gp.predict(x_max,eval_MSE=1) const_liar=np.random.rand() temp_Y = np.append(temp_Y, const_liar ) temp_gp.fit(temp_X,temp_Y) # for debug finish_batch=time.time()-start_batch #return new_X,new_X_original self.NumPoints=np.append(self.NumPoints,new_X.shape[0]) self.X=np.vstack((self.X,new_X)) # convert back to original scale temp_X_new_original=[val*self.max_min_gap+self.bounds[:,0] for idx, val in enumerate(new_X)] temp_X_new_original=np.asarray(temp_X_new_original) self.X_original=np.vstack((self.X_original, temp_X_new_original)) # evaluate y=f(x) temp=self.f(temp_X_new_original) temp=np.reshape(temp,(-1,1)) self.Y_original=np.append(self.Y_original,temp) self.Y=(self.Y_original-np.mean(self.Y_original))/(np.max(self.Y_original)-np.min(self.Y_original)) # find the maximizer in the GP mean function try: len(self.gp) x_mu_max=[] for j in range(self.J): x_mu_max_temp=acq_max_with_name(gp=self.gp[j],scalebounds=self.scalebounds[self.featIdx[j]],acq_name="mu") x_mu_max=np.hstack((x_mu_max,x_mu_max_temp)) except: x_mu_max=acq_max_with_name(gp=self.gp,scalebounds=self.scalebounds,acq_name="mu") x_mu_max_original=x_mu_max*self.max_min_gap+self.bounds[:,0] # set y_max = mu_max #mu_max=acq_mu.acq_kind(x_mu_max,gp=self.gp) self.Y_original_maxGP = np.append(self.Y_original_maxGP, self.f(x_mu_max_original)) self.X_original_maxGP = np.vstack((self.X_original_maxGP, x_mu_max_original)) return new_X
def select_informative_location_by_uncertainty(self, n_virtual_obs, x_max, t_max): # this function will select a list of informative locations to place a virtual obs # x_max is the selected hyperparameter # t_max is the selected number of epochs to train SearchSpace = np.copy(self.scaleSearchSpace) for dd in range(self.dim - 1): SearchSpace[dd, 0], SearchSpace[dd, 1] = x_max[dd], x_max[dd] SearchSpace[-1, 1] = t_max temp_X, temp_T = self.X.copy(), self.T.copy() temp_gp = copy.deepcopy(self.gp) temp_Y = np.random.random(size=(len(temp_T), 1)) temp_gp.fit(temp_X, temp_T, temp_Y, self.Y_curves) new_batch_T = None pred_var_value = [0] * n_virtual_obs for ii in range(n_virtual_obs): x_max_pred_variance, pred_var_value[ii] = acq_max_with_name( gp=temp_gp, scaleSearchSpace=SearchSpace, acq_name='pure_exploration', IsReturnY=True) # stop augmenting if the uncertainty is smaller than a threshold # or stop augmenting if the uncertainty is smaller than a threshold log_cond = np.log(temp_gp.compute_condition_number()) if log_cond > self.threshold_cond or pred_var_value[ii] < ( self.gp.noise_delta + 1e-3): break if x_max_pred_variance[-1] in temp_T[ -ii:]: # if repetition, stop augmenting break temp_X = np.vstack((temp_X, x_max.reshape( (1, -1)))) # append new x temp_T = np.vstack((temp_T, x_max_pred_variance[-1].reshape( (1, -1)))) # append new t temp_gp.X, temp_gp.T = temp_X, temp_T temp_Y = np.random.random(size=(len(temp_T), 1)) temp_gp.fit(temp_X, temp_T, temp_Y, self.Y_curves) if new_batch_T is None: new_batch_T = x_max_pred_variance[-1].reshape((1, -1)) else: new_batch_T = np.vstack( (new_batch_T, x_max_pred_variance[-1].reshape((1, -1)))) # if self.verbose: # print("pred_var_value at the augmented points:",np.round( pred_var_value,decimals=4)) if new_batch_T is None: return [], 0 else: output = np.sort(new_batch_T.ravel()).tolist() return output, len(output)
def maximize(self): """ Main optimization method. Input parameters ---------- gp_params: parameter for Gaussian Process Returns ------- x: recommented point for evaluation """ if self.stop_flag == 1: return if self.acq['name'] == 'random': x_max = generate_random_points(bounds=self.scalebounds, size=1) self.X_original = np.vstack((self.X_original, x_max)) # evaluate Y using original X #self.Y = np.append(self.Y, self.f(temp_X_new_original)) self.Y_original = np.append(self.Y_original, self.f(x_max)) # update Y after change Y_original self.Y = (self.Y_original - np.mean(self.Y_original)) / np.std( self.Y_original) self.time_opt = np.hstack((self.time_opt, 0)) return fstar_scaled = (self.fstar - np.mean(self.Y_original)) / np.std( self.Y_original) # init a new Gaussian Process if self.isTGP == 1: self.gp = TransformedGP(self.gp_params) # Find unique rows of X to avoid GP from breaking ur = unique_rows(self.X) self.gp.fit(self.X[ur], self.Y[ur], fstar_scaled) else: self.gp = GaussianProcess(self.gp_params) ur = unique_rows(self.X) self.gp.fit(self.X[ur], self.Y[ur]) # optimize GP parameters after 10 iterations newlengthscale = None # we donot optimize lengthscale for the setting of gp_lengthscale if len(self.Y) % (4 * self.dim) == 0: if self.optimize_gp == 'maximize': newlengthscale = self.gp.optimize_lengthscale_SE_maximizing( self.gp_params['lengthscale'], self.gp_params['noise_delta']) self.gp_params['lengthscale'] = newlengthscale elif self.optimize_gp == 'loo': newlengthscale = self.gp.optimize_lengthscale_SE_loo( self.gp_params['lengthscale'], self.gp_params['noise_delta']) self.gp_params['lengthscale'] = newlengthscale if self.verbose == 1: print("estimated lengthscale =", newlengthscale) # init a new Gaussian Process after optimizing hyper-parameter if self.isTGP == 1: self.gp = TransformedGP(self.gp_params) # Find unique rows of X to avoid GP from breaking ur = unique_rows(self.X) self.gp.fit(self.X[ur], self.Y[ur], fstar_scaled) else: self.gp = GaussianProcess(self.gp_params) ur = unique_rows(self.X) self.gp.fit(self.X[ur], self.Y[ur]) # Set acquisition function start_opt = time.time() # run the acquisition function for the first time to get xstar self.xstars = [] fstar_scaled = (self.fstar - np.mean(self.Y_original)) / np.std( self.Y_original) fstar_scaled = (self.fstar - np.mean(self.Y_original)) / np.std( self.Y_original) self.acq['fstar_scaled'] = np.asarray([fstar_scaled]) x_max = acq_max_with_name(gp=self.gp, scalebounds=self.scalebounds, acq_name=self.acq['name'], fstar_scaled=fstar_scaled) """ self.acq_func = AcquisitionFunction(self.acq) x_max = acq_max(ac=self.acq_func.acq_kind,gp=self.gp,bounds=self.scalebounds, opt_toolbox=self.opt_toolbox) """ # record the optimization time finished_opt = time.time() elapse_opt = finished_opt - start_opt self.time_opt = np.hstack((self.time_opt, elapse_opt)) # store X self.X = np.vstack((self.X, x_max.reshape((1, -1)))) # compute X in original scale temp_X_new_original = x_max * self.max_min_gap + self.bounds[:, 0] self.X_original = np.vstack((self.X_original, temp_X_new_original)) # evaluate Y using original X #self.Y = np.append(self.Y, self.f(temp_X_new_original)) y_original = self.f(temp_X_new_original) self.Y_original = np.append(self.Y_original, y_original) # update Y after change Y_original self.Y = (self.Y_original - np.mean(self.Y_original)) / np.std( self.Y_original) if self.gp.flagIncremental == 1: self.gp.fit_incremental(x_max, self.Y[-1])