Esempio n. 1
0
def optim_inits(x_opt, inference_samples, partition_samples, edge_mat_samples, n_vertices,
                acquisition_func=expected_improvement, reference=None):
    """
    :param x_opt: 1D Tensor
    :param inference_samples:
    :param partition_samples:
    :param edge_mat_samples:
    :param n_vertices:
    :param acquisition_func:
    :param reference:
    :return:
    """
    rnd_nbd = torch.cat(tuple([torch.randint(low=0, high=int(n_v), size=(N_RANDOM_VERTICES, 1)) for n_v in n_vertices]), dim=1).long()
    min_nbd = neighbors(x_opt, partition_samples, edge_mat_samples, n_vertices, uniquely=False)
    shuffled_ind = list(range(min_nbd.size(0)))
    np.random.shuffle(shuffled_ind)
    x_init_candidates = torch.cat(tuple([min_nbd[shuffled_ind[:N_SPRAY]], rnd_nbd]), dim=0)
    acquisition_values = acquisition_expectation(x_init_candidates, inference_samples, partition_samples, n_vertices,
                                                 acquisition_func, reference)

    nonnan_ind = ~torch.isnan(acquisition_values).squeeze(1)
    x_init_candidates = x_init_candidates[nonnan_ind]
    acquisition_values = acquisition_values[nonnan_ind]

    acquisition_sorted, acquisition_sort_ind = torch.sort(acquisition_values.squeeze(1), descending=True)
    x_init_candidates = x_init_candidates[acquisition_sort_ind]

    return x_init_candidates[:N_GREEDY_ASCENT_INIT], acquisition_sorted[:N_GREEDY_ASCENT_INIT]
Esempio n. 2
0
def greedy_ascent(x_init, inference_samples, partition_samples, edge_mat_samples, n_vertices,
                  acquisition_func=expected_improvement, max_n_ascent=float('inf'), reference=None):
    """
    In order to find local maximum of an acquisition function, at each vertex,
    it follows the most increasing edge starting from an initial point
    if MAX_ASCENT is infinity, this method tries to find local maximum, otherwise,
    it may stop at a noncritical vertex (this option is for a computational reason)
    :param x_init: 1d tensor
    :param inference_samples:
    :param edge_mat_samples:
    :param n_vertices: 1D np.array
    :param acquisition_func:
    :param max_n_ascent:
    :param reference:
    :return: 1D Tensor, numeric(float)
    """
    n_ascent = 0
    x = x_init
    max_acquisition = acquisition_expectation(x, inference_samples, partition_samples, n_vertices,
                                              acquisition_func, reference)
    while n_ascent < max_n_ascent:
        x_nbds = neighbors(x, partition_samples, edge_mat_samples, n_vertices, uniquely=True)
        nbds_acquisition = acquisition_expectation(x_nbds, inference_samples, partition_samples, n_vertices,
                                                   acquisition_func, reference)
        max_nbd_acquisition, max_nbd_ind = torch.max(nbds_acquisition, 0)
        if max_nbd_acquisition > max_acquisition:
            max_acquisition = max_nbd_acquisition
            x = x_nbds[max_nbd_ind.item()]
            n_ascent += 1
        else:
            break
    return x, max_acquisition.item()
Esempio n. 3
0
 def move(self):
     nbds = neighbors(self.state, self.partition_samples, self.edge_mat_samples, self.n_vertices, uniquely=False)
     self.state = nbds[np.random.randint(0, nbds.size(0))]
