Exemplo n.º 1
0
    def maximise_acquisition(self, acq_fn, anc_data, *args, **kwargs):
        # Merged from multiple places in Dragonfly's code to select the right optimiser
        # Avoids patching "cp_ga_optimiser_from_proc_args" globally
        domain, max_evals = anc_data.domain, anc_data.max_evals
        obj_in_func_caller = CPFunctionCaller(lambda x: acq_fn([x]),
                                              domain,
                                              domain_orderings=None)
        worker_manager = SyntheticWorkerManager(1, time_distro='const')
        if "prev_evaluations" in kwargs:
            options = {
                "prev_evaluations":
                Namespace(qinfos=kwargs["prev_evaluations"])
            }
        else:
            options = {}

        if self.acq_opt_method == "aging":
            _, ga_max_pt, _ = \
                build_aging_cp_ga_optimiser(obj_in_func_caller, domain, worker_manager, max_evals,
                                            mode='asy', options=None)
        else:
            assert self.acq_opt_method == "local"
            _, ga_max_pt, _ = \
                build_local_cp_ga_optimiser(obj_in_func_caller, domain, self.mutate_all,
                                            worker_manager, max_evals, mode='asy', options=options)
        return ga_max_pt
Exemplo n.º 2
0
def build_local_cp_ga_optimiser(func_caller,
                                cp_domain,
                                nn_mutate_op,
                                worker_manager,
                                max_capital,
                                mode='asy',
                                orderings=None,
                                options=None,
                                reporter="silent"):
    """ A GA optimiser on Cartesian product space from the function caller. """

    log = logging.getLogger("LocalGA Optimiser")

    if not isinstance(func_caller, ExperimentCaller):
        func_caller = CPFunctionCaller(func_caller,
                                       cp_domain,
                                       domain_orderings=orderings)
    options = load_options(blackbox_opt_args, partial_options=options)
    options.mode = mode
    options.capital_type = 'return_value'

    start_time = timer()
    log.info(
        f"Starting GA optimisation with capital {max_capital} ({options.capital_type})."
    )
    result = LocalCPGAOptimiser(func_caller,
                                nn_mutate_op,
                                worker_manager,
                                options=options,
                                reporter=reporter).optimise(max_capital)
    end_time = timer()
    log.info(f"GA optimisation finished, took {(end_time - start_time):.2f}s.")
    return result
Exemplo n.º 3
0
def build_aging_cp_ga_optimiser(func_caller,
                                cp_domain,
                                worker_manager,
                                max_capital,
                                mode='asy',
                                orderings=None,
                                single_mutation_ops=None,
                                single_crossover_ops=None,
                                options=None,
                                reporter="silent"):
    """ A GA optimiser on Cartesian product space from the function caller. """

    log = logging.getLogger("AgingGA Optimiser")

    if not isinstance(func_caller, ExperimentCaller):
        func_caller = CPFunctionCaller(func_caller,
                                       cp_domain,
                                       domain_orderings=orderings)
    options = load_options(ga_opt_args, partial_options=options)
    options.mode = mode
    options.capital_type = 'return_value'
    options.population_size = 100
    options.sample_size = 25

    start_time = timer()
    log.info(
        f"Starting GA optimisation with capital {max_capital} ({options.capital_type})."
    )
    result = CPGAOptimiser(func_caller,
                           worker_manager,
                           single_mutation_ops=single_mutation_ops,
                           single_crossover_ops=single_crossover_ops,
                           options=options,
                           reporter=reporter).optimise(max_capital)
    end_time = timer()
    log.info(f"GA optimisation finished, took {(end_time - start_time):.2f}s.")
    return result
Exemplo n.º 4
0
        accuracy = 100 * correct / total
        return accuracy

def parallel_exec(draw):
    train_instance = Trainable_cifar10()
    train_instance.reset(*draw)
    return train_instance.train_and_eval()



if __name__ == "__main__":
    DEBUG = True
    config = load_config_file('cifar10-dom.json')
    domain, domain_orderings = config.domain, config.domain_orderings
    func_caller = CPFunctionCaller(None, domain, domain_orderings=domain_orderings)
    opt = gp_bandit.CPGPBandit(func_caller, ask_tell_mode=True)
    opt.initialise()

    parallel_jobs = 10
    train_instance = Trainable_cifar10()

    while True:
        results = {}
        if parallel_jobs > 0:
            draws = [opt.ask() for _ in range(parallel_jobs)]
            with Pool(parallel_jobs) as p:
                accuracies = p.map(parallel_exec, draws)
            # accuracies = [parallel_exec(d) for d in draws]
            [opt.tell([(d,a)]) for d,a in zip(draws, accuracies)]
            results.update({tuple(d):a for d,a in zip(draws, accuracies)})
