用 Python 进行差分进化全局优化

差异进化是一种全局优化算法。

它是一种进化算法,与其他进化算法(例如遗传算法)有关。与遗传算法不同,它是专门设计用于对实值向量(而不是位串)进行运算的。此外,与遗传算法不同的是,它使用向量减法和加法等向量运算来导航搜索空间,而不是遗传学启发的变换。

在本教程中,您将发现差异演化全局优化算法。完成本教程后,您将知道:

  • 差分进化优化是一种进化算法,旨在与实值候选解一起使用。

  • 如何在python中使用差异进化优化算法API。

  • 使用差异演化解决具有多个最优解的全局优化问题的示例。

教程概述

本教程分为三个部分:他们是:

  • 差异进化

  • 差分进化API

  • 差分进化的工作实例

差异进化

差分进化,简称DE,是一种随机的全局搜索优化算法。它是一种进化算法,与其他进化算法(例如遗传算法)有关。与使用位序列表示候选解决方案的遗传算法不同,差分演化被设计为与用于连续目标函数的多维实值候选解决方案一起使用。

该算法在搜索中不使用梯度信息,因此非常适合于非微分非线性目标函数。该算法通过维护代表实值向量的候选解的总体来工作。通过制作现有解决方案的修改版本来创建新的候选解决方案,然后在算法的每次迭代中替换大部分人口。使用“策略”来创建新的候选解决方案,该策略涉及选择要添加突变的基本解决方案,以及从总体中计算出突变的数量和类型的其他候选解决方案,称为差异向量。例如,一种策略可以选择最佳候选解决方案作为突变中差异矢量的基础和随机解决方案。

如果子级具有更好的目标函数评估,则将基础解决方案替换为其子级。

变异计算为候选解决方案对之间的差异,从而产生差异矢量,然后将差异矢量添加到基本解决方案中,并通过设置在[0,2]范围内的变异因子超参数进行加权。

并非基本解决方案的所有元素都发生了突变。这是通过重组超参数控制的,通常将其设置为较大的值(例如80%),这意味着基本解决方案中的大多数(但不是全部)变量都将被替换。通过对概率分布(例如二项式或指数式)进行采样,分别为每个位置确定保留或替换基本解中的值的决策。

使用标准术语来描述以下形式的差异策略:     DE / x / y / z

DE代表“差分进化”,x定义了要变异的基本解,例如“ rand”代表随机,“ best”代表总体中的最佳解。y代表添加到基本解中的差异向量的数量,例如1,z定义用于确定每个解是否在总体中被保留或替换的概率分布,例如用于二项式的“bin”或用于二项式的“ exp”。

配置DE / best / 1 / binDE / best / 2 / bin是受欢迎的配置,因为它们在许多目标功能上表现良好。既然我们已经熟悉了差分进化算法,那么让我们看一下如何使用SciPy API实现。

差分进化API

Python中可通过differential_evolution()SciPy函数使用差分演化全局优化算法。该函数将目标函数的名称和每个输入变量的界限作为搜索的最小参数。

# perform the differential evolution search
result = differential_evolution(objective, bounds)

尽管可以将它们配置为自定义搜索,但还有许多其他具有默认值的搜索超参数。

关键的超参数是控制所执行的差异进化搜索类型的“策略”参数。默认情况下,将其设置为“ best1bin”(DE / best / 1 / bin),对于大多数问题而言,这是一个很好的配置。它通过从总体中选择随机解,从另一个中减去一个,然后将差异的缩放版本添加到总体中的最佳候选解中,来创建新的候选解。

new = best + (mutation * (rand1 – r and2))

“ popsize”参数控制总体中维护的候选解决方案的大小或数量。它是候选解决方案中维数的一个因素,默认情况下设置为15。这意味着对于2D目标函数,将维持(2 *15)或30个候选解决方案的总体大小。

该算法的迭代总数由“ maxiter”参数维护,默认为1,000。“变异”参数控制每次迭代对候选解决方案进行的更改数量。默认情况下,它设置为0.5。重组量通过“ recombination”参数控制,默认情况下设置为0.7(给定候选解决方案的70%)。最后,将本地搜索应用于在搜索结束时找到的最佳候选解决方案。这是通过“抛光”参数控制的,默认情况下将其设置为True。搜索的结果是一个OptimizeResult对象,可以在其中像字典一样访问属性。可以通过“成功”或“消息”键来访问搜索的成功与否。可以通过“ nfev”访问功能评估的总数,并且可以通过“ x”键访问为搜索找到的最佳输入。现在,我们已经熟悉了Python中的差异进化API,下面我们来看一些可行的示例。

