Exemplo n.º 1
0
    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))
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
    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])
Exemplo n.º 8
0
    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
Exemplo n.º 9
0
    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])