Exemplo n.º 5
0
def maximise_function(func, domain, max_capital, config=None, options=None):
    """
    Maximises a function 'func' over the domain 'domain'.
    Inputs:
      func: The function to be maximised.
      domain: The domain over which the function should be maximised, should be an
              instance of the Domain class in exd/domains.py.
              If domain is a list of the form [[l1, u1], [l2, u2], ...] where li < ui,
              then we will create a Euclidean domain with lower bounds li and upper bounds
              ui along each dimension.
      max_capital: The maximum capital (budget) available for optimisation.
      config: Contains configuration parameters that are typically returned by
              exd.cp_domain_utils.load_config_file. config can be None only if domain
              is a EuclideanDomain object.
      options: Additional hyper-parameters for optimisation.
      * Alternatively, domain could be None if config is either a path_name to a
        configuration file or has configuration parameters.
    Returns:
      opt_val: The maximum value found during the optimisatio procdure.
      opt_pt: The corresponding optimum point.
      history: A record of the optimisation procedure which include the point evaluated
               and the values at each time step.
  """
    # Preprocess domain and config arguments
    raw_func = func
    domain, preproc_func_list, config, _ = _preprocess_arguments(
        domain, [func], config)
    func = preproc_func_list[0]
    # Load arguments depending on domain type
    if domain.get_type() == 'euclidean':
        func_caller = EuclideanFunctionCaller(func, domain, vectorised=False)
    else:
        func_caller = CPFunctionCaller(
            func,
            domain,
            raw_func=raw_func,
            domain_orderings=config.domain_orderings)
    # Create worker manager and function caller
    worker_manager = SyntheticWorkerManager(num_workers=1)
    # Optimise function here -----------------------------------------------------------
    opt_val, opt_pt, history = gpb_from_func_caller(func_caller,
                                                    worker_manager,
                                                    max_capital,
                                                    is_mf=False,
                                                    options=options)
    # Post processing
    if domain.get_type() == 'euclidean' and config is None:
        opt_pt = func_caller.get_raw_domain_coords(opt_pt)
        history.curr_opt_points = [
            func_caller.get_raw_domain_coords(pt)
            for pt in history.curr_opt_points
        ]
        history.query_points = [
            func_caller.get_raw_domain_coords(pt)
            for pt in history.query_points
        ]
    else:
        opt_pt = get_raw_from_processed_via_config(opt_pt, config)
        history.curr_opt_points_raw = [
            get_raw_from_processed_via_config(pt, config)
            for pt in history.curr_opt_points
        ]
        history.query_points_raw = [
            get_raw_from_processed_via_config(pt, config)
            for pt in history.query_points
        ]
    return opt_val, opt_pt, history
