Exemplo n.º 1
0
def mems_exp(cfg):
    log.info("============= Configuration =============")
    log.info(f"Config:\n{cfg.pretty()}")
    log.info("=========================================")

    search_space = gen_search_space(cfg.problem)
    outcome_con = gen_outcome_constraints(cfg.problem)

    exp = SimpleExperiment(
        name=cfg.problem.name,
        search_space=SearchSpace(search_space),
        evaluation_function=jumper,
        objective_name="Energy_(uJ)",
        minimize=False,
        outcome_constraints=outcome_con,
    )

    optimization_config = OptimizationConfig(objective=Objective(
        metric=MEMsMetric(name="Energy_(uJ)"),
        minimize=False,
    ), )

    class MyRunner(Runner):
        def run(self, trial):
            return {"name": str(trial.index)}

    exp.runner = MyRunner()
    exp.optimization_config = optimization_config
    from ax.utils.notebook.plotting import render, init_notebook_plotting
    from ax.plot.contour import plot_contour

    print(f"Running {cfg.bo.random} Sobol initialization trials...")
    sobol = Models.SOBOL(exp.search_space)
    num_search = cfg.bo.random
    for i in range(num_search):
        exp.new_trial(generator_run=sobol.gen(1))
        exp.trials[len(exp.trials) - 1].run()

    # data = exp.fetch_data()

    num_opt = cfg.bo.optimized
    for i in range(num_opt):
        if (i % 5) == 0 and cfg.plot_during:
            plot = plot_contour(
                model=gpei,
                param_x="N",
                param_y="L",
                metric_name="Energy_(uJ)",
            )
            data = plot[0]['data']
            lay = plot[0]['layout']

            render(plot)

        print(f"Running GP+EI optimization trial {i + 1}/{num_opt}...")
        # Reinitialize GP+EI model at each step with updated data.
        batch = exp.new_trial(generator_run=gpei.gen(1))
        gpei = Models.BOTORCH(experiment=exp, data=exp.eval())

    plot_learn = plot_learning(exp, cfg)
    # go.Figure(plot_learn).show()
    save_fig([plot_learn], "optimize")

    from ax.utils.notebook.plotting import render, init_notebook_plotting
    from ax.plot.contour import plot_contour

    plot = plot_contour(model=gpei,
                        param_x="N",
                        param_y="L",
                        metric_name="Energy_(uJ)",
                        lower_is_better=cfg.metric.minimize)
    save_fig(plot, dir=f"N_L_Energy")
    # render(plot)

    plot = plot_contour(model=gpei,
                        param_x="N",
                        param_y="w",
                        metric_name="Energy_(uJ)",
                        lower_is_better=cfg.metric.minimize)
    # render(plot)
    save_fig(plot, dir=f"N_w_Energy")

    plot = plot_contour(model=gpei,
                        param_x="w",
                        param_y="L",
                        metric_name="Energy_(uJ)",
                        lower_is_better=cfg.metric.minimize)
    save_fig(plot, dir=f"w_L_Energy")
