def minimize_plot(name, optimizer, fun, bounds, value_limit=math.inf, plot_limit=math.inf, num_retries=1024, workers=mp.cpu_count(), logger=logger(), stop_fitness=-math.inf, statistic_num=5000): time0 = time.perf_counter() # optimization start time name += '_' + optimizer.name logger.info('optimize ' + name) store = Store(fun, bounds, capacity=500, logger=logger, statistic_num=statistic_num) ret = retry(store, optimizer.minimize, value_limit, workers, stop_fitness) impr = store.get_improvements() np.savez_compressed(name, ys=impr) filtered = np.array([imp for imp in impr if imp[1] < plot_limit]) if len(filtered) > 0: impr = filtered logger.info(name + ' time ' + str(dtime(time0))) plot(impr, 'progress_aret.' + name + '.png', label=name, xlabel='time in sec', ylabel=r'$f$') return ret
def minimize_plot(name, fun, nobj, ncon, bounds, popsize=64, max_evaluations=100000, nsga_update=False, pareto_update=0, workers=mp.cpu_count(), logger=logger(), plot_name=None): name += '_mode_' + str(popsize) + '_' + \ ('nsga_update' if nsga_update else ('de_update_' + str(pareto_update))) logger.info('optimize ' + name) xs, ys = minimize(fun, nobj, ncon, bounds, popsize=popsize, max_evaluations=max_evaluations, nsga_update=nsga_update, pareto_update=pareto_update, workers=workers, logger=logger, plot_name=plot_name) np.savez_compressed(name, xs=xs, ys=ys) moretry.plot(name, ncon, xs, ys)
def cv_score(X): X = X[0] score = cross_val_score( XGBRegressor( colsample_bytree=X[0], gamma=X[1], min_child_weight=X[2], learning_rate=X[3], max_depth=int(X[4]), n_estimators=10000, reg_alpha=X[5], reg_lambda=X[6], subsample=X[7], n_jobs=1 # required for cmaes with multiple workers ), train_x, train_y, scoring='neg_mean_squared_error').mean() score = np.array(score) global f_evals f_evals.value += 1 global best_f if best_f.value < score: best_f.value = score logger.info( "time = {0:.1f} y = {1:.5f} f(xmin) = {2:.5f} nfev = {3} {4}".format( dtime(t0), score, best_f.value, f_evals.value, X)) return score
def test_multiretry(num_retries = min(256, 8*mp.cpu_count()), keep = 0.7, optimizer = de2_cma(1500), logger = logger(), repeat = 10): seqs = Tandem(0).seqs n = len(seqs) problems = [Tandem(i) for i in range(n)] ids = [str(seqs[i]) for i in range(n)] t0 = time.perf_counter() for _ in range(repeat): # check all variants problem_stats = multiretry.minimize(problems, ids, num_retries, keep, optimizer, logger) ps = problem_stats[0] # for _ in range(10): # # improve the best variant using only one node # fval = ray.get(ps.retry.remote(optimizer)) # logger.info("improve best variant " + ray.get(ps.name.remote()) # + ' ' + str(ray.get(ps.id.remote())) # + ' ' + str(ray.get(ps.value.remote())) # + ' time = ' + str(dtime(t0))) # if fval < -1490: # break # optimize best variant starting from scratch using all nodes logger.info("improve best variant " + ray.get(ps.name.remote()) + ' ' + str(ray.get(ps.id.remote())) + ' ' + str(ray.get(ps.value.remote())) + ' time = ' + str(dtime(t0))) problem = problems[ray.get(ps.index.remote())] _rayoptimizer(optimizer, problem, 1, max_time = 1200, log = logger)
def fun(self, x): self.evals.value += 1 y = self.pfun(x) if y < self.best_y.value: self.best_y.value = y logger.info(str(dtime(self.t0)) + ' ' + str(self.evals.value) + ' ' + str(self.best_y.value) + ' ' + str(list(x))) return y
def test_multiretry(num_retries = 512, keep = 0.7, optimizer = de_cma(1500), logger = logger(), repeat = 50): seqs = Tandem(0).seqs n = len(seqs) problems = [Tandem(i) for i in range(n)] ids = [str(seqs[i]) for i in range(n)] for _ in range(100): problem_stats = multiretry.minimize(problems, ids, num_retries, keep, optimizer, logger) ps = problem_stats[0] for _ in range(repeat): logger.info("problem " + ps.prob.name + ' ' + str(ps.id)) ps.retry(optimizer)
def adv_minimize_plot(name, optimizer, fun, bounds, value_limit = math.inf, num_retries = 1024, logger=logger(), statistic_num = 0): time0 = time.perf_counter() # optimization start time name += '_smart_' + optimizer.name logger.info('smart optimize ' + name) store = advretry.Store(lambda x:fun(x)[0], bounds, capacity=5000, logger=logger, num_retries=num_retries, statistic_num = statistic_num) advretry.retry(store, optimizer.minimize, value_limit) xs = np.array(store.get_xs()) ys = np.array([fun(x) for x in xs]) retry.plot(ys, '_all_' + name + '.png', interp=False) np.savez_compressed(name , xs=xs, ys=ys) xs, front = pareto(xs, ys) logger.info(name+ ' time ' + str(dtime(time0))) retry.plot(front, '_front_' + name + '.png')
def test_multiretry(num_retries=128, keep=0.7, optimizer=de_cma(1500), logger=logger(), repeat=50): problems = [] ids = [] for seq in sequences(): problems.append(Cassini1multi(planets=seq)) ids.append(str(seq)) for _ in range(100): problem_stats = multiretry.minimize(problems, ids, num_retries, keep, optimizer, logger) ps = problem_stats[0] for _ in range(repeat): logger.info("problem " + ps.prob.name + ' ' + str(ps.id)) ps.retry(optimizer)
def minimize_plot(name, optimizer, fun, bounds, weight_bounds, ncon = 0, value_limits = None, num_retries = 1024, exp = 2.0, workers = mp.cpu_count(), logger=logger(), statistic_num = 0, plot_name = None): time0 = time.perf_counter() # optimization start time name += '_' + optimizer.name logger.info('optimize ' + name) xs, ys = minimize(fun, bounds, weight_bounds, ncon, value_exp = exp, value_limits = value_limits, num_retries = num_retries, optimizer = optimizer, workers = workers, logger=logger, statistic_num = statistic_num, plot_name = plot_name) logger.info(name + ' time ' + str(dtime(time0))) np.savez_compressed(name, xs=xs, ys=ys) plot(name, ncon, xs, ys)
def minimize( fun, bounds, max_nodes=None, workers=None, num_retries=5000, value_limit=math.inf, logger=None, popsize=31, min_evaluations=1500, max_eval_fac=None, check_interval=100, capacity=500, stop_fittness=None, optimizer=None, statistic_num=0, max_time=100000, minimizers=None # reused distributed ray actors ): """Minimization of a scalar function of one or more variables using coordinated parallel CMA-ES retry. Parameters ---------- fun : callable The objective function to be minimized. ``fun(x, *args) -> float`` where ``x`` is an 1-D array with shape (n,) and ``args`` is a tuple of the fixed parameters needed to completely specify the function. bounds : sequence or `Bounds`, optional Bounds on variables. There are two ways to specify the bounds: 1. Instance of the `scipy.Bounds` class. 2. Sequence of ``(min, max)`` pairs for each element in `x`. None is used to specify no bound. max_nodes : int maximal number of distributed nodes (physical CPUs) used. workers : int number of parallel processes used. Use None if using CPUs with different number of cores, then mp.cpu_count() is used at each node. num_retries : int, optional Number of optimization retries, only used to calculate the evaluation limit increment. Because nodes may have different CPU-power, max_time is used to terminate optimization. value_limit : float, optional Upper limit for optimized function values to be stored. This limit needs to be carefully set to a value which is seldom found by optimization retry to keep the store free of bad runs. The crossover offspring of bad parents can cause the algorithm to get stuck at local minima. logger : logger, optional logger for log output of the retry mechanism. If None, logging is switched off. Default is a logger which logs both to stdout and appends to a file ``optimizer.log``. popsize = int, optional CMA-ES population size used for all CMA-ES runs. Not used for differential evolution. Ignored if parameter optimizer is defined. min_evaluations : int, optional Initial limit of the number of function evaluations. Only used if optimizer is undefined, otherwise this setting is defined in the optimizer. max_eval_fac : int, optional Final limit of the number of function evaluations = max_eval_fac*min_evaluations check_interval : int, optional After ``check_interval`` runs the store is sorted and the evaluation limit is incremented by ``evals_step_size`` capacity : int, optional capacity of the evaluation store. Higher value means broader search. stop_fittness : float, optional Limit for fitness value. optimization runs terminate if this value is reached. optimizer : optimizer.Optimizer, optional optimizer to use. Default is a sequence of differential evolution and CMA-ES. Since advanced retry sets the initial step size it works best if CMA-ES is used / in the sequence of optimizers. max_time : int, optional Time limit in seconds minimizers : list of Minimizer, optional remote ray actors for reuse. Need to be terminated finally - call terminate.remote(). Returns ------- res : scipy.OptimizeResult, list of Minimizer The optimization result is represented as an ``OptimizeResult`` object. Important attributes are: ``x`` the solution array, ``fun`` the best function value, ``nfev`` the number of function evaluations, ``success`` a Boolean flag indicating if the optimizer exited successfully. """ if minimizers is None: # determine the number of nodes connected # len(ray.nodes()) seems not not work for ray 0.8.6 ipadrs = set(ray.get([remote_ipadr.remote() for _ in range(20000)])) if not logger is None: logger.info("cluster optimization on nodes: " + str(ipadrs)) nodes = len(ipadrs) if max_nodes is None else min( max_nodes, len(ipadrs)) minimizers = [] ips = {} master_ip = ipadr() # start the ray remote minimizers for rid in range(nodes): minimizer = None while minimizer is None: minimizer = Minimizer.remote(master_ip, rid, fun) ip = ray.get(minimizer.ip.remote()) if ip in ips: minimizer.__ray_terminate__.remote() minimizer = None else: ips[ip] = minimizer minimizers.append(minimizer) # else reuse minimizers for minimizer in minimizers: ray.get( minimizer.init.remote(bounds, workers, value_limit, num_retries, popsize, min_evaluations, max_eval_fac, check_interval, capacity, stop_fittness, optimizer)) ray.get(minimizer.retry.remote()) store = Store(bounds, max_eval_fac, check_interval, capacity, logger, num_retries, statistic_num) # each second exchange results for _ in range(max_time): time.sleep(1) improved = False for minimizer in minimizers: # polling is ugly but experiments with a coordinator actor failed # should be refactored when ray improves if ray.get(minimizer.is_improved.remote()): improved = True y, xs, lower, upper = ray.get(minimizer.best.remote(0)) store.add_result(y, xs, lower, upper, 0) # for recipient in minimizers: if recipient != minimizer: recipient.add_result.remote(y, xs, lower, upper) if improved: store.sort() time.sleep(10) # time to transfer all messages # terminate subprocesses for minimizer in minimizers: ray.get(minimizer.terminate_procs.remote()) return OptimizeResult(x=store.get_x_best(), fun=store.get_y_best(), nfev=store.get_count_evals(), success=True), minimizers