差分进化的工作实例

在本节中,我们将看一个在具有挑战性的目标函数上使用差分演化算法的示例。Ackley函数是目标函数的一个示例,该目标函数具有单个全局最优值和多个局部最优值,可能会在其中陷入局部搜索。因此,需要全局优化技术。这是一个二维目标函数,其全局最佳值为[0,0],其值为0.0。下面的示例实现了Ackley,并创建了一个三维表面图,显示了全局最优值和多个局部最优值。

# ackley multimodal function
from numpy import arange
from numpy import exp
from numpy import sqrt
from numpy import cos
from numpy import e
from numpy import pi
from numpy import meshgrid
from matplotlib import pyplot
from mpl_toolkits.mplot3d import Axes3D
 
# objective function
def objective(x, y):
 return -20.0 * exp(-0.2 * sqrt(0.5 * (x**2 + y**2))) - exp(0.5 * (cos(2 * pi * x) + cos(2 * pi * y))) + e + 20
 
# define range for input
r_min, r_max = -5.0, 5.0
# sample input range uniformly at 0.1 increments
xaxis = arange(r_min, r_max, 0.1)
yaxis = arange(r_min, r_max, 0.1)
# create a mesh from the axis
x, y = meshgrid(xaxis, yaxis)
# compute targets
results = objective(x, y)
# create a surface plot with the jet color scheme
figure = pyplot.figure()
axis = figure.gca(projection='3d')
axis.plot_surface(x, y, results, cmap='jet')
# show the plot
pyplot.show()

运行示例将创建Ackley函数的表面图,以显示大量的局部最优值。

首先,我们可以将搜索空间的边界定义为每个维度中函数的极限。

# define the bounds on the search
bounds = [[r_min, r_max], [r_min, r_max]]

然后,我们可以通过指定目标函数的名称和搜索范围来应用搜索。在这种情况下,我们将使用默认的超参数。

# perform the differential evolution search
result = differential_evolution(objective, bounds)

搜索完成后,它将报告搜索状态和执行的迭代次数,以及通过评估发现的最佳结果。

# summarize the result
print('Status : %s' % result['message'])
print('Total Evaluations: %d' % result['nfev'])
# evaluate solution
solution = result['x']
evaluation = objective(solution)
print('Solution: f(%s) = %.5f' % (solution, evaluation))

结合在一起,下面列出了将微分进化应用于Ackley目标函数的完整示例。

# differential evolution global optimization for the ackley multimodal objective function
from scipy.optimize import differential_evolution
from numpy.random import rand
from numpy import exp
from numpy import sqrt
from numpy import cos
from numpy import e
from numpy import pi
 
# objective function
def objective(v):
 x, y = v
 return -20.0 * exp(-0.2 * sqrt(0.5 * (x**2 + y**2))) - exp(0.5 * (cos(2 * pi * x) + cos(2 * pi * y))) + e + 20
 
# define range for input
r_min, r_max = -5.0, 5.0
# define the bounds on the search
bounds = [[r_min, r_max], [r_min, r_max]]
# perform the differential evolution search
result = differential_evolution(objective, bounds)
# summarize the result
print('Status : %s' % result['message'])
print('Total Evaluations: %d' % result['nfev'])
# evaluate solution
solution = result['x']
evaluation = objective(solution)
print('Solution: f(%s) = %.5f' % (solution, evaluation))

运行示例将执行优化,然后报告结果。

注意:由于算法或评估程序的随机性,或者数值精度的差异,您的结果可能会有所不同。考虑运行该示例几次并比较平均结果。

在这种情况下,我们可以看到该算法在输入为零且目标函数评估为零的情况下定位了最优值。

我们可以看到总共执行了3,063个功能评估。

Status: Optimization terminated successfully.
Total Evaluations: 3063
Solution: f([0. 0.]) = 0.00000

作者:沂水寒城,CSDN博客专家,个人研究方向:机器学习、深度学习、NLP、CV

Blog: http://yishuihancheng.blog.csdn.net

赞 赏 作 者

用 Python 进行差分进化全局优化_第1张图片

更多阅读

2020 年最佳流行 Python 库 Top 10

2020 Python中文社区热门文章 Top 10

5分钟快速掌握 Python 定时任务框架

特别推荐

用 Python 进行差分进化全局优化_第2张图片

用 Python 进行差分进化全局优化_第3张图片

点击下方阅读原文加入社区会员

你可能感兴趣的:(算法,python,人工智能,深度学习,机器学习)