def main(): NGEN = 100 MU, LAMBDA = 10, 10 verbose = True # create_plot = True population = [] for i in range(0, 10): population.append(creator.Individual(*get_random_parameters())) # print(population) for ind in population: ind.fitness.values = toolbox.evaluate(ind) # hof = tools.HallOfFame(1) strategy = cma.StrategyMultiObjective(population, sigma=1.0, mu=MU, lambda_=LAMBDA) toolbox.register("generate", strategy.generate, creator.Individual) toolbox.register("update", strategy.update) stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("min", np.min, axis=0) stats.register("max", np.max, axis=0) logbook = tools.Logbook() logbook.header = ["gen", "nevals"] + (stats.fields if stats else []) fitness_history = [] for gen in range(NGEN): population = toolbox.generate() # Evaluate fitnesses = toolbox.map(toolbox.evaluate, population) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit fitness_history.append(fit) toolbox.update(population) record = stats.compile(population) if stats is not None else {} logbook.record(gen=gen, nevals=len(population), **record) if verbose: print(logbook.stream) # print(population) # print(hof[0]) # print(population, list(map(test_func, population))) for ind in population: acc, pr_time = test_func(ind) print("ind: {0} accuracy: {1} time: {2}".format(ind, acc, pr_time))
def test_mo_cma_es(): def distance(feasible_ind, original_ind): """A distance function to the feasibility region.""" return sum((f - o)**2 for f, o in zip(feasible_ind, original_ind)) def closest_feasible(individual): """A function returning a valid individual from an invalid one.""" feasible_ind = numpy.array(individual) feasible_ind = numpy.maximum(BOUND_LOW, feasible_ind) feasible_ind = numpy.minimum(BOUND_UP, feasible_ind) return feasible_ind def valid(individual): """Determines if the individual is valid or not.""" if any(individual < BOUND_LOW) or any(individual > BOUND_UP): return False return True NDIM = 5 BOUND_LOW, BOUND_UP = 0.0, 1.0 MU, LAMBDA = 10, 10 NGEN = 500 # The MO-CMA-ES algorithm takes a full population as argument population = [creator.__dict__[INDCLSNAME](x) for x in numpy.random.uniform(BOUND_LOW, BOUND_UP, (MU, NDIM))] toolbox = base.Toolbox() toolbox.register("evaluate", benchmarks.zdt1) toolbox.decorate("evaluate", tools.ClosestValidPenality(valid, closest_feasible, 1.0e-6, distance)) for ind in population: ind.fitness.values = toolbox.evaluate(ind) strategy = cma.StrategyMultiObjective(population, sigma=1.0, mu=MU, lambda_=LAMBDA) toolbox.register("generate", strategy.generate, creator.__dict__[INDCLSNAME]) toolbox.register("update", strategy.update) for gen in range(NGEN): # Generate a new population population = toolbox.generate() # Evaluate the individuals fitnesses = toolbox.map(toolbox.evaluate, population) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit # Update the strategy with the evaluated individuals toolbox.update(population) hv = hypervolume(strategy.parents, [11.0, 11.0]) assert hv > HV_THRESHOLD, "Hypervolume is lower than expected %f < %f" % (hv, HV_THRESHOLD)
def test_mo_cma_es(): def distance(feasible_ind, original_ind): """A distance function to the feasibility region.""" return sum((f - o)**2 for f, o in zip(feasible_ind, original_ind)) def closest_feasible(individual): """A function returning a valid individual from an invalid one.""" feasible_ind = numpy.array(individual) feasible_ind = numpy.maximum(BOUND_LOW, feasible_ind) feasible_ind = numpy.minimum(BOUND_UP, feasible_ind) return feasible_ind def valid(individual): """Determines if the individual is valid or not.""" if any(individual < BOUND_LOW) or any(individual > BOUND_UP): return False return True NDIM = 5 BOUND_LOW, BOUND_UP = 0.0, 1.0 MU, LAMBDA = 10, 10 NGEN = 500 numpy.random.seed(128) # The MO-CMA-ES algorithm takes a full population as argument population = [ creator.__dict__[INDCLSNAME](x) for x in numpy.random.uniform(BOUND_LOW, BOUND_UP, (MU, NDIM)) ] toolbox = base.Toolbox() toolbox.register("evaluate", benchmarks.zdt1) toolbox.decorate( "evaluate", tools.ClosestValidPenalty(valid, closest_feasible, 1.0e+6, distance)) for ind in population: ind.fitness.values = toolbox.evaluate(ind) strategy = cma.StrategyMultiObjective(population, sigma=1.0, mu=MU, lambda_=LAMBDA) toolbox.register("generate", strategy.generate, creator.__dict__[INDCLSNAME]) toolbox.register("update", strategy.update) for gen in range(NGEN): # Generate a new population population = toolbox.generate() # Evaluate the individuals fitnesses = toolbox.map(toolbox.evaluate, population) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit # Update the strategy with the evaluated individuals toolbox.update(population) # Note that we use a penalty to guide the search to feasible solutions, # but there is no guarantee that individuals are valid. # We expect the best individuals will be within bounds or very close. num_valid = 0 for ind in strategy.parents: dist = distance(closest_feasible(ind), ind) if numpy.isclose(dist, 0.0, rtol=1.e-5, atol=1.e-5): num_valid += 1 assert num_valid >= len(strategy.parents) # Note that NGEN=500 is enough to get consistent hypervolume > 116, # but not 119. More generations would help but would slow down testing. hv = hypervolume(strategy.parents, [11.0, 11.0]) assert hv > HV_THRESHOLD, "Hypervolume is lower than expected %f < %f" % ( hv, HV_THRESHOLD)
def CMAES_MO(var, weights, funcs_l, sigma, verbose=True, MAXITER=100, STAGNATION_ITER=10, lambda_=3, mu=5): NRESTARTS = 10 # Initialization + 9 I-POP restarts creator.create("MaFitness", base.Fitness, weights=weights) creator.create("Individual", list, fitness=creator.MaFitness) toolbox = base.Toolbox() eval_funcs = lambda x: tuple([f(x) for f in funcs_l]) toolbox.register("evaluate", eval_funcs) S.Swarm.controller.rez_params() S.model = var c = S.extract_genotype() init_func = lambda c, sigma, size: np.random.normal(c, sigma, size) toolbox.register("attr_float", init_func, c, sigma, len(var)) toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.attr_float) toolbox.register("population", tools.initRepeat, list, toolbox.individual) toolbox.register("evaluate", eval_funcs) halloffame = tools.HallOfFame(1) stats = tools.Statistics(lambda ind: np.array([ind.fitness.values])) stats.register("average", np.mean) stats.register("std", np.std) stats.register("min", np.min) stats.register("max", np.max) logbooks = list() bestvalues = list() medianvalues = list() i = 0 t = 0 while i < (NRESTARTS): pop = toolbox.population(n=mu) strategy = cma.StrategyMultiObjective(centroid=c, sigma=sigma, lambda_=lambda_, population=pop) toolbox.register("generate", strategy.generate, creator.Individual) toolbox.register("update", strategy.update) logbooks.append(tools.Logbook()) logbooks[ -1].header = "gen", "evals", "restart", "regime", "std", "min", "avg", "max" conditions = { "MaxIter": False, "TolHistFun": False, "EqualFunVals": False, "TolX": False, "TolUpSigma": False, "Stagnation": False, "ConditionCov": False, "NoEffectAxis": False, "NoEffectCoor": False } while not any(conditions.values()): if (t % 5 == 0): S.Swarm.controller.visibility = True else: S.Swarm.controller.visibility = False t = t + 1 # Generate a new population population = pop + toolbox.generate() # Evaluate the individuals fitnesses = toolbox.map(toolbox.evaluate, population) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit halloffame.update(population) record = stats.compile(population) logbooks[-1].record(gen=t, restart=i, **record) if verbose: print(logbooks[-1].stream) # Update the strategy with the evaluated individuals toolbox.update(population) # Log the best and median value of this population bestvalues.append(population[-1].fitness.values) medianvalues.append(population[int(round(len(population) / 2.))].fitness.values) if t >= MAXITER: # The maximum number of iteration per CMA-ES ran conditions["MaxIter"] = True if len(bestvalues) > STAGNATION_ITER and len(medianvalues) > STAGNATION_ITER and \ np.median(bestvalues[-20:]) >= np.median( bestvalues[-STAGNATION_ITER:-STAGNATION_ITER + 20]) and \ np.median(medianvalues[-20:]) >= np.median( medianvalues[-STAGNATION_ITER:-STAGNATION_ITER + 20]): # Stagnation occured conditions["Stagnation"] = True pop = [p.fitness.values for p in population[-1:-mu]] stop_causes = [k for k, v in conditions.items() if v] print( "Stopped because of condition%s %s" % ((":" if len(stop_causes) == 1 else "s:"), ",".join(stop_causes))) i += 1
def main(): # The cma module uses the numpy random number generator # numpy.random.seed(128) MU, LAMBDA = 10, 10 NGEN = 500 verbose = True # The MO-CMA-ES algorithm takes a full population as argument population = [ creator.Individual(x) for x in (numpy.random.uniform(0, 1, (MU, N))) ] for ind in population: ind.fitness.values = toolbox.evaluate(ind) strategy = cma.StrategyMultiObjective(population, sigma=1.0, mu=MU, lambda_=LAMBDA) toolbox.register("generate", strategy.generate, creator.Individual) toolbox.register("update", strategy.update) stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("min", numpy.min, axis=0) stats.register("max", numpy.max, axis=0) logbook = tools.Logbook() logbook.header = ["gen", "nevals"] + (stats.fields if stats else []) for gen in range(NGEN): # Generate a new population population = toolbox.generate() # Evaluate the individuals fitnesses = toolbox.map(toolbox.evaluate, population) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit # Update the strategy with the evaluated individuals toolbox.update(population) record = stats.compile(population) if stats is not None else {} logbook.record(gen=gen, nevals=len(population), **record) if verbose: print(logbook.stream) if verbose: print("Final population hypervolume is %f" % hypervolume(strategy.parents, [11.0, 11.0])) # import matplotlib.pyplot as plt # valid_front = numpy.array([ind.fitness.values for ind in strategy.parents if valid(ind)]) # invalid_front = numpy.array([ind.fitness.values for ind in strategy.parents if not valid(ind)]) # fig = plt.figure() # if len(valid_front) > 0: # plt.scatter(valid_front[:,0], valid_front[:,1], c="g") # if len(invalid_front) > 0: # plt.scatter(invalid_front[:,0], invalid_front[:,1], c="r") # plt.show() return strategy.parents
def main(): # The cma module uses the numpy random number generator # numpy.random.seed(128) MU, LAMBDA = 10, 10 NGEN = 500 verbose = True create_plot = False # The MO-CMA-ES algorithm takes a full population as argument population = [ creator.Individual(x) for x in (numpy.random.uniform(0, 1, (MU, N))) ] for ind in population: ind.fitness.values = toolbox.evaluate(ind) strategy = cma.StrategyMultiObjective(population, sigma=1.0, mu=MU, lambda_=LAMBDA) toolbox.register("generate", strategy.generate, creator.Individual) toolbox.register("update", strategy.update) stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("min", numpy.min, axis=0) stats.register("max", numpy.max, axis=0) logbook = tools.Logbook() logbook.header = ["gen", "nevals"] + (stats.fields if stats else []) fitness_history = [] for gen in range(NGEN): # Generate a new population population = toolbox.generate() # Evaluate the individuals fitnesses = toolbox.map(toolbox.evaluate, population) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit fitness_history.append(fit) # Update the strategy with the evaluated individuals toolbox.update(population) record = stats.compile(population) if stats is not None else {} logbook.record(gen=gen, nevals=len(population), **record) if verbose: print((logbook.stream)) if verbose: print(("Final population hypervolume is %f" % hypervolume(strategy.parents, [11.0, 11.0]))) # Note that we use a penalty to guide the search to feasible solutions, # but there is no guarantee that individuals are valid. # We expect the best individuals will be within bounds or very close. num_valid = 0 for ind in strategy.parents: dist = distance(closest_feasible(ind), ind) if numpy.isclose(dist, 0.0, rtol=1.e-5, atol=1.e-5): num_valid += 1 print(("Number of valid individuals is %d/%d" % (num_valid, len(strategy.parents)))) print("Final population:") print((numpy.asarray(strategy.parents))) if create_plot: interactive = 0 if not interactive: import matplotlib as mpl_tmp mpl_tmp.use( 'Agg') # Force matplotlib to not use any Xwindows backend. import matplotlib.pyplot as plt fig = plt.figure() plt.title("Multi-objective minimization via MO-CMA-ES") plt.xlabel("First objective (function) to minimize") plt.ylabel("Second objective (function) to minimize") # Limit the scale because our history values include the penalty. plt.xlim((-0.1, 1.20)) plt.ylim((-0.1, 1.20)) # Plot all history. Note the values include the penalty. fitness_history = numpy.asarray(fitness_history) plt.scatter(fitness_history[:, 0], fitness_history[:, 1], facecolors='none', edgecolors="lightblue") valid_front = numpy.array([ ind.fitness.values for ind in strategy.parents if close_valid(ind) ]) invalid_front = numpy.array([ ind.fitness.values for ind in strategy.parents if not close_valid(ind) ]) if len(valid_front) > 0: plt.scatter(valid_front[:, 0], valid_front[:, 1], c="g") if len(invalid_front) > 0: plt.scatter(invalid_front[:, 0], invalid_front[:, 1], c="r") if interactive: plt.show() else: print("Writing cma_mo.png") plt.savefig("cma_mo.png") return strategy.parents