Exemplo n.º 2
0
class optimization():

    def __init__(self):
        self.max_worker = multiprocessing.cpu_count()
        if self.max_worker > 1:
            self.max_worker -= 5
        #self.max_worker = 1
        
        self.best_obj_so_far = float('-inf')
        self.exp = None #define an experiment for ax
        self.best_parameters_from_experiment = None
        self.global_iteration_count = 0

    
    def evaluate_parameter(self,parameter, weight=None):
        total_returns = []
        
        q = multiprocessing.Queue(maxsize = self.max_worker)

        for iteration_index in range(0,C.ROUNDS_OF_WORKER):
            p_list = []
            for worker in range(0,self.max_worker):
                try:
                    p = multiprocessing.Process(target = self.get_one_sample_score,\
                                                args = (q,parameter))
                    p.start()
                    p_list.append(p)
                except:
                    pass

            for j in range(len(p_list)):
                res = q.get()
                total_returns.append(res[0])
                
        self.global_iteration_count += 1

        if np.mean(total_returns)>self.best_obj_so_far:
            self.best_obj_so_far = np.mean(total_returns)
            self.best_parameters_from_experiment = parameter
            print('the best objective so far is',self.best_obj_so_far)
            print('the associated best parameters are',parameter)
            print('the current time is',datetime.datetime.now())
            cwd = os.getcwd()
            parameter_file = 'best_parameter_from_direct_experiment.json'
            cwd = os.path.join(cwd,parameter_file)
            with open(cwd, 'w') as statusFile:
                statusFile.write(jsonpickle.encode(self.best_parameters_from_experiment))

        print('this is global iteration',self.global_iteration_count)
        print('the objective for ths iteration is',np.mean(total_returns))
        print('the current time is',datetime.datetime.now())
        print(' ')

        optimization_objective = (np.mean(total_returns) - np.std(total_returns) * 0.5, np.std(total_returns))
        

        return {'adj_return': optimization_objective}


    def get_one_sample_score(self,q,free_parameters):

        free_para1 = free_parameters['cov_para_1']
        free_para2 = free_parameters['cov_para_2']
        free_para3 = free_parameters['cov_para_3']
        free_para4 = free_parameters['cov_para_4']
        free_para5 = free_parameters['cov_para_5']
        free_para6 = free_parameters['cov_para_6']
        free_para7 = free_parameters['cov_para_7']
        free_para8 = free_parameters['cov_para_8']
        free_para9 = free_parameters['cov_para_9']
        free_para10 = free_parameters['cov_para_10']

        diag_1 = 1
        diag_2 = np.sqrt(1-free_para1**2)
        if (1-free_para2**2-free_para3**2)<0:
            diag_3 = np.sqrt(np.abs(1-free_para2**2-free_para3**2))
        else:
            diag_3 = np.sqrt(1-free_para2**2-free_para3**2)

        if (1-free_para4**2-free_para5**2-free_para6**2)<0:
            diag_4 = np.sqrt(np.abs(1-free_para4**2-free_para5**2-free_para6**2))
        else:
            diag_4 = np.sqrt(1-free_para4**2-free_para5**2-free_para6**2)
        
        if (1-free_para7**2-free_para8**2-free_para9**2-free_para10**2)<0:
            diag_5 = np.sqrt(np.abs(1-free_para7**2-free_para8**2-free_para9**2-free_para10**2))
        else:
            diag_5 = np.sqrt(1-free_para7**2-free_para8**2-free_para9**2-free_para10**2)



        lower_triangular_matrix = np.asarray([[diag_1,0,0,0,0],
                                [free_para1,diag_2,0,0,0],
                                [free_para2,free_para3,diag_3,0,0],
                                [free_para4,free_para5,free_para6,diag_4,0],
                                [free_para7,free_para8,free_para9,free_para10,diag_5]])


        cov_matrix = lower_triangular_matrix@lower_triangular_matrix.transpose()


        #now, define the marginal distribution of the gaussian copula
        univerates = [{'loc': 0,
        'scale': 1,
        'a': free_parameters['beta_1a'],
        'b': free_parameters['beta_1b'],
        'type': 'copulas.univariate.beta.BetaUnivariate'},
        {'loc': 0,
        'scale': 1,
        'a': free_parameters['beta_2a'],
        'b': free_parameters['beta_2b'],
        'type': 'copulas.univariate.beta.BetaUnivariate'},
        {'loc': 0,
        'scale': 1,
        'a': free_parameters['beta_3a'],
        'b': free_parameters['beta_3b'],
        'type': 'copulas.univariate.beta.BetaUnivariate'},
        {'loc': 0,
        'scale': 1,
        'a': free_parameters['beta_4a'],
        'b': free_parameters['beta_4b'],
        'type': 'copulas.univariate.beta.BetaUnivariate'},
        {'loc': 0,
        'scale': 1,
        'a': free_parameters['beta_5a'],
        'b': free_parameters['beta_5b'],
        'type': 'copulas.univariate.beta.BetaUnivariate'}]


        #now, we construct the gaussian copula
        copula_parameters = {}
        copula_parameters['covariance'] = cov_matrix
        copula_parameters['univariates'] = univerates
        copula_parameters['type'] = 'copulas.multivariate.gaussian.GaussianMultivariate'
        copula_parameters['columns'] = [0,1,2,3,4]

        new_dist = Multivariate.from_dict(copula_parameters)

        #other parameters needed for transforming the features
        lambda_expon_1 = free_parameters['lambda_expon_1']
        lambda_expon_2 = free_parameters['lambda_expon_2']
        lambda_expon_3 = free_parameters['lambda_expon_3']
        lambda_expon_4 = free_parameters['lambda_expon_4']
        lambda_expons = [lambda_expon_1,lambda_expon_2,lambda_expon_3,lambda_expon_4]


        #now, we begin to simulate trading
        #first, initialize the observation
        locol_env = trading_vix.trading_vix()
        this_trajectory_reward = []
        has_at_least_sell = False
        null_objective = True
        current_feature = locol_env.reset()

        for time_index in range(0,200):
        
            #compute an action given current observation
            transformed_features = []
            for feature_index in range(len(lambda_expons)):
                transformation = expon.cdf(current_feature[feature_index,0],scale = 1.0/lambda_expons[feature_index])
                min_transformation = 0.1
                transformation = min_transformation*np.exp(np.log(1.0/min_transformation)*transformation)
                transformed_features.append(transformation)
            transformed_features = np.asarray(transformed_features)
            transformed_features = np.reshape(transformed_features,(1,-1))
            #holding_position = expit(current_feature[-1,:][0])
            holding_position = current_feature[-1,:][0]
            if holding_position<0:
                print('holding is less than 0, there is some problem and the holding position is',holding_position)
            if holding_position>1:
                print('holding is greater than 1, there is some problem and the holding position is',holding_position)
            min_transformed_holding = 0.1
            transformed_holding = min_transformed_holding*np.exp(np.log(1.0/min_transformed_holding)*holding_position)
            transformed_holding = np.reshape(transformed_holding,(1,1))
            data_point_for_df = np.concatenate((transformed_features,transformed_holding),axis = 1)

            assert data_point_for_df.shape[1] == 5
            data_point_for_copula = pd.DataFrame(data_point_for_df)
            action = new_dist.cdf(data_point_for_copula)

            #print('action in optimization trading vix is',action)

            #apply the action to the environment
            current_feature, reward, has_at_least_sell = locol_env.step(action)

            if has_at_least_sell and null_objective:
                #print('sold at least once')
                null_objective = False

            #record reward
            this_trajectory_reward.append(reward)

        #final time step,get the long term reward
        reward = locol_env.final()
        this_trajectory_reward.append(reward)

        if null_objective:
            objective = -1e9
        else:
            objective = np.sum(this_trajectory_reward)

        q.put([objective])


    def init_search_space(self):
        search_space = SearchSpace(
        parameters=[
            RangeParameter(name="cov_para_1", parameter_type=ParameterType.FLOAT, lower=-0.9, upper=0.9),
            RangeParameter(name="cov_para_2", parameter_type=ParameterType.FLOAT, lower=-0.9, upper=0.9),
            RangeParameter(name="cov_para_3", parameter_type=ParameterType.FLOAT, lower=-0.9, upper=0.9),
            RangeParameter(name="cov_para_4", parameter_type=ParameterType.FLOAT, lower=-0.9, upper=0.9),
            RangeParameter(name="cov_para_5", parameter_type=ParameterType.FLOAT, lower=-0.9, upper=0.9),
            RangeParameter(name="cov_para_6", parameter_type=ParameterType.FLOAT, lower=-0.9, upper=0.9),
            RangeParameter(name="cov_para_7", parameter_type=ParameterType.FLOAT, lower=-0.9, upper=0.9),
            RangeParameter(name="cov_para_8", parameter_type=ParameterType.FLOAT, lower=-0.9, upper=0.9),
            RangeParameter(name="cov_para_9", parameter_type=ParameterType.FLOAT, lower=-0.9, upper=0.9),
            RangeParameter(name="cov_para_10", parameter_type=ParameterType.FLOAT, lower=-0.9, upper=0.9),

            RangeParameter(name="beta_1a", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_1b", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_2a", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_2b", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_3a", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_3b", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_4a", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_4b", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_5a", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_5b", parameter_type=ParameterType.FLOAT, lower=0, upper=20),

            RangeParameter(name="lambda_expon_1", parameter_type=ParameterType.FLOAT, lower=0.001, upper=0.1),
            RangeParameter(name="lambda_expon_2", parameter_type=ParameterType.FLOAT, lower=0.001, upper=0.1),
            RangeParameter(name="lambda_expon_3", parameter_type=ParameterType.FLOAT, lower=0.001, upper=0.1),
            RangeParameter(name="lambda_expon_4", parameter_type=ParameterType.FLOAT, lower=0.001, upper=0.1),
            ]
        )

        self.exp = SimpleExperiment(
        name="0",
        search_space=search_space,
        evaluation_function=self.evaluate_parameter,
        objective_name="adj_return"
        )


    def initialization_trials(self):
        sobol = Models.SOBOL(self.exp.search_space)
        for i in range(C.INITIALIZATION_TRIALS):
            self.exp.new_trial(generator_run=sobol.gen(1))


    def optimization_trials(self):
        device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
        device = torch.device("cpu")
        print(device)
        for i in range(C.OPTIMIZATION_TRIALS):
            print('Running GP+EI optimization trial', i+1)
            # Reinitialize GP+EI model at each step with updated data.
            #gpei = Models.GPEI(experiment=self.exp, data=self.exp.eval(), dtype=torch.float32, device=device)
            gpei = Models.GPEI(experiment=self.exp, data=self.exp.eval())
            batch = self.exp.new_trial(generator_run=gpei.gen(1))

    
    def get_best_parameters(self):
        _, trial = list(self.exp.trials.items())[-1]
        print(trial)
        trial.generator_run
        gr = trial.generator_run
        best_arm, best_arm_predictions = gr.best_arm_predictions
        best_parameters = best_arm.parameters
        self.best_parameters = best_parameters
        print('the best parameters are',best_parameters)


    def store_parameters(self):
        cwd = os.getcwd()
        #cwd = os.path.join(cwd, 'data_folder')
        parameter_file = 'best_parameter_from_multi_armed_bandit.json'
        cwd = os.path.join(cwd,parameter_file)
        with open(cwd, 'w') as statusFile:
            statusFile.write(jsonpickle.encode(self.best_parameters))

        cwd = os.getcwd()
        parameter_file = 'best_parameter_from_direct_experiment.json'
        cwd = os.path.join(cwd,parameter_file)
        with open(cwd, 'w') as statusFile:
            statusFile.write(jsonpickle.encode(self.best_parameters_from_experiment))


    
    def run_optimization(self):


        self.init_search_space()

        print('Begin initialization trials')

        self.initialization_trials()

        self.optimization_trials()
        self.get_best_parameters()
        self.store_parameters()
Exemplo n.º 3
0
# #### Run the optimization loop
#
# We're ready to run the Bayesian Optimization loop.

for i in range(5):
    print(f"Running optimization batch {i+1}/5...")

    # user added:
    # get_botorch is a self-contained macro-framework that does everything for you:
    # 1) It fits the GP model to the new data
    # 2) If optimizes the acquisition function and provides the next candidate
    # 3) It evaluates such candidate (next point)
    # 4) It returns the best suggestion (best guess)
    model = get_botorch(
        experiment=exp,
        data=exp.eval(),
        search_space=exp.search_space,
        model_constructor=_get_and_fit_simple_custom_gp,
    )
    batch = exp.new_trial(generator_run=model.gen(1))

    # user TODO: See https://ax.dev/api/_modules/ax/modelbridge/factory.html#get_botorch
    # 1) Pass a custom acquisition function constructor
    # 2) Maybe change the optimizer
    # 3)

    print(batch)

print("Done!")
Exemplo n.º 4
0
def mems_exp(cfg):
    log.info("============= Configuration =============")
    log.info(f"Config:\n{cfg.pretty()}")
    log.info("=========================================")

    raise NotImplementedError("TODO load experimental data and verify likelihood of differnet points")
    search_space = gen_search_space(cfg.problem)
    outcome_con = gen_outcome_constraints(cfg.problem)

    exp = SimpleExperiment(
        name=cfg.problem.name,
        search_space=SearchSpace(search_space),
        evaluation_function=jumper,
        objective_name="Energy_(uJ)",
        minimize=False,
        outcome_constraints=outcome_con,
    )

    optimization_config = OptimizationConfig(
        objective=Objective(
            metric=MEMsMetric(name="Energy_(uJ)"),
            minimize=False,
        ),
    )

    class MyRunner(Runner):
        def run(self, trial):
            return {"name": str(trial.index)}

    exp.runner = MyRunner()
    exp.optimization_config = optimization_config
    from ax.utils.notebook.plotting import render, init_notebook_plotting
    from ax.plot.contour import plot_contour

    print(f"Running {cfg.bo.random} Sobol initialization trials...")
    sobol = Models.SOBOL(exp.search_space)
    num_search = cfg.bo.random
    for i in range(num_search):
        exp.new_trial(generator_run=sobol.gen(1))
        exp.trials[len(exp.trials) - 1].run()

    # data = exp.fetch_data()

    num_opt = cfg.bo.optimized
    for i in range(num_opt):
        if (i % 5) == 0 and cfg.plot_during:
            plot = plot_contour(model=gpei,
                                param_x="N",
                                param_y="L",
                                metric_name="Energy_(uJ)", )
            data = plot[0]['data']
            lay = plot[0]['layout']

            render(plot)

        print(f"Running GP+EI optimization trial {i + 1}/{num_opt}...")
        # Reinitialize GP+EI model at each step with updated data.
        batch = exp.new_trial(generator_run=gpei.gen(1))
        gpei = Models.BOTORCH(experiment=exp, data=exp.eval())

    gpei = Models.BOTORCH(experiment=exp, data=exp.eval())

    from ax.models.torch.botorch_defaults import predict_from_model
    import torch
    X = torch.Tensor([[2, 7e-4, 1e-4], [1, 5e-4, 1e-4]]).double()
    mean, cov = predict_from_model(gpei.model.model, X)
    # X(Tensor) – n x d parameters

    ll = log_likelihood(X, mean, cov)
    plot_ll(ll)
Exemplo n.º 5
0
class optimization():

    def __init__(self):
        self.max_worker = multiprocessing.cpu_count()
        if self.max_worker > 1:
            self.max_worker -= 5
        #self.max_worker = 1
        
        self.best_obj_so_far = float('-inf')
        self.exp = None #define an experiment for ax
        self.best_parameters_from_experiment = None
        self.global_iteration_count = 0

    
    def evaluate_parameter(self,parameter, weight=None):
        total_returns = []
        
        q = multiprocessing.Queue(maxsize = self.max_worker)

        for iteration_index in range(0,C.ROUNDS_OF_WORKER):
            p_list = []
            for worker in range(0,self.max_worker):
                try:
                    p = multiprocessing.Process(target = self.get_one_sample_score,\
                                                args = (q,parameter))
                    p.start()
                    p_list.append(p)
                except:
                    pass

            for j in range(len(p_list)):
                res = q.get()
                total_returns.append(res[0])
                
        self.global_iteration_count += 1

        if np.mean(total_returns)>self.best_obj_so_far:
            self.best_obj_so_far = np.mean(total_returns)
            self.best_parameters_from_experiment = parameter
            print('the best objective so far is',self.best_obj_so_far)
            print('the associated best parameters are',parameter)
            print('the current time is',datetime.datetime.now())
            cwd = os.getcwd()
            parameter_file = 'best_parameter_from_direct_experiment.json'
            cwd = os.path.join(cwd,parameter_file)
            with open(cwd, 'w') as statusFile:
                statusFile.write(jsonpickle.encode(self.best_parameters_from_experiment))

        print('this is global iteration',self.global_iteration_count)
        print('the objective for ths iteration is',np.mean(total_returns))
        print('the current time is',datetime.datetime.now())
        print(' ')

        optimization_objective = (np.mean(total_returns) - np.std(total_returns) * 0.5, np.std(total_returns))
        

        return {'adj_return': optimization_objective}


    def get_one_sample_score(self,q,free_parameters):

        #the size of each gaussian copula cannot be too large
        #otherwise, the CDF will almost always be 0. 
        #the max dimension of the copula is 3
        #so, we will use a hierarchical structure of gaussian copulas
        #with each of having dimension of less than 3. 

        cov_input = [free_parameters['cov_para_1'],free_parameters['cov_para_2'],free_parameters['cov_para_3']]
        marginal_input = [free_parameters['beta_1a'],free_parameters['beta_1b'],
                 free_parameters['beta_2a'],free_parameters['beta_2b'],
                 free_parameters['beta_3a'],free_parameters['beta_3b']]
        dist_1 = utils.construct_a_copula(cov_input,marginal_input)

        cov_input = [free_parameters['cov_para_4']]
        marginal_input = [free_parameters['beta_4a'],free_parameters['beta_4b'],
                 free_parameters['beta_5a'],free_parameters['beta_5b']]
        dist_2 = utils.construct_a_copula(cov_input,marginal_input)
        


        #other parameters needed for transforming the features
        lambda_expon_1 = free_parameters['lambda_expon_1']
        lambda_expon_2 = free_parameters['lambda_expon_2']
        lambda_expon_3 = free_parameters['lambda_expon_3']
        lambda_expons = [lambda_expon_1,lambda_expon_2,lambda_expon_3]


        #now, we begin to simulate trading
        #first, initialize the observation
        locol_env = trading_vix_objective_2.trading_vix()
        this_trajectory_reward = []
        current_feature = locol_env.reset()

        for time_index in range(0,200):
        
            #compute an action given current observation
            transformed_features = []
            for feature_index in range(len(lambda_expons)):
                transformation = expon.cdf(current_feature[feature_index,0],scale = 1.0/lambda_expons[feature_index])
                transformed_features.append(transformation)
            transformed_features = np.asarray(transformed_features)
            transformed_features = np.reshape(transformed_features,(1,-1))
            data_point_for_copula_1 = pd.DataFrame(transformed_features)
            copula_1_output = dist_1.cdf(data_point_for_copula_1)

            data_point_for_copula_2 = np.asarray([copula_1_output,current_feature[-1,:][0]])
            data_point_for_copula_2 = np.reshape(data_point_for_copula_2,(1,-1))
            data_point_for_copula_2 = pd.DataFrame(data_point_for_copula_2)
            copula_2_output = dist_2.cdf(data_point_for_copula_2)

            #print('action is',copula_1_output)

            #apply the action to the environment
            current_feature, reward = locol_env.step(copula_1_output)

            #record reward
            this_trajectory_reward.append(reward)

        #final time step,get the long term reward
        reward = locol_env.final()
        this_trajectory_reward.append(reward)

        #print('the sum of the reward is',np.sum(this_trajectory_reward))
        objective = np.sum(this_trajectory_reward)
        if objective == 0:
            objective = -1e9

        q.put([objective])


    def init_search_space(self):
        search_space = SearchSpace(
        parameters=[
            RangeParameter(name="cov_para_1", parameter_type=ParameterType.FLOAT, lower=-0.9, upper=0.9),
            RangeParameter(name="cov_para_2", parameter_type=ParameterType.FLOAT, lower=-0.9, upper=0.9),
            RangeParameter(name="cov_para_3", parameter_type=ParameterType.FLOAT, lower=-0.9, upper=0.9),
            RangeParameter(name="cov_para_4", parameter_type=ParameterType.FLOAT, lower=-0.9, upper=0.9),
            # RangeParameter(name="cov_para_5", parameter_type=ParameterType.FLOAT, lower=-0.9, upper=0.9),
            # RangeParameter(name="cov_para_6", parameter_type=ParameterType.FLOAT, lower=-0.9, upper=0.9),

            RangeParameter(name="beta_1a", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_1b", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_2a", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_2b", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_3a", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_3b", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_4a", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_4b", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_5a", parameter_type=ParameterType.FLOAT, lower=0, upper=20),
            RangeParameter(name="beta_5b", parameter_type=ParameterType.FLOAT, lower=0, upper=20),

            RangeParameter(name="lambda_expon_1", parameter_type=ParameterType.FLOAT, lower=0.001, upper=0.1),
            RangeParameter(name="lambda_expon_2", parameter_type=ParameterType.FLOAT, lower=0.001, upper=0.1),
            RangeParameter(name="lambda_expon_3", parameter_type=ParameterType.FLOAT, lower=0.001, upper=0.1),
            ]
        )

        self.exp = SimpleExperiment(
        name="0",
        search_space=search_space,
        evaluation_function=self.evaluate_parameter,
        objective_name="adj_return"
        )


    def initialization_trials(self):
        sobol = Models.SOBOL(self.exp.search_space)
        for i in range(C.INITIALIZATION_TRIALS):
            self.exp.new_trial(generator_run=sobol.gen(1))


    def optimization_trials(self):
        device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
        device = torch.device("cpu")
        print(device)
        for i in range(C.OPTIMIZATION_TRIALS):
            print('Running GP+EI optimization trial', i+1)
            # Reinitialize GP+EI model at each step with updated data.
            #gpei = Models.GPEI(experiment=self.exp, data=self.exp.eval(), dtype=torch.float32, device=device)
            gpei = Models.GPEI(experiment=self.exp, data=self.exp.eval())
            batch = self.exp.new_trial(generator_run=gpei.gen(1))

    
    def get_best_parameters(self):
        _, trial = list(self.exp.trials.items())[-1]
        print(trial)
        trial.generator_run
        gr = trial.generator_run
        best_arm, best_arm_predictions = gr.best_arm_predictions
        best_parameters = best_arm.parameters
        self.best_parameters = best_parameters
        print('the best parameters are',best_parameters)


    def store_parameters(self):
        cwd = os.getcwd()
        #cwd = os.path.join(cwd, 'data_folder')
        parameter_file = 'index_copula_parameter.json'
        cwd = os.path.join(cwd,parameter_file)
        with open(cwd, 'w') as statusFile:
            statusFile.write(jsonpickle.encode(self.best_parameters))

        cwd = os.getcwd()
        parameter_file = 'best_parameter_from_direct_experiment.json'
        cwd = os.path.join(cwd,parameter_file)
        with open(cwd, 'w') as statusFile:
            statusFile.write(jsonpickle.encode(self.best_parameters_from_experiment))


    
    def run_optimization(self):


        self.init_search_space()

        print('Begin initialization trials')

        self.initialization_trials()

        self.optimization_trials()
        self.get_best_parameters()
        self.store_parameters()
Exemplo n.º 6
0
                               parameter_type=ParameterType.FLOAT),    
        RangeParameter(name="leafes", lower=2, upper=1000,    
                               parameter_type=ParameterType.INT)]
    )