def next_evaluation(x_opt, input_data, inference_samples, partition_samples, edge_mat_samples, n_vertices,
                    acquisition_func, reference=None, parallel=None, problem=None, batch_size=1, exclude=[]):
    x_inits, acq_inits = optim_inits(x_opt, inference_samples, partition_samples, edge_mat_samples, n_vertices,
                                     acquisition_func, reference)
    n_inits = x_inits.size(0)
    assert n_inits % 2 == 0

    ga_args_list = [(x_inits[i], inference_samples, partition_samples, edge_mat_samples,
                     n_vertices, acquisition_func, MAX_N_ASCENT, reference) for i in range(n_inits)]

    ga_return_values = [greedy_ascent(*(ga_args_list[i])) for i in range(n_inits)]
    ga_opt_vrt, ga_opt_acq = zip(*ga_return_values)

    opt_vrt = list(ga_opt_vrt[:])
    opt_acq = list(ga_opt_acq[:])

    acq_sort_inds = np.argsort(-np.array(opt_acq))
    suggestion = None
    for i in range(len(opt_vrt)):
        ind = acq_sort_inds[i]
        if not torch.all(opt_vrt[ind] == input_data, dim=1).any():
            suggestion = opt_vrt[ind]
            break
    if suggestion is None or any((suggestion == x).all() for x in exclude):
        for i in range(len(opt_vrt)):
            ind = acq_sort_inds[i]
            nbds = neighbors(opt_vrt[ind], partition_samples, edge_mat_samples, n_vertices, uniquely=True)
            for j in range(nbds.size(0)):
                if not torch.all(nbds[j] == input_data, dim=1).any():
                    suggestion = nbds[j]
                    break
            if suggestion is not None:
                break
    while suggestion is None or any((suggestion == x).all() for x in exclude):
        suggestion = torch.cat(tuple([torch.randint(low=0, high=int(n_v), size=(1, 1)) for n_v in n_vertices]), dim=1).long()

    mean, std, var = prediction_statistic(suggestion, inference_samples, partition_samples, n_vertices)

    if problem is not None and batch_size > 1:
        problem.add_combo(suggestion)
        problem.update(inference_samples, partition_samples)
        algorithm = NSGAII(problem)
        algorithm.run(100)

        result = {}
        for x in algorithm.result:
            result[repr(x.variables)] = x
        result = list(result.values())

        if len(result) > batch_size-1:
            additional = np.random.choice(result, size=(batch_size-1), replace=False)
        else:
            additional = np.random.choice(result, size=(batch_size-1), replace=True)

        addl_means = [x.objectives[0] for x in additional]
        addl_stds = [x.objectives[1] for x in additional]
        additional = torch.tensor([x.variables for x in additional])
        additional = additional.view((batch_size-1), -1)
        for i in range(additional.size(0)):
            problem.add_combo(additional[i,:])

        return suggestion, mean, std, var, additional, addl_means, addl_stds

    else:
        return suggestion, mean, std, var, torch.zeros(0, len(n_vertices), dtype=torch.long), [], []