Exemplo n.º 6
0
def maximise_multifidelity_function(func,
                                    fidel_space,
                                    domain,
                                    fidel_to_opt,
                                    fidel_cost_func,
                                    max_capital,
                                    config=None,
                                    options=None):
    """
    Maximises a multi-fidelity function 'func' over the domain 'domain' and fidelity
    space 'fidel_space'.
    Inputs:
      func: The function to be maximised. Takes two arguments func(z, x) where z is a
            member of the fidelity space and x is a member of the domain.
      fidel_space: The fidelity space from which the approximations are obtained.
                   Should be an instance of the Domain class in exd/domains.py.
                   If of the form [[l1, u1], [l2, u2], ...] where li < ui, then we will
                   create a Euclidean domain with lower bounds li and upper bounds
                   ui along each dimension.
      domain: The domain over which the function should be maximised, should be an
              instance of the Domain class in exd/domains.py.
              If domain is a list of the form [[l1, u1], [l2, u2], ...] where li < ui,
              then we will create a Euclidean domain with lower bounds li and upper bounds
              ui along each dimension.
      fidel_to_opt: The point at the fidelity space at which we wish to maximise func.
      max_capital: The maximum capital (budget) available for optimisation.
      config: Contains configuration parameters that are typically returned by
              exd.cp_domain_utils.load_config_file. config can be None only if domain
              is a EuclideanDomain object.
      options: Additional hyper-parameters for optimisation.
      * Alternatively, domain and fidelity space could be None if config is either a
        path_name to a configuration file or has configuration parameters.
    Returns:
      opt_val: The maximum value found during the optimisation procdure.
      opt_pt: The corresponding optimum point.
      history: A record of the optimisation procedure which include the point evaluated
               and the values at each time step.
  """
    # Preprocess domain and config arguments
    raw_func = func
    fidel_space, domain, preproc_func_list, fidel_cost_func, fidel_to_opt, config, _ = \
      _preprocess_multifidelity_arguments(fidel_space, domain, [func], fidel_cost_func,
                                          fidel_to_opt, config)
    func = preproc_func_list[0]
    # Load arguments and function caller
    if fidel_space.get_type() == 'euclidean' and domain.get_type(
    ) == 'euclidean':
        func_caller = EuclideanFunctionCaller(func,
                                              domain,
                                              vectorised=False,
                                              raw_fidel_space=fidel_space,
                                              fidel_cost_func=fidel_cost_func,
                                              raw_fidel_to_opt=fidel_to_opt)
    else:
        func_caller = CPFunctionCaller(
            func,
            domain,
            '',
            raw_func=raw_func,
            domain_orderings=config.domain_orderings,
            fidel_space=fidel_space,
            fidel_cost_func=fidel_cost_func,
            fidel_to_opt=fidel_to_opt,
            fidel_space_orderings=config.fidel_space_orderings)

    # Create worker manager
    worker_manager = SyntheticWorkerManager(num_workers=1)
    # Optimise function here -----------------------------------------------------------
    opt_val, opt_pt, history = gpb_from_func_caller(func_caller,
                                                    worker_manager,
                                                    max_capital,
                                                    is_mf=True,
                                                    options=options)
    # Post processing
    if domain.get_type() == 'euclidean' and config is None:
        opt_pt = func_caller.get_raw_domain_coords(opt_pt)
        history.curr_opt_points = [
            func_caller.get_raw_domain_coords(pt)
            for pt in history.curr_opt_points
        ]
        history.query_points = [
            func_caller.get_raw_domain_coords(pt)
            for pt in history.query_points
        ]
    else:

        def _get_raw_from_processed_for_mf(fidel, pt):
            """ Returns raw point from processed point by accounting for the fact that a
          point could be None in the multi-fidelity setting. """
            if fidel is None or pt is None:
                return None, None
            else:
                return get_raw_from_processed_via_config((fidel, pt), config)

        # Now re-write curr_opt_points
        opt_pt = _get_raw_from_processed_for_mf(fidel_to_opt, opt_pt)[1]
        history.curr_opt_points_raw = [
            _get_raw_from_processed_for_mf(fidel_to_opt, pt)[1]
            for pt in history.curr_opt_points
        ]
        query_fidel_points_raw = [
            _get_raw_from_processed_for_mf(fidel, pt)
            for fidel, pt in zip(history.query_fidels, history.query_points)
        ]
        history.query_fidels = [zx[0] for zx in query_fidel_points_raw]
        history.query_points = [zx[1] for zx in query_fidel_points_raw]
    return opt_val, opt_pt, history
