def test_cma_es_rosebrock_n(M=10): def funct(x,y): result = 0 for xx,yy in zip(x,y): result+=100.0*((yy-xx*xx)**2.0) + (1-xx)**2.0 return result N=M*2 x = flex.double(N,10.0) sd = flex.double(N,3.0) m = cma_es(N,x,sd) while ( not m.converged() ): # sample population p = m.sample_population() pop_size = p.accessor().all()[0] # update objective function v = flex.double(pop_size) for ii in range(pop_size): vector = p[(ii*N):(ii*N + N)] x = vector[0:M] y = vector[M:] v[ii] = funct(x,y) m.update_distribution(v) print(list(m.get_result())) print(flex.min(v)) print() x_final = m.get_result() print(list(x_final))
def test_cma_es_rosebrock_n(M=10): def funct(x,y): result = 0 for xx,yy in zip(x,y): result+=100.0*((yy-xx*xx)**2.0) + (1-xx)**2.0 return result N=M*2 x = flex.double(N,10.0) sd = flex.double(N,3.0) m = cma_es(N,x,sd) while ( not m.converged() ): # sample population p = m.sample_population() pop_size = p.accessor().all()[0] # update objective function v = flex.double(pop_size) for ii in range(pop_size): vector = p[(ii*N):(ii*N + N)] x = vector[0:M] y = vector[M:] v[ii] = funct(x,y) m.update_distribution(v) print list(m.get_result()) print flex.min(v) print x_final = m.get_result() print list(x_final)
def test_cma_es_file(): import libtbx.load_env m = cma_es(libtbx.env.dist_path("cma_es") + "/cma/initials.par") while (not m.converged()): # sample population and get problem size p = m.sample_population() pop_size = p.accessor().all()[0] N = p.accessor().all()[1] # update objective function v = flex.double(pop_size) for i in xrange(pop_size): v[i] = fitfun(p[(i*N):(i*N + N)],N) m.update_distribution(v) x_final = m.get_result() assert(approx_equal(x_final,flex.double(len(x_final),0.0),eps=1e-5))
def test_cma_es_file(): import libtbx.load_env m = cma_es(libtbx.env.dist_path("cma_es") + "/cma/initials.par") while (not m.converged()): # sample population and get problem size p = m.sample_population() pop_size = p.accessor().all()[0] N = p.accessor().all()[1] # update objective function v = flex.double(pop_size) for i in range(pop_size): v[i] = fitfun(p[(i*N):(i*N + N)],N) m.update_distribution(v) x_final = m.get_result() assert(approx_equal(x_final,flex.double(len(x_final),0.0),eps=1e-5))
def test_cma_es(): N = 3 x = flex.double(N,100.0) sd = flex.double(N,5.0) m = cma_es(N,x,sd) while (not m.converged()): # sample population p = m.sample_population() pop_size = p.accessor().all()[0] # update objective function v = flex.double(pop_size) for i in xrange(pop_size): v[i] = obj_fun(p[(i*N):(i*N + N)]) m.update_distribution(v) x_final = m.get_result() assert(approx_equal(x_final,center,eps=1e-6))
def test_cma_es(): N = 3 x = flex.double(N,100.0) sd = flex.double(N,5.0) m = cma_es(N,x,sd) while (not m.converged()): # sample population p = m.sample_population() pop_size = p.accessor().all()[0] # update objective function v = flex.double(pop_size) for i in range(pop_size): v[i] = obj_fun(p[(i*N):(i*N + N)]) m.update_distribution(v) x_final = m.get_result() assert(approx_equal(x_final,center,eps=1e-6))
def __init__(self, N, mean, sigma, evaluator, l=0): self.N = N self.x = mean self.sigma = sigma self.evaluator = evaluator self.optimizer = cma_es(self.N, self.x, self.sigma, l) self.count = 0 while (not self.optimizer.converged() ): # get sample population p = self.optimizer.sample_population() pop_size = p.accessor().all()[0] # update objective function v = flex.double(pop_size) for i in xrange(pop_size): vector = p[(i*N):(i*N + N)] v[i] = self.evaluator( vector ) self.optimizer.update_distribution(v) self.count += 1 self.x_final = self.optimizer.get_result() self.score_final = self.evaluator( self.x_final )
def __init__(self, N, mean, sigma, evaluator, l=0): self.N = N self.x = mean self.sigma = sigma self.evaluator = evaluator self.optimizer = cma_es(self.N, self.x, self.sigma, l) self.count = 0 while (not self.optimizer.converged()): # get sample population p = self.optimizer.sample_population() pop_size = p.accessor().all()[0] # update objective function v = flex.double(pop_size) for i in xrange(pop_size): vector = p[(i * N):(i * N + N)] v[i] = self.evaluator(vector) self.optimizer.update_distribution(v) self.count += 1 self.x_final = self.optimizer.get_result() self.score_final = self.evaluator(self.x_final)
def prior_guided_optimization(config, data_array, param_space, fast_addressing_of_data_array, regression_models, iteration_number, objective_weights, objective_limits, classification_model=None): """ Run a prior-guided bayesian optimization iteration. :param config: dictionary containing all the configuration parameters of this optimization. :param data_array: a dictionary containing previously explored points and their function values. :param param_space: parameter space object for the current application. :param fast_addressing_of_data_array: dictionary for quick-access to previously explored configurations. :param regression_models: the surrogate models used to evaluate points. :param iteration_number: the current iteration number. :param objective_weights: objective weights for multi-objective optimization. Not implemented yet. :param objective_limits: estimated minimum and maximum limits for each objective. :param classification_model: feasibility classifier for constrained optimization. """ acquisition_function_optimizer = config["acquisition_function_optimizer"] scalarization_key = config["scalarization_key"] function_parameters = {} function_parameters["param_space"] = param_space function_parameters["iteration_number"] = iteration_number function_parameters["regression_models"] = regression_models function_parameters['classification_model'] = classification_model function_parameters["objective_weights"] = objective_weights function_parameters["objective_limits"] = objective_limits function_parameters['model_type'] = config["models"]["model"] function_parameters["model_weight"] = config["model_posterior_weight"] function_parameters["posterior_floor"] = config[ "posterior_computation_lower_limit"] model_good_quantile = config["model_good_quantile"] function_parameters["threshold"] = {} optimization_metrics = param_space.get_optimization_parameters() for objective in optimization_metrics: function_parameters["threshold"][objective] = np.quantile( data_array[objective], model_good_quantile) if param_space.get_prior_normalization_flag() is True: prior_limit_estimation_points = config["prior_limit_estimation_points"] good_prior_normalization_limits = estimate_prior_limits( param_space, prior_limit_estimation_points, objective_weights) else: good_prior_normalization_limits = None function_parameters[ "good_prior_normalization_limits"] = good_prior_normalization_limits if classification_model is not None: function_parameters["posterior_normalization_limits"] = [ float("inf"), float("-inf") ] local_search_starting_points = config["local_search_starting_points"] local_search_random_points = config["local_search_random_points"] _, best_configuration_ls = local_search( local_search_starting_points, local_search_random_points, param_space, fast_addressing_of_data_array, False, # set feasibility to false, we handle it inside the acquisition function compute_EI_from_posteriors, function_parameters, scalarization_key, previous_points=data_array) logfile = deal_with_relative_and_absolute_path(config["run_directory"], config["log_file"]) sigma = config["cma_es_sigma"] cma_es_starting_points = config["cma_es_starting_points"] cma_es_random_points = config["cma_es_random_points"] best_configuration_cma = cma_es( param_space, data_array, fast_addressing_of_data_array, scalarization_key, logfile, compute_EI_from_posteriors, function_parameters, cma_es_random_points=cma_es_random_points, cma_es_starting_points=cma_es_starting_points, sigma=sigma) eis, valids = compute_EI_from_posteriors( [best_configuration_ls, best_configuration_cma], **function_parameters) if eis[0] < eis[1]: best_configuration = best_configuration_ls elif eis[1] < eis[0]: best_configuration = best_configuration_cma else: best_configuration = best_configuration_ls return best_configuration
def _arg_max_log_likelihood_function(self): """ This function estimates the autocorrelation parameters theta as the maximizer of the reduced likelihood function. (Minimization of the opposite reduced likelihood function is used for infoenience) Returns ------- optimal_theta : array_like The best set of autocorrelation parameters (the sought maximizer of the reduced likelihood function). optimal_reduced_likelihood_function_value : double The optimal reduced likelihood function value. optimal_par : dict The BLUP parameters associated to thetaOpt. """ if self.verbose: print("The chosen optimizer is: " + str(self.optimizer)) print('Log-likelihood mode: {}'.format(self.llf_mode)) if self.random_start > 1: print("{} random restarts are specified.".format( self.random_start)) # setup the log10 search bounds bounds = np.c_[self.thetaL, self.thetaU] if self.llf_mode == 'nugget_estim': alpha_bound = np.atleast_2d([1e-10, 1.0 - 1e-10]) #print(bounds, alpha_bound) bounds = np.r_[bounds, alpha_bound] elif self.llf_mode == 'noisy': # TODO: better estimation the upper and lowe bound of sigma2 # TODO: implement optimization for the heterogenous case sigma2_upper = self.y.std()**2. - self.noise_var sigma2_bound = np.atleast_2d([1e-5, sigma2_upper]) bounds = np.r_[bounds, sigma2_bound] log10bounds = log10(bounds) # if the model has been optimized before as the starting point, # then use the last optimized hyperparameters # supposed to be good for updating the model incrementally # TODO: validate this if hasattr(self, 'theta_'): log10theta0 = log10(self.theta_) else: log10theta0 = log10(self.theta0) if self.theta0 is not None else \ np.random.uniform(log10(bounds)[:, 0], log10(bounds)[:, 1]) log10param = log10theta0 if self.llf_mode not in ['nugget_estim', 'noisy'] else \ np.r_[log10theta0, uniform(log10bounds[-1, 0], log10bounds[-1, 1])] optimal_par = {} n_par = len(log10param) # TODO: how to set this properly? or it should be left open for the user eval_budget = 200 * n_par if self.eval_budget is None else self.eval_budget llf_opt = np.inf # L-BFGS method based on analytical gradient if self.optimizer == 'BFGS': def obj_func(log10param): param = 10.**np.array(log10param) __ = self.log_likelihood_function(param, eval_grad=True) return -__[0], -__[1] * param.reshape(-1, 1) wait_count = 0 # stagnation counter for iteration in range(self.random_start): if iteration != 0: log10param = np.random.uniform(log10bounds[:, 0], log10bounds[:, 1]) param_opt_, llf_opt_, info = fmin_l_bfgs_b(obj_func, log10param, bounds=log10bounds, maxfun=eval_budget) if iteration == 0: param_opt = param_opt_ llf_opt = llf_opt_ elif (llf_opt - llf_opt_) / max(abs(llf_opt), abs(llf_opt), 1) >= 1e7 * MACHINE_EPSILON: param_opt, llf_opt = param_opt_, llf_opt_ wait_count = 0 else: wait_count += 1 if self.verbose: print('restart {} {} evals, best llf: {}'.format( iteration + 1, info['funcalls'], -llf_opt)) if info["warnflag"] != 0: warnings.warn( "fmin_l_bfgs_b terminated abnormally with " "the state: {}".format(info)) eval_budget -= info['funcalls'] if eval_budget <= 0 or wait_count >= self.wait_iter: break elif self.optimizer == 'CMA': # IPOP-CMA-ES def obj_func(log10param): param = 10.**np.array(log10param) __ = self.log_likelihood_function(param) return __ opt = { 'sigma_init': 0.25 * np.max(log10bounds[:, 1] - log10bounds[:, 0]), 'eval_budget': eval_budget, 'f_target': np.inf, 'lb': log10bounds[:, 1], 'ub': log10bounds[:, 0], 'restart_budget': self.random_start } optimizer = cma_es(n_par, log10param, obj_func, opt, is_minimize=False, restart='IPOP') param_opt, llf_opt, evalcount, info = optimizer.optimize() param_opt = param_opt.flatten() if self.verbose: print('{} evals, best llf: {}'.format(evalcount, -llf_opt)) optimal_param = 10.**param_opt optimal_llf_value = self.log_likelihood_function( optimal_param, optimal_par) if self.llf_mode in ['nugget_estim', 'noisy']: optimal_theta = optimal_param[:-1] else: optimal_theta = optimal_param return optimal_theta, optimal_llf_value, optimal_par