python Библиотека DEAP, несколько процессоров - PullRequest
0 голосов
/ 17 февраля 2020

Я хочу решить многоцелевую задачу оптимизации, используя DEAP, основанную на python инфраструктуру. Из-за длительных процессов мне нужно использовать все свои ресурсы процессора для вычислений. Поэтому я использовал многопроцессорную библиотеку, как предложено в документации DEAP и в этом примере , но в результате получается PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed. Мой общий код слишком длинный, чтобы записать его, но следующий код похож на мой код и приводит к той же ошибке. Можете ли вы сказать мне, где я могу сделать ошибку? Заранее спасибо

import multiprocessing
from deap import creator, base, tools, algorithms
import random
import matplotlib.pyplot as plt
def TEST(dec_var):
    return dec_var[0]**2+dec_var[1]**2,(dec_var[0]-2)**2+dec_var[1]**2
def feasible(dec_var):
    if all(i>0 for i in dec_var):
        return True
    return False

creator.create("FitnessMin", base.Fitness, weights=(-1.0,-1.0))
creator.create("Individual", list, fitness=creator.FitnessMin)
toolbox=base.Toolbox()

toolbox.register("uniform", random.uniform, 0.0, 7.0)
toolbox.register("individual",tools.initRepeat,creator.Individual,toolbox.uniform ,n=2)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)

toolbox.register("mate", tools.cxTwoPoint)
toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=1, indpb=0.1)
toolbox.register("select", tools.selNSGA2)
toolbox.register("evaluate", TEST)
toolbox.decorate("evaluate", tools.DeltaPenalty(feasible,(1000,1000)))

def main(seed=None):
    random.seed(seed)

    NGEN = 250
    MU = 100
    CXPB = 0.9

    stats_func1 = tools.Statistics(key=lambda ind: ind.fitness.values[0])
    stats_func2 = tools.Statistics(key=lambda ind: ind.fitness.values[1])
    stats = tools.MultiStatistics(func1=stats_func1, func2=stats_func2)
    stats.register("avg", numpy.mean, axis=0)
    stats.register("std", numpy.std, axis=0)
    stats.register("min", numpy.min, axis=0)
    stats.register("max", numpy.max, axis=0)

    logbook = tools.Logbook()
    logbook.header = "gen", "evals", "func1","func2"
    logbook.chapters["func1"].header = "min", "max"
    logbook.chapters["func2"].header = "min", "max"    
    pop = toolbox.population(n=MU)


    invalid_ind = [ind for ind in pop if not ind.fitness.valid]
    fitnesses = toolbox.map(toolbox.evaluate, invalid_ind)
    for ind, fit in zip(invalid_ind, fitnesses):
        ind.fitness.values = fit


    pop = toolbox.select(pop, len(pop))
    record = stats.compile(pop)
    logbook.record(gen=0, evals=len(invalid_ind), **record)
    print(logbook.stream)


    for gen in range(1, NGEN):

        offspring = tools.selTournamentDCD(pop, len(pop))
        offspring = [toolbox.clone(ind) for ind in offspring]

        for ind1, ind2 in zip(offspring[::2], offspring[1::2]):
            if random.random() <= CXPB:
                toolbox.mate(ind1, ind2)

            toolbox.mutate(ind1)
            toolbox.mutate(ind2)
            del ind1.fitness.values, ind2.fitness.values


        invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
        fitnesses = toolbox.map(toolbox.evaluate, invalid_ind)
        for ind, fit in zip(invalid_ind, fitnesses):
            ind.fitness.values = fit


        pop = toolbox.select(pop + offspring, MU)
        record = stats.compile(pop)
        logbook.record(gen=gen, evals=len(invalid_ind), **record)
        print(logbook.stream)



    return pop, logbook
if __name__ == "__main__":
    pool = multiprocessing.Pool(processes=4)
    toolbox.register("map", pool.map)
    pop, stats = main()
    pool.close()
    print pop

1 Ответ

0 голосов
/ 17 февраля 2020

Это указано на странице документации, которую вы связали:

Функция лямбда-травления пока недоступна в Python.

Вы используете лямбда-функции в stats_func1 и stats_func2 - просто переместите их в глобальные функции и повторите попытку:

def stats_key_1(ind):
    return ind.fitness.values[0]

def stats_key_2(ind):
    return ind.fitness.values[1]

# ... snip ...

def main(seed=None):

    # ... snip ...

    stats_func1 = tools.Statistics(key=stats_key_1)
    stats_func2 = tools.Statistics(key=stats_key_1)
...