Esempio n. 5
0
def next_evaluation(x_opt,
                    input_data,
                    inference_samples,
                    partition_samples,
                    edge_mat_samples,
                    n_vertices,
                    acquisition_func=expected_improvement,
                    reference=None,
                    parallel=None):
    """
    In case of '[Errno 24] Too many open files', check 'nofile' limit by typing 'ulimit -n' in a terminal
    if it is too small then add lines to '/etc/security/limits.conf'
        *               soft    nofile          [Large Number e.g 65536]
        *               soft    nofile          [Large Number e.g 65536]
    Rebooting may be needed.
    :param x_opt: 1D Tensor
    :param input_data:
    :param inference_samples:
    :param partition_samples:
    :param edge_mat_samples:
    :param n_vertices: 1d np.array
    :param acquisition_func:
    :param reference: numeric(float)
    :param parallel:
    :return:
    """
    id_digit = np.ceil(np.log(np.prod(n_vertices)) / np.log(10))
    id_unit = torch.from_numpy(
        np.cumprod(np.concatenate([np.ones(1),
                                   n_vertices[:-1]])).astype(np.int))
    fmt_str = '\t %5.2f (id:%' + str(id_digit) + 'd) ==> %5.2f (id:%' + str(
        id_digit) + 'd)'

    start_time = time.time()
    print(
        '(%s) Acquisition function optimization initial points selection began'
        % (time.strftime('%H:%M:%S', time.gmtime(start_time))))

    x_inits, acq_inits = optim_inits(x_opt, inference_samples,
                                     partition_samples, edge_mat_samples,
                                     n_vertices, acquisition_func, reference)
    n_inits = x_inits.size(0)
    assert n_inits % 2 == 0

    end_time = time.time()
    elapsed_time = end_time - start_time
    print(
        '(%s) Acquisition function optimization initial points selection ended - %s'
        % (time.strftime('%H:%M:%S', time.gmtime(end_time)),
           time.strftime('%H:%M:%S', time.gmtime(elapsed_time))))

    start_time = time.time()
    print(
        '(%s) Acquisition function optimization with %2d inits' %
        (time.strftime('%H:%M:%S', time.gmtime(start_time)), x_inits.size(0)))

    ga_args_list = [
        (x_inits[i], inference_samples, partition_samples, edge_mat_samples,
         n_vertices, acquisition_func, MAX_N_ASCENT, reference)
        for i in range(n_inits)
    ]
    ga_start_time = time.time()
    sys.stdout.write('    Greedy Ascent  began at %s ' %
                     time.strftime('%H:%M:%S', time.gmtime(ga_start_time)))
    if parallel:
        with mp.Pool(processes=min(n_inits, N_CPU // 3)) as pool:
            ga_result = []
            process_started = [False] * n_inits
            process_running = [False] * n_inits
            process_index = 0
            while process_started.count(False) > 0:
                cpu_usage = psutil.cpu_percent(0.25)
                run_more = (100.0 - cpu_usage) * float(
                    psutil.cpu_count()) > 100.0 * N_AVAILABLE_CORE
                if run_more:
                    ga_result.append(
                        pool.apply_async(greedy_ascent,
                                         args=ga_args_list[process_index]))
                    process_started[process_index] = True
                    process_running[process_index] = True
                    process_index += 1
            while [not res.ready() for res in ga_result].count(True) > 0:
                time.sleep(1)
            ga_return_values = [res.get() for res in ga_result]
    else:
        ga_return_values = [
            greedy_ascent(*(ga_args_list[i])) for i in range(n_inits)
        ]
    ga_opt_vrt, ga_opt_acq = zip(*ga_return_values)
    sys.stdout.write(
        'and took %s\n' %
        time.strftime('%H:%M:%S', time.gmtime(time.time() - ga_start_time)))
    print('  '.join(['%.3E' % ga_opt_acq[i] for i in range(n_inits)]))

    opt_vrt = list(ga_opt_vrt[:])
    opt_acq = list(ga_opt_acq[:])

    ## Optimization using simulated annealing,
    ## 1. First optimize with Greedy Ascent, then do additional optimization with that results with Simulated Annealing
    ## 2. Optimize with a different set of initial points for Greedy Ascent and Simulated Annealing and choose the best
    ## Both does not any improvement on the result solely from Greedy Ascent
    # x_rands = torch.cat(tuple([torch.randint(low=0, high=int(n_v), size=(N_SA_RUN, 1))
    #                            for n_v in n_vertices]), dim=1).long()
    # sa_args_list = [(x_rands[i], inference_samples, partition_samples, edge_mat_samples,
    #                  n_vertices, acquisition_func, reference) for i in range(N_SA_RUN)]
    # sa_start_time = time.time()
    # sys.stdout.write('    Sim. Annealing began at %s ' % time.strftime('%H:%M:%S', time.gmtime(sa_start_time)))
    # if parallel:
    #     with mp.Pool(processes=min(N_SA_RUN, N_CPU // 2)) as pool:
    #         sa_result = []
    #         process_started = [False] * N_SA_RUN
    #         process_running = [False] * N_SA_RUN
    #         process_index = 0
    #         while process_started.count(False) > 0:
    #             cpu_usage = psutil.cpu_percent(1.0)
    #             run_more = (100.0 - cpu_usage) * float(psutil.cpu_count()) > 100.0 * N_AVAILABLE_CORE
    #             if run_more:
    #                 sa_result.append(pool.apply_async(simulated_annealing, args=sa_args_list[process_index]))
    #                 process_started[process_index] = True
    #                 process_running[process_index] = True
    #                 process_index += 1
    #         while [not res.ready() for res in sa_result].count(True) > 0:
    #             time.sleep(1)
    #
    #         sa_return_values = [res.get() for res in sa_result]
    # else:
    #     sa_return_values = [simulated_annealing(*(sa_args_list[i])) for i in range(N_SA_RUN)]
    # sa_opt_vrt, sa_opt_acq = zip(*sa_return_values)
    # sys.stdout.write('and took %s\n' % time.strftime('%H:%M:%S', time.gmtime(time.time() - sa_start_time)))
    # print('  '.join(['%4.2f' % sa_opt_acq[i] for i in range(N_SA_RUN)]))
    #
    # opt_vrt = opt_vrt + list(sa_opt_vrt[:])
    # opt_acq = opt_acq + list(sa_opt_acq[:])

    end_time = time.time()
    elapsed_time = end_time - start_time
    print('(%s) Acquisition function optimization ended %s' %
          (time.strftime('%H:%M:%S', time.gmtime(end_time)),
           time.strftime('%H:%M:%S', time.gmtime(elapsed_time))))

    # argsort sorts in ascending order so it is negated to have descending order
    acq_sort_inds = np.argsort(-np.array(opt_acq))
    suggestion = None
    for i in range(len(opt_vrt)):
        ind = acq_sort_inds[i]
        if not torch.all(opt_vrt[ind] == input_data, dim=1).any():
            suggestion = opt_vrt[ind]
            break
    if suggestion is None:
        for i in range(len(opt_vrt)):
            ind = acq_sort_inds[i]
            nbds = neighbors(opt_vrt[ind],
                             partition_samples,
                             edge_mat_samples,
                             n_vertices,
                             uniquely=True)
            for j in range(nbds.size(0)):
                if not torch.all(nbds[j] == input_data, dim=1).any():
                    suggestion = nbds[j]
                    break
            if suggestion is not None:
                break
    if suggestion is None:
        suggestion = torch.cat(tuple([
            torch.randint(low=0, high=int(n_v), size=(1, 1))
            for n_v in n_vertices
        ]),
                               dim=1).long()

    mean, std, var = prediction_statistic(suggestion, inference_samples,
                                          partition_samples, n_vertices)
    return suggestion, mean, std, var