experiment = SimpleExperiment(
    name = f"weather_lbgm_{dt.datetime.today().strftime('%d-%m-%Y')}",
    search_space = search_space,
    evaluation_function = mdl.obj_fun,
)

sobol = Models.SOBOL(experiment.search_space)
for i in range(n_random_trials):
    experiment.new_trial(generator_run=sobol.gen(1))

best_arm = None
for i in range(n_searches):
    gpei = Models.GPEI(experiment=experiment, data=experiment.eval())
    generator_run = gpei.gen(1)
    best_arm, _ = generator_run.best_arm_predictions
    experiment.new_trial(generator_run=generator_run)

best_para_ax = best_arm.parameters


n_oos = 0
params['num_boost_round'] = 200
mdl = Model(data_mat, lags, n_oos, n_val, prediction_range, target_vars_inds, params)
mdl.fit(best_para_ax)
X_pred = mdl.standing_forecast()
Exemplo n.º 7
0
def pid(cfg):
    env_name = cfg.env.params.name
    env = gym.make(env_name)
    env.reset()
    full_rewards = []
    exp_cfg = cfg.experiment

    from learn.utils.plotly import hv_characterization
    hv_characterization()

    def compare_control(env, cfg, save=True):
        import torch
        from learn.control.pid import PidPolicy

        controllers = []
        labels = []
        metrics = []

        # PID  baselines
        # /Users/nato/Documents/Berkeley/Research/Codebases/dynamics-learn/sweeps/2020-04-14/11-12-02

        # from learn.simulate_sac import *
        # Rotation policy
        sac_policy1 = torch.load(
            '/Users/nato/Documents/Berkeley/Research/Codebases/dynamics-learn/outputs/2020-03-24/18-32-26/trial_70000.dat'
        )
        controllers.append(sac_policy1['policy'])
        labels.append("SAC - Rotation")
        metrics.append(0)

        # Living reward policy
        sac_policy2 = torch.load(
            '/Users/nato/Documents/Berkeley/Research/Codebases/dynamics-learn/outputs/2020-03-24/18-31-45/trial_35000.dat'
        )
        controllers.append(sac_policy2['policy'])
        labels.append("SAC - Living")
        metrics.append(1)

        # Square cost policy
        # sac_policy2 = torch.load(
        #     '/Users/nato/Documents/Berkeley/Research/Codebases/dynamics-learn/sweeps/2020-03-25/20-30-47/metric.name=Square,robot=iono_sim/26/trial_40000.dat')
        controllers.append(sac_policy2['policy'])
        labels.append("SAC - Square")
        metrics.append(2)

        # un-Optimized PID parameters
        pid_params = [[2531.917, 61.358, 33.762], [2531.917, 61.358, 33.762]]
        pid = PidPolicy(cfg)
        pid.set_params(pid_params)
        controllers.append(pid)
        labels.append("PID - temp")
        metrics.append(0)

        controllers.append(pid)
        labels.append("PID - temp")
        metrics.append(1)

        # Optimized PID parameters
        pid_params = [[2531.917, 61.358, 3333.762],
                      [2531.917, 61.358, 3333.762]]
        pid = PidPolicy(cfg)
        pid.set_params(pid_params)
        controllers.append(pid)
        labels.append("PID - improved")
        metrics.append(2)

        from learn.control.mpc import MPController
        cfg.policy.mode = 'mpc'
        # dynam_model = torch.load(
        #     '/Users/nato/Documents/Berkeley/Research/Codebases/dynamics-learn/outputs/2020-03-25/10-45-17/trial_1.dat')
        dynam_model = torch.load(
            '/Users/nato/Documents/Berkeley/Research/Codebases/dynamics-learn/sweeps/2020-03-25/20-30-57/metric.name=Rotation,robot=iono_sim/14/trial_9.dat'
        )
        mpc = MPController(env, dynam_model['model'], cfg)

        controllers.append(mpc)
        labels.append("MPC - 1")
        metrics.append(0)
        controllers.append(mpc)
        labels.append("MPC - 2")
        metrics.append(1)
        controllers.append(mpc)
        labels.append("MPC - 3")
        metrics.append(2)

        import plotly.graph_objects as go
        import plotly

        colors = [
            '#1f77b4',  # muted blue
            '#ff7f0e',  # safety orange
            '#2ca02c',  # cooked asparagus green
            '#d62728',  # brick red
            '#9467bd',  # muted purple
            '#8c564b',  # chestnut brown
            '#e377c2',  # raspberry yogurt pink
            '#7f7f7f',  # middle gray
            '#bcbd22',  # curry yellow-green
            '#17becf'  # blue-teal
        ]

        markers = [
            "cross",
            "circle-open-dot",
            "x-open-dot",
            "triangle-up-open-dot",
            "y-down-open",
            "diamond-open-dot",
            "hourglass",
            "hash",
            "star",
            "square",
        ]

        m1 = living_reward
        m2 = rotation_mat
        m3 = squ_cost
        eval_metrics = [m1, m2, m3]
        metric_names = ["Living", "Rotation", "Square"]

        fig = plotly.subplots.make_subplots(
            rows=3,
            cols=2,
            # subplot_titles=["Living", "Rotation", "Square"],
            subplot_titles=[
                "Pitch",
                "Roll",
                " ",
                " ",
                " ",
                " ",
            ],
            vertical_spacing=0.03,
            horizontal_spacing=0.03,
            shared_xaxes=True,
        )  # go.Figure()

        fig_mpc = go.Figure()
        fig_sac = go.Figure()

        pry = [1, 0, 2]
        # state0 = 2*env.reset()
        # state0 = env.reset()
        state0 = np.array([0, np.deg2rad(15), 0, 0, 0, 0])
        for i, (con, lab, m) in enumerate(zip(controllers, labels, metrics)):
            print(f"Evaluating controller type {lab}")
            _ = env.reset()
            env.set_state(np.concatenate((np.zeros(6), state0)))
            state = state0
            states = []
            actions = []
            rews = []
            done = False
            # for t in range(cfg.experiment.r_len + 1):
            for t in range(500):
                if done:
                    break
                if "SAC" in lab:
                    with torch.no_grad():
                        with eval_mode(con):
                            action = con.select_action(state)
                            if i < 2:
                                action = np.array([65535, 65535, 65535, 65535
                                                   ]) * (action + 1) / 2
                            else:
                                action = np.array([3000, 3000, 3000, 3000
                                                   ]) * (action + 1) / 2

                else:
                    action = con.get_action(state, metric=eval_metrics[m])
                states.append(state)
                actions.append(action)

                state, rew, done, _ = env.step(action)
                done = done

            states = np.stack(states)
            actions = np.stack(actions)

            pitch = np.degrees(states[:, pry[0]])
            roll = np.degrees(states[:, pry[1]])

            # deal with markers
            num_mark = np.zeros(len(pitch))
            mark_every = 50
            m_size = 32
            start = np.random.randint(0, int(len(pitch) / 10))
            num_mark[start::mark_every] = m_size
            if "SAC" in lab:
                fig_sac.add_trace(
                    go.Scatter(
                        y=pitch,
                        name=metric_names[m],  # legendgroup=lab[:3],
                        # showlegend=(True if (i % 3 == 0) else False),
                        line=dict(color=colors[m], width=4),
                        cliponaxis=False,
                        mode='lines+markers',
                        marker=dict(color=colors[m],
                                    symbol=markers[-m],
                                    size=num_mark.tolist())))

            elif "MPC" in lab:
                fig_mpc.add_trace(
                    go.Scatter(
                        y=pitch,
                        name=metric_names[m],  # legendgroup=lab[:3],
                        # showlegend=(True if (i % 3 == 0) else False),
                        line=dict(color=colors[m], width=4),
                        cliponaxis=False,
                        mode='lines+markers',
                        marker=dict(color=colors[m],
                                    symbol=markers[-m],
                                    size=num_mark.tolist())))

            fig.add_trace(
                go.Scatter(
                    y=pitch,
                    name=lab[:3] + str(m),
                    legendgroup=lab[:3],
                    showlegend=(True if (i % 3 == 0) else False),
                    line=dict(color=colors[int(i / 3)],
                              width=2),  # mode='lines+markers',
                    # marker=dict(color=colors[i], symbol=markers[i], size=16)
                ),
                row=m + 1,
                col=1)

            fig.add_trace(
                go.Scatter(
                    y=roll,
                    name=lab[:3] + str(m),
                    legendgroup=lab[:3],
                    showlegend=(False),
                    line=dict(color=colors[int(i / 3)],
                              width=2),  # mode='lines+markers',
                    # marker=dict(color=colors[i], symbol=markers[i], size=16)
                ),
                row=m + 1,
                col=2)

        fig.update_layout(
            title='Comparison of Controllers and Reward Functions',
            font=dict(family="Times New Roman, Times, serif",
                      size=24,
                      color="black"),
            legend_orientation="h",
            legend=dict(
                x=.6,
                y=0.07,
                bgcolor='rgba(205, 223, 212, .4)',
                bordercolor="Black",
            ),
            # xaxis_title='Timestep',
            # yaxis_title='Angle (Degrees)',
            plot_bgcolor='white',
            width=1600,
            height=1000,
            # xaxis=dict(
            #     showline=True,
            #     showgrid=False,
            #     showticklabels=True, ),
            # yaxis=dict(
            #     showline=True,
            #     showgrid=False,
            #     showticklabels=True, ),
        )

        fig_sac.update_layout(  # title='Comparison of SAC Policies',
            font=dict(family="Times New Roman, Times, serif",
                      size=32,
                      color="black"),
            legend_orientation="h",
            legend=dict(
                x=.35,
                y=0.1,
                bgcolor='rgba(205, 223, 212, .4)',
                bordercolor="Black",
            ),
            # xaxis_title='Timestep',
            # yaxis_title='Angle (Degrees)',
            showlegend=False,
            plot_bgcolor='white',
            width=1600,
            height=800,
            margin=dict(t=5, r=5),
        )

        fig_mpc.update_layout(  # title='Comparison of MPC Policies',
            font=dict(family="Times New Roman, Times, serif",
                      size=32,
                      color="black"),
            legend_orientation="h",
            showlegend=False,
            legend=dict(
                x=.35,
                y=0.1,
                bgcolor='rgba(205, 223, 212, .4)',
                bordercolor="Black",
                # ncol= 2,
            ),
            # xaxis_title='Timestep',
            # yaxis_title='Angle (Degrees)',
            plot_bgcolor='white',
            width=1600,
            height=800,
            margin=dict(t=5, r=5),
        )

        reg_color = 'rgba(255,60,60,.15)'
        fig_sac.add_trace(
            go.Scatter(x=[0, 500],
                       y=[5, 5],
                       name='Living Region',
                       legendgroup='Living Region',
                       fill='tozeroy',
                       mode='lines',
                       fillcolor=reg_color,
                       line=dict(width=0.0,
                                 color=reg_color)))  # fill down to xaxis
        fig_sac.add_trace(
            go.Scatter(x=[0, 500],
                       y=[-5, -5],
                       showlegend=False,
                       legendgroup='Living Region',
                       fill='tozeroy',
                       mode='lines',
                       fillcolor=reg_color,
                       line=dict(width=0.0,
                                 color=reg_color)))  # fill down to xaxis

        fig_mpc.add_trace(
            go.Scatter(x=[0, 500],
                       y=[5, 5],
                       name='Living Region',
                       legendgroup='Living Region',
                       fill='tozeroy',
                       mode='lines',
                       fillcolor=reg_color,
                       line=dict(width=0.0,
                                 color=reg_color)))  # fill down to xaxis
        fig_mpc.add_trace(
            go.Scatter(x=[0, 500],
                       y=[-5, -5],
                       showlegend=False,
                       legendgroup='Living Region',
                       fill='tozeroy',
                       mode='lines',
                       fillcolor=reg_color,
                       line=dict(width=0.0,
                                 color=reg_color)))  # fill down to xaxis

        # SOLO
        rang_ind = [-20, 20]
        fig_sac.update_xaxes(
            title_text="Timestep",
            range=[0, 500],
            ticks="inside",
            tickwidth=2,
            zeroline=True,
            zerolinecolor='rgba(0,0,0,.5)',
            zerolinewidth=1,
        )
        fig_sac.update_yaxes(
            title_text="Pitch (degrees)",
            range=rang_ind,
            ticks="inside",
            tickwidth=2,
            zeroline=True,
            zerolinecolor='rgba(0,0,0,.5)',
            zerolinewidth=1,
        )
        fig_sac.show()
        fig_sac.write_image(os.getcwd() + "/compare_sac.pdf")

        fig_mpc.update_xaxes(
            title_text="Timestep",
            range=[0, 500],
            ticks="inside",
            tickwidth=2,
            zeroline=True,
            zerolinecolor='rgba(0,0,0,.5)',
            zerolinewidth=1,
        )
        fig_mpc.update_yaxes(
            title_text="Pitch (degrees)",
            range=rang_ind,
            ticks="inside",
            tickwidth=2,
            zeroline=True,
            zerolinecolor='rgba(0,0,0,.5)',
            zerolinewidth=1,
        )
        fig_mpc.show()
        fig_mpc.write_image(os.getcwd() + "/compare_mpc.pdf")

        # COMPARISON

        fig.update_xaxes(
            title_text="Timestep",
            row=3,
            col=1,
            ticks="inside",
            tickwidth=2,
            zeroline=True,
            zerolinecolor='rgba(0,0,0,.5)',
            zerolinewidth=1,
        )
        fig.update_xaxes(
            row=2,
            col=1,
            zeroline=True,
            zerolinecolor='rgba(0,0,0,.5)',
            zerolinewidth=1,
        )
        fig.update_xaxes(
            row=1,
            col=1,
            zeroline=True,
            zerolinecolor='rgba(0,0,0,.5)',
            zerolinewidth=1,
        )
        fig.update_xaxes(
            title_text="Timestep",
            row=3,
            col=2,
            ticks="inside",
            tickwidth=2,
            zeroline=True,
            zerolinecolor='rgba(0,0,0,.5)',
            zerolinewidth=1,
        )
        fig.update_xaxes(
            row=2,
            col=2,
            zeroline=True,
            zerolinecolor='rgba(0,0,0,.5)',
            zerolinewidth=1,
        )
        fig.update_xaxes(
            row=1,
            col=2,
            zeroline=True,
            zerolinecolor='rgba(0,0,0,.5)',
            zerolinewidth=1,
        )
        # fig.update_xaxes(title_text="xaxis 1 title", row=1, col=1)
        # fig.update_yaxes(title_text="Roll (Degrees)", row=1, col=1)

        rang = [-30, 30]
        nticks = 6
        fig.update_yaxes(
            title_text="Living Rew.",
            range=rang,
            row=1,
            col=1,
            nticks=nticks,
            ticks="inside",
            tickwidth=2,
            zeroline=True,
            zerolinecolor='rgba(0,0,0,.5)',
            zerolinewidth=1,
        )
        fig.update_yaxes(
            title_text="Rotation Rew.",
            range=rang,
            row=2,
            col=1,
            nticks=nticks,
            ticks="inside",
            tickwidth=2,
            zeroline=True,
            zerolinecolor='rgba(0,0,0,.5)',
            zerolinewidth=1,
        )
        fig.update_yaxes(
            title_text="Square Cost",
            range=rang,
            row=3,
            col=1,
            nticks=nticks,
            ticks="inside",
            tickwidth=2,
            zeroline=True,
            zerolinecolor='rgba(0,0,0,.5)',
            zerolinewidth=1,
        )
        fig.update_yaxes(
            range=rang,
            row=1,
            col=2,
            nticks=nticks,
            showticklabels=False,
            ticks="inside",
            tickwidth=2,
            zeroline=True,
            zerolinecolor='rgba(0,0,0,.5)',
            zerolinewidth=1,
        )
        fig.update_yaxes(
            range=rang,
            row=2,
            col=2,
            nticks=nticks,
            showticklabels=False,
            ticks="inside",
            tickwidth=2,
            zeroline=True,
            zerolinecolor='rgba(0,0,0,.5)',
            zerolinewidth=1,
        )
        fig.update_yaxes(
            range=rang,
            row=3,
            col=2,
            nticks=nticks,
            showticklabels=False,
            ticks="inside",
            tickwidth=2,
            zeroline=True,
            zerolinecolor='rgba(0,0,0,.5)',
            zerolinewidth=1,
        )

        print(f"Plotting {len(labels)} control responses")
        # save = False
        # if save:
        #     fig.write_image(os.getcwd() + "compare.png")
        # else:
        #     fig.show()
        #
        # return fig

    # compare_control(env, cfg, save=True)
    # quit()
    plot_results(logx=False, save=True, mpc=False)
    quit()

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # # # # # # # # # # # Evalutation Function  # # # # # # # # # # # # # # # # # # # #
    def bo_rollout_wrapper(params, weights=None):  # env, controller, exp_cfg):
        pid_1 = [params["pitch-p"], params["pitch-i"], params["pitch-d"]]
        # pid_1 = [params["roll-p"], params["roll-i"],
        #          params["roll-d"]]  # [params["pitch-p"], params["pitch-i"], params["pitch-d"]]
        pid_2 = [params["roll-p"], params["roll-i"], params["roll-d"]]
        print(
            f"Optimizing Parameters {np.round(pid_1, 3)},{np.round(pid_2, 3)}")
        pid_params = [[pid_1[0], pid_1[1], pid_1[2]],
                      [pid_2[0], pid_2[1], pid_2[2]]]
        # pid_params = [[1000, 0, 0], [1000, 0, 0]]
        pid = PidPolicy(cfg)

        pid.set_params(pid_params)

        cum_cost = []
        r = 0
        fncs = [squ_cost, living_reward, rotation_mat]
        mult_rewards = [[] for _ in range(len(fncs))]
        while r < cfg.experiment.repeat:
            pid.reset()
            states, actions, rews, sim_error = rollout(env, pid, exp_cfg)
            # plot_rollout(states, actions, pry=[1, 0, 2])
            rewards_full = get_rewards(states, actions, fncs=fncs)
            for i, vec in enumerate(rewards_full):
                mult_rewards[i].append(vec)

            # if sim_error:
            #     print("Repeating strange simulation")
            #     continue
            # if len(rews) < 400:
            #     cum_cost.append(-(cfg.experiment.r_len - len(rews)) / cfg.experiment.r_len)
            # else:
            rollout_cost = np.sum(rews) / cfg.experiment.r_len  # / len(rews)
            # if rollout_cost > max_cost:
            #      max_cost = rollout_cost
            # rollout_cost += get_reward_euler(states[-1], actions[-1])
            cum_cost.append(rollout_cost)
            r += 1

        std = np.std(cum_cost)
        cum_cost = np.mean(cum_cost)
        # print(f"Cum. Cost {cum_cost / max_cost}")
        # print(f"- Mean Cum. Cost / Rew: {cum_cost}, std dev: {std}")
        eval = {
            "Square": (np.mean(rewards_full[0]), np.std(rewards_full[0])),
            "Living": (np.mean(rewards_full[1]), np.std(rewards_full[1])),
            "Rotation": (np.mean(rewards_full[2]), np.std(rewards_full[2]))
        }

        for n, (key, value) in enumerate(eval.items()):
            if n == 0:
                print(f"- Square {np.round(value, 4)}")
            elif n == 1:
                print(f"- Living {np.round(value, 4)}")
            else:
                print(f"- Rotn {np.round(value, 4)}")
        return eval
        # return cum_cost.reshape(1, 1), std

    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    from ax import (
        ComparisonOp,
        ParameterType,
        RangeParameter,
        SearchSpace,
        SimpleExperiment,
        OutcomeConstraint,
    )

    exp = SimpleExperiment(
        name="PID Control Robot",
        search_space=SearchSpace([
            RangeParameter(
                name=f"roll-p",
                parameter_type=ParameterType.FLOAT,
                lower=1.0,
                upper=10000.0,
                log_scale=True,
            ),
            # FixedParameter(name="roll-i", value=0.0, parameter_type=ParameterType.FLOAT),
            RangeParameter(
                name=f"roll-i",
                parameter_type=ParameterType.FLOAT,
                lower=0,
                upper=1000.0,
                log_scale=False,
            ),
            RangeParameter(
                name=f"roll-d",
                parameter_type=ParameterType.FLOAT,
                lower=.1,
                upper=5000.0,
                log_scale=True,
            ),
            RangeParameter(
                name=f"pitch-p",
                parameter_type=ParameterType.FLOAT,
                lower=1.0,
                upper=10000.0,
                log_scale=True,
            ),
            RangeParameter(
                name=f"pitch-d",
                parameter_type=ParameterType.FLOAT,
                lower=0,
                upper=1000.0,
                log_scale=False,
            ),
            RangeParameter(
                name=f"pitch-i",
                parameter_type=ParameterType.FLOAT,
                lower=.1,
                upper=5000.0,
                log_scale=True,
            ),
            # FixedParameter(name="pitch-i", value=0.0, parameter_type=ParameterType.FLOAT),
        ]),
        evaluation_function=bo_rollout_wrapper,
        objective_name=cfg.metric.name,
        minimize=cfg.metric.minimize,
        outcome_constraints=[],
    )

    from ax.storage.metric_registry import register_metric
    from ax.storage.runner_registry import register_runner

    class GenericMetric(Metric):
        def fetch_trial_data(self, trial):
            records = []
            for arm_name, arm in trial.arms_by_name.items():
                params = arm.parameters
                mean, sem = bo_rollout_wrapper(params)
                records.append({
                    "arm_name": arm_name,
                    "metric_name": self.name,
                    "mean": mean,
                    "sem": sem,
                    "trial_index": trial.index,
                })
            return Data(df=pd.DataFrame.from_records(records))

    class MyRunner(Runner):
        def run(self, trial):
            return {"name": str(trial.index)}

    optimization_config = OptimizationConfig(objective=Objective(
        metric=GenericMetric(name=cfg.metric.name),
        minimize=cfg.metric.minimize,
    ), )
    register_metric(GenericMetric)
    register_runner(MyRunner)

    exp.runner = MyRunner()
    exp.optimization_config = optimization_config

    log.info(f"Running experiment, metric name {cfg.metric.name}")
    log.info(f"Running Sobol initialization trials...")
    sobol = Models.SOBOL(exp.search_space)
    num_search = cfg.bo.random
    for i in range(num_search):
        exp.new_trial(generator_run=sobol.gen(1))
        exp.trials[len(exp.trials) - 1].run()

    import plotly.graph_objects as go

    gpei = Models.BOTORCH(experiment=exp, data=exp.eval())

    objectives = ["Living", "Square", "Rotation"]

    def plot_all(model, objectives, name="", rend=False):
        for o in objectives:
            plot = plot_contour(
                model=model,
                param_x="roll-p",
                param_y="roll-d",
                metric_name=o,
            )
            plot[0]['layout']['title'] = o
            data = plot[0]['data']
            lay = plot[0]['layout']

            for i, d in enumerate(data):
                if i > 1:
                    d['cliponaxis'] = False

            fig = {
                "data": data,
                "layout": lay,
            }
            go.Figure(fig).write_image(name + o + ".png")
            if rend: render(plot)

    plot_all(gpei, objectives, name="Random fit-")

    num_opt = cfg.bo.optimized
    for i in range(num_opt):
        log.info(f"Running GP+EI optimization trial {i + 1}/{num_opt}...")
        # Reinitialize GP+EI model at each step with updated data.
        batch = exp.new_trial(generator_run=gpei.gen(1))
        gpei = Models.BOTORCH(experiment=exp, data=exp.eval())

        if ((i + 1) % 10) == 0:
            plot_all(gpei,
                     objectives,
                     name=f"optimizing {str(i + 1)}-",
                     rend=False)

    from ax.plot.exp_utils import exp_to_df

    best_arm, _ = gpei.gen(1).best_arm_predictions
    best_parameters = best_arm.parameters
    log.info(f"Best parameters {best_parameters}")

    experiment_log = {
        "Exp": exp_to_df(exp=exp),
        "Cfg": cfg,
        "Best_param": best_parameters,
    }

    log.info("Printing Parameters")
    log.info(exp_to_df(exp=exp))
    save_log(cfg, exp, experiment_log)

    fig_learn = plot_learning(exp, cfg)
    fig_learn.write_image("learning" + ".png")
    fig_learn.show()
    plot_all(gpei, objectives, name=f"FINAL -", rend=True)