Exemplo n.º 7
0
def main():
    """ Main function. """
    # Load configuration file
    objective, config_file, mf_cost = _CHOOSER_DICT[PROBLEM]
    config = load_config_file(config_file)

    # Specify optimisation method -----------------------------------------------------
    opt_method = 'bo'
    # opt_method = 'ga'
    # opt_method = 'rand'

    # Optimise
    max_capital = 60
    domain, domain_orderings = config.domain, config.domain_orderings
    if PROBLEM in ['3d', '5d']:
        # Create function caller.
        # Note there is no function passed in to the Function Caller object.
        func_caller = CPFunctionCaller(None,
                                       domain,
                                       domain_orderings=domain_orderings)

        if opt_method == 'bo':
            opt = gp_bandit.CPGPBandit(func_caller, ask_tell_mode=True)
        elif opt_method == 'ga':
            opt = cp_ga_optimiser.CPGAOptimiser(func_caller,
                                                ask_tell_mode=True)
        elif opt_method == 'rand':
            opt = random_optimiser.CPRandomOptimiser(func_caller,
                                                     ask_tell_mode=True)
        opt.initialise()

        # Optimize using the ask-tell interface
        # User continually asks for the next point to evaluate, then tells the optimizer the
        # new result to perform Bayesian optimisation.
        best_x, best_y = None, float('-inf')
        for _ in range(max_capital):
            x = opt.ask()
            y = objective(x)
            opt.tell([(x, y)])
            print('x: %s, y: %s' % (x, y))
            if y > best_y:
                best_x, best_y = x, y
        print("Optimal Value: %s, Optimal Point: %s" % (best_y, best_x))

        # Compare results with the maximise_function API
        print("-------------")
        print("Compare with maximise_function API:")
        opt_val, opt_pt, history = maximise_function(objective,
                                                     config.domain,
                                                     max_capital,
                                                     opt_method=opt_method,
                                                     config=config)

    elif PROBLEM == '3d_euc':
        # Create function caller.
        # Note there is no function passed in to the Function Caller object.
        domain = domain.list_of_domains[0]
        func_caller = EuclideanFunctionCaller(None, domain)

        if opt_method == 'bo':
            opt = gp_bandit.EuclideanGPBandit(func_caller, ask_tell_mode=True)
        elif opt_method == 'ga':
            raise ValueError("Invalid opt_method %s" % (opt_method))
        opt.initialise()

        # Optimize using the ask-tell interface
        # User continually asks for the next point to evaluate, then tells the optimizer the
        # new result to perform Bayesian optimisation.
        best_x, best_y = None, float('-inf')
        for _ in range(max_capital):
            # Optionally, you can add an integer argument `n_points` to ask to have it return
            # `n_points` number of points. These points will be returned as a list.
            # No argument for `n_points` returns a single point from ask.
            x = opt.ask()
            y = objective(x)
            opt.tell([(x, y)])
            print('x: %s, y: %s' % (x, y))
            if y > best_y:
                best_x, best_y = x, y
        print("Optimal Value: %s, Optimal Point: %s" % (best_y, best_x))

        # Compare results with the maximise_function API
        print("-------------")
        print("Compare with maximise_function API:")
        opt_val, opt_pt, history = maximise_function(objective,
                                                     config.domain,
                                                     max_capital,
                                                     opt_method=opt_method,
                                                     config=config)

    else:
        # Create function caller.
        # Note there is no function passed in to the Function Caller object.
        (ask_tell_fidel_space, ask_tell_domain, _, ask_tell_mf_cost, ask_tell_fidel_to_opt, ask_tell_config, _) = \
          preprocess_multifidelity_arguments(config.fidel_space, domain, [objective],
                                             mf_cost, config.fidel_to_opt, config)
        func_caller = CPFunctionCaller(
            None,
            ask_tell_domain,
            domain_orderings=domain_orderings,
            fidel_space=ask_tell_fidel_space,
            fidel_cost_func=ask_tell_mf_cost,
            fidel_to_opt=ask_tell_fidel_to_opt,
            fidel_space_orderings=config.fidel_space_orderings,
            config=ask_tell_config)
        if opt_method == 'bo':
            opt = gp_bandit.CPGPBandit(func_caller,
                                       is_mf=True,
                                       ask_tell_mode=True)
        else:
            raise ValueError("Invalid opt_method %s" % (opt_method))
        opt.initialise()

        # Optimize using the ask-tell interface
        # User continually asks for the next point to evaluate, then tells the optimizer the
        # new result to perform Bayesian optimisation.
        best_z, best_x, best_y = None, None, float('-inf')
        for _ in range(max_capital):
            point = opt.ask()
            z, x = point[0], point[1]
            y = objective(z, x)
            opt.tell([(z, x, y)])
            print('z: %s, x: %s, y: %s' % (z, x, y))
            if y > best_y:
                best_z, best_x, best_y = z, x, y
        print("Optimal Value: %s, Optimal Point: %s" % (best_y, best_x))

        # Compare results with the maximise_multifidelity_function API
        print("-------------")
        print("Compare with maximise_multifidelity_function API:")
        opt_val, opt_pt, history = maximise_multifidelity_function(
            objective,
            config.fidel_space,
            config.domain,
            config.fidel_to_opt,
            mf_cost,
            max_capital,
            opt_method=opt_method,
            config=config)

    print('opt_pt: %s' % (str(opt_pt)))
    print('opt_val: %s' % (str(opt_val)))