Python DEAP и многопроцессорная обработка на Windows: AttributeError - PullRequest
0 голосов
/ 06 апреля 2020

У меня следующая ситуация:

  • Windows 10
  • Python 3.7
  • deap 1.3.1

Существует main.py с

def main():
    ...
    schedule.schedule()
    ...

if __name__== "__main__":
    main()

Затем у меня также есть файл schedule.py с

def schedule()
   ...
    toolbox = base.Toolbox()

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

    toolbox.register('individual', init_indiv, creator.Individual, bounds=bounds)
    toolbox.register("population", tools.initRepeat, list, toolbox.individual)

    toolbox.register("evaluate", fitness, data=args)
    toolbox.register("mate", tools.cxTwoPoint)
    toolbox.register("mutate", tools.mutFlipBit, indpb=0.05)
    toolbox.register("select", tools.selTournament, tournsize=3)

    # Further parameters
    cxpb = 0.7
    mutpb = 0.2

    # Measure how long it takes to caluclate 1 generation
    MAX_HOURS_GA = parameter._MAX_HOURS_GA
    POPSIZE_GA = parameter._POPSIZE_GA
    pool = multiprocessing.Pool(processes=4)
    toolbox.register("map", pool.map)
    pop = toolbox.population(n=POPSIZE_GA * len(bounds))
    result = algorithms.eaSimple(pop, toolbox, cxpb, mutpb, 1, verbose=False)

Теперь при выполнении этого выдается следующая ошибка:

Process SpawnPoolWorker-1:
Traceback (most recent call last):
  File "C:\Users\...\lib\multiprocessing\process.py", line 297, in _bootstrap
    self.run()
  File "C:\Users\...\lib\multiprocessing\process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\...\lib\multiprocessing\pool.py", line 110, in worker
    task = get()
  File "C:\Users\...\lib\multiprocessing\queues.py", line 354, in get
    return _ForkingPickler.loads(res)
AttributeError: Can't get attribute 'Individual' on <module 'deap.creator' from 'C:\\Users...

Теперь отмечу, что в документации DEAP (https://deap.readthedocs.io/en/master/tutorials/basic/part4.html) написано

Предупреждение. Как указано в рекомендациях по многопроцессорности, в разделе Windows Пул процессов должен быть защищен в разделе> if __name__ == "__main__" из-за способа инициализации процессов.

но это на самом деле не помогает мне, поскольку я, конечно, не хочу, чтобы все toolbox.register(...) были в моем основном списке, и это даже было бы невозможно сделать. Простое перемещение создания пула

    pool = multiprocessing.Pool(processes=4)
    toolbox.register("map", pool.map)

в главное не помогло.

Кажется, есть другие люди с похожими проблемами, даже довольно недавно (https://github.com/rsteca/sklearn-deap/issues/59). Для большинства из них, кажется, существует какой-то обходной путь, но ни один из них не подходит для моей ситуации, или, по крайней мере, я не мог понять, как заставить их работать. Я также попытался изменить порядок регистрации функций и инициализации пула, но безуспешно. Я также попытался использовать S COOP вместо этого, но с похожими результатами.

Есть идеи?

1 Ответ

0 голосов
/ 07 апреля 2020

Решение состоит в том, чтобы создать «FitnessMin» и «Individual» в глобальном масштабе, т.е. в main.py:

import ...

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

def main():
    ...
    schedule.schedule()
    ...

if __name__== "__main__":
    main()
...