Exemplo n.º 8
0
    def optimize(self):
        SOBOL_TRIALS = 75
        gpei_list = [50, 30, 10, 0]
        parameters = None

        for gpei_trials in gpei_list:
            try:
                search_space = SearchSpace(parameters=[
                    ChoiceParameter(name='risk_function',
                                    values=['polynomial', 'exponential'],
                                    parameter_type=ParameterType.STRING),
                    RangeParameter(name='alpha_poly',
                                   lower=1.0,
                                   upper=5.0,
                                   parameter_type=ParameterType.FLOAT),
                    RangeParameter(name='alpha_exp',
                                   lower=0.0,
                                   upper=1.0,
                                   parameter_type=ParameterType.FLOAT),
                    RangeParameter(name='exp_threshold',
                                   lower=1.0,
                                   upper=10.0,
                                   parameter_type=ParameterType.FLOAT)
                ])

                experiment = SimpleExperiment(
                    name='risk_function_parametrisation',
                    search_space=search_space,
                    evaluation_function=self.evaluate_parameterization,
                    objective_name='par10',
                    minimize=True)

                sobol = Models.SOBOL(experiment.search_space)
                for _ in range(SOBOL_TRIALS):
                    experiment.new_trial(generator_run=sobol.gen(1))

                best_arm = None
                for _ in range(gpei_trials):
                    gpei = Models.GPEI(experiment=experiment,
                                       data=experiment.eval())
                    generator_run = gpei.gen(1)
                    best_arm, _ = generator_run.best_arm_predictions
                    experiment.new_trial(generator_run=generator_run)

                parameters = best_arm.parameters
                break

            except:
                print('GPEI Optimization failed')
                if gpei_trials == 0:
                    # choose expectation if optimization failed for all gpei_trial values
                    # exp thresholds are dummy variables
                    parameters = {
                        'risk_function': 'polynomial',
                        'alpha_poly': 1.0,
                        'alpha_exp': 1.0,
                        'exp_threshold': 1.0
                    }

                else:
                    continue

        return self.resolve_risk_function(parameters['risk_function'],
                                          parameters['alpha_poly'],
                                          parameters['alpha_exp'],
                                          parameters['exp_threshold'])
    search_space=transformer_search_space,
    evaluation_function=transformer.trainer,
    objective_name='f1',
)

# Run the optimization and fit a GP on all data
sobol = modelbridge.get_sobol(search_space=exp.search_space)
print(f"\nRunning Sobol initialization trials...\n{'='*40}\n")
for _ in range(init_trials):
    exp.new_trial(generator_run=sobol.gen(1))

for i in range(opt_trials):
    print(
        f"\nRunning GP+EI optimization trial {i+1}/{opt_trials}...\n{'='*40}\n"
    )
    gpei = modelbridge.get_GPEI(experiment=exp, data=exp.eval())
    exp.new_trial(generator_run=gpei.gen(1))

    # save every 5 trials
    if (i + 1) % 5 == 0:
        output_dir = os.path.join(
            'Ax_output', dset,
            datetime.datetime.now().strftime('%m%d-%H%M%S'))
        os.makedirs(output_dir)

        # Save all experiment parameters
        df = exp.eval().df
        df.to_csv(os.path.join(output_dir, 'exp_eval.csv'), index=False)

        # Save best parameter
        best_arm_name = df.arm_name[df['mean'] == df['mean'].max()].values[0]