Оценка пригодности PyGMO Batch - PullRequest
1 голос
/ 27 февраля 2020

Моя цель - выполнить оценку параметров (калибровку модели), используя PyGmo . Моей моделью будет внешняя модель "черного блока" (c -код), выводящая целевую функцию J для минимизации (в данном случае J будет "Нормализованная Root средняя квадратическая ошибка" (NRMSE) между моделями выходные данные и измеренные данные. Чтобы ускорить оптимизацию (калибровку), я хотел бы запускать свои модели / симуляции на нескольких ядрах / потоках параллельно. Поэтому я хотел бы использовать пакетный анализатор пригодности (bfe) в PyGMO. Я подготовил минимальный пример использования простого класса задачи, но с использованием чистого python (без внешней модели) и проблемы rosenbrock:

#!/usr/bin/env python
# coding: utf-8

import numpy as np
from fmpy import read_model_description, extract, simulate_fmu, freeLibrary
from fmpy.fmi2 import FMU2Slave
import pygmo as pg
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
import time

#-------------------------------------------------------

def main():
        # Optimization
        # Define problem
        class my_problem:
                def __init__(self, dim):
                        self.dim = dim
                def fitness(self, x):
                        J = np.zeros((1,))
                        for i in range(len(x) - 1):
                                J[0] += 100.*(x[i + 1]-x[i]**2)**2+(1.-x[i])**2
                        return J
                def get_bounds(self):
                        return (np.full((self.dim,),-5.),np.full((self.dim,),10.))
                def get_name(self):
                        return "My implementation of the Rosenbrock problem"
                def get_extra_info(self):
                        return "\nDimensions: " + str(self.dim)
                def batch_fitness(self, dvs):
                        J = [123] * len(dvs)
                        return J

        prob = pg.problem(my_problem(30))
        print('\n----------------------------------------------')
        print('\nProblem description: \n')
        print(prob)

        #-------------------------------------------------------

        dvs = pg.batch_random_decision_vector(prob, 1)
        print('\n----------------------------------------------')
        print('\nBarch fitness evaluation:')
        print('\ndvs length:' + str(len(dvs)))
        print('\ndvs:')
        print(dvs)
        udbfe = pg.default_bfe()
        b = pg.bfe(udbfe=udbfe)       
        print('\nudbfe:')
        print(udbfe)
        print('\nbfe:')
        print(b)
        fvs = b(prob, dvs)
        print(fvs)

        #-------------------------------------------------------

        pop_size = 50
        gen_size = 1000
        algo = pg.algorithm(pg.sade(gen = gen_size)) # The algorithm (a self-adaptive form of Differential Evolution (sade - jDE variant)
        algo.set_verbosity(int(gen_size/10)) # We set the verbosity to 100 (i.e. each 100 gen there will be a log line)
        print('\n----------------------------------------------')
        print('\nOptimization:')
        start = time.time()
        pop = pg.population(prob, size = pop_size) # The initial population
        pop = algo.evolve(pop) # The actual optimization process
        best_fitness = pop.get_f()[pop.best_idx()] # Getting the best individual in the population
        print('\n----------------------------------------------')
        print('\nResult:')
        print('\nBest fitness: ', best_fitness) # Get the best parameter set
        best_parameterset = pop.get_x()[pop.best_idx()]
        print('\nBest parameter set: ',best_parameterset)
        print('\nTime elapsed for optimization: ', time.time() - start, ' seconds\n')

if __name__ == '__main__':
    main()

Когда я пытаюсь запустить этот код, я получаю следующую ошибку:

Исключительная ситуация: ValueError

функция: bfe_check_output_fvs

где: C: \ projects \ pagmo2 \ src \ detail \ bfe_impl. cpp, 103

что: Недопустимый результат был получен при оценке пригодности партии: число произведенных векторов пригодности, 30, отличается от числа векторов входных решений, 1

Удаляя или комментируя эти две строки:

   fvs = b(prob, dvs)
    print(fvs)

, сценарий можно запустить без ошибок.

Мои вопросы:

  1. Как использовать фитнес-пакет оценка? (Я знаю, что это новая возможность PyGMO, и они все еще работают над документацией ...) Кто-нибудь может привести минимальный пример того, как это реализовать?
  2. Это правильный путь для go ускорить мою проблему калибровки модели? Или я должен использовать острова и архипелаги? Если я правильно понял, острова в архипелаге go не общаются друг с другом, верно? Таким образом, если кто-то выполняет, например, Оптимизацию роя частиц и хочет оценивать несколько вызовов целевых функций одновременно (параллельно), тогда оценщик пригодности партии является правильным выбором?
  3. Нужно ли мне заботиться об архипелагах и островах в этом примере ? Для чего они предназначены? Стоит ли проводить несколько оптимизаций, но с разными начальными значениями x (входные данные для целевой функции), а затем выбрать лучшее решение? Это общий подход в оптимизации с GA?

Я очень хорошо знаком с областью оптимизации и PyGMO, так что спасибо за помощь!

1 Ответ

1 голос
/ 28 февраля 2020

Это правильный путь к go, чтобы ускорить проблему калибровки моей модели? Или я должен использовать острова и архипелаги? Если я правильно понял, острова в архипелаге go не общаются друг с другом, верно? Так, если кто-то выполняет, например, Оптимизацию роя частиц и хочет оценивать несколько вызовов целевых функций одновременно (параллельно), тогда оценщик пригодности партии является правильным выбором?

В pagmo есть 2 режима распараллеливания, модель островков (т. е. крупнозернистое распараллеливание) и механизм BFE (т. е. мелкозернистое распараллеливание).

Модель островков работает с любой комбинацией задачи / алгоритма и основана на идее множественного оптимизации выполняются параллельно при обмене информацией для ускорения глобального сближения с решением.

Механизм BFE вместо этого распараллеливает оптимизацию single , и для его работы требуется явная поддержка в решателе. , В настоящее время в Pagmo только немногие решатели могут воспользоваться преимуществами машин BFE. Механизм BFE также можно использовать для распараллеливания инициализации группы людей, что может быть полезно, если ваша функция физической формы особенно тяжелая.

Какой метод распараллеливания вам больше всего подходит, зависит от свойств вашей проблемы. По моему опыту, пользователи склонны предпочитать механизм BFE (мелкозернистое распараллеливание), если функция пригодности очень тяжелая (например, для вычисления требуются минуты или более), потому что в такой ситуации оценки пригодности настолько дороги, что для Воспользовавшись моделью острова, придется ждать слишком долго. BFE также в некотором смысле легче понять, потому что вам не нужно углубляться в детали архипелагов, топологий и т. Д. c. С другой стороны, BFE работает только с определенными решателями (хотя с течением времени мы пытаемся расширить поддержку BFE для других решателей).

Как использовать оценку пригодности партии? (Я знаю, что это новая возможность PyGMO, и они все еще работают над документацией ...) Кто-нибудь может привести минимальный пример того, как это реализовать?

Один из способов использования BFE - это что вы сделали в своем примере, т. е. с помощью реализации метода batch_fitness() в вашей задаче. Тем не менее, я бы предложил закомментировать метод batch_fitness() и попробовать использовать один из универсальных оценщиков пригодности для партии, предоставляемых с pagmo. Самый простой способ - создать экземпляр класса bfe по умолчанию и передать его одному из алгоритмов, которые могут использовать механизм BFE. Одним из таких алгоритмов является nspso:

https://esa.github.io/pygmo2/algorithms.html#pygmo .nspso

Итак, что-то вроде этого:

b = pg.bfe() # Construct a default BFE
uda = pg.nspso(gen = gen_size) # Construct the algorithm
uda.set_bfe(b) # Tell the UDA to use the BFE machinery
algo = pg.algorithm(uda) # Construct a pg.algorithm from the UDA
new_pop = algo.evolve(pop) # Evolve the population

Это должно использовать несколько процессов для параллельно оцените свои фитнес-функции в рамках алгоритма nspso l oop.

Если вам нужна дополнительная помощь, пожалуйста, зайдите в нашу общедоступную чат-комнату для пользователей / 1044 *, где вам следует обратиться за помощью. быстро (обычно):

https://gitter.im/pagmo2/Lobby

...