首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PyGMO批量适应度评价

PyGMO批量适应度评价
EN

Stack Overflow用户
提问于 2020-02-27 14:51:18
回答 1查看 853关注 0票数 3

我的目标是使用PyGmo执行参数估计(模型校准)。我的模型将是一个外部的"black“模型(c-代码),输出被最小化的目标函数J (在本例中,J将是模型输出与实测数据之间的”归一化均方误差“)。为了加速优化(校准),我想在多个内核/线程上并行运行我的模型/模拟。因此,我想在PyGMO中使用批处理适应度评估器(bfe)。我使用一个简单的问题类编写了一个最小的示例,但是使用了纯python (没有外部模型)和rosenbrock问题:

代码语言:javascript
复制
#!/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。

删去或删去这两行:

代码语言:javascript
复制
   fvs = b(prob, dvs)
    print(fvs)

脚本可以无错误地运行。

我的问题:

  1. 如何使用批量健身评估?(我知道这是PyGMO的一个新功能,他们还在编写文档.)有人能给出一个关于如何实现这一点的最小例子吗?
  2. 这是加速我的模型校准问题的正确方法吗?或者我应该使用岛屿和群岛?如果我做对了,群岛上的岛屿就不会彼此沟通了,对吧?因此,如果一个人执行粒子群优化,并且想同时(并行)评估几个目标函数调用,那么批适应度评估器是正确的选择吗?
  3. 在这个例子中,我需要关心群岛和岛屿吗?它们到底是干什么用的?是否值得运行几个优化,但以不同的初始x(输入到目标函数),然后采取最佳的解决方案?这是遗传算法优化中常见的方法吗?

我对优化领域和PyGMO非常熟悉,所以感谢您的帮助!

EN

回答 1

Stack Overflow用户

发布于 2020-02-28 08:48:50

这是加速我的模型校准问题的正确方法吗?或者我应该使用岛屿和群岛?如果我做对了,群岛上的岛屿就不会彼此沟通了,对吧?因此,如果一个人执行粒子群优化,并且想同时(并行)评估几个目标函数调用,那么批适应度评估器是正确的选择吗?

分页并行有两种模式:岛模型(即粗粒度并行化)和BFE机器(即细粒度并行化)。

海岛模型适用于任意问题/算法组合,其思想是在交换信息的同时并行运行多个优化,以加速全局收敛到一个解。

相反,BFE机器并行化了一个单一的优化,它需要在求解器中得到明确的支持才能工作。目前在pagmo中,只有少数几个求解者能够利用BFE机器。BFE机器也可以用来并行初始化一个群体的个人,这是有用的是你的健身功能是特别重量级的。

哪种并行化方法最适合您,取决于问题的属性。根据我的经验,如果适应度函数非常重(例如,计算需要几分钟或更长时间),用户倾向于使用BFE机器(细粒度并行化),因为在这种情况下,健康评估成本太高,要想利用岛屿模型,就必须等待太长时间。BFE在某种意义上也更容易理解,因为您不需要深入研究群岛、拓扑等的细节。另一方面,BFE只对某些求解者进行工作(尽管我们试图随着时间的推移将BFE支持扩展到其他解决者)。

如何使用批量健身评估?(我知道这是PyGMO的一个新功能,他们还在编写文档.)有人能给出一个关于如何实现这一点的最小例子吗?

使用BFE的一种方法是您在示例中所做的工作,即通过在您的问题中实现batch_fitness()方法。但是,我的建议是注释掉batch_fitness()方法,并尝试使用带有页面的通用批处理适应度评估器之一。最简单的方法就是默认构造bfe类的一个实例,然后将其传递给可以使用BFE机器的算法之一。其中一种算法是nspso:

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

所以,就像这样:

代码语言:javascript
复制
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算法的循环中并行地评估您的适应度函数。

如果您需要更多的帮助,请到我们的公共用户/devs聊天室,在那里您应该得到相当快的帮助(通常):

https://gitter.im/pagmo2/Lobby

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60435885

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档