【翻译自 : Visualization for Function Optimization in Python

      【说明:Jason Brownlee PhD大神的文章个人很喜欢,所以闲暇时间里会做一点翻译和学习实践的工作,这里是相应工作的实践记录,希望能帮到有需要的人!】

      函数优化涉及从目标函数中找到产生最佳值的输入。优化算法在输入变量的搜索空间中导航以定位最佳位置,目标函数的形状和算法在搜索空间中的行为在现实世界中都是不透明的。因此,通常使用简单的低维函数来研究优化算法,这些函数可以直接直观地看到。此外,通过优化算法在这些简单函数的输入空间中的样本可以在其适当的上下文中可视化。

       低维函数的可视化以及这些函数上的算法行为可以帮助开发直觉,这些直觉随后可以转移到更复杂的高维函数优化问题上。

      在本教程中,您将发现如何在Python中创建可视化的函数优化。完成本教程后,您将知道:

可视化是研究函数优化算法时的重要工具。
如何使用线图可视化一维函数和样本。
如何使用等高线和曲面图可视化二维函数和样本。

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

1、功能优化的可视化
2、可视化一维功能优化
   1、测试功能
   2、样品测试功能
   3、测试功能的线图
   4、测试功能散点图
   5、带有标记最优值的线图
   6、样品线图
3、可视化2D功能优化
   1、测试功能
   2、样品测试功能
   3、测试功能的轮廓图
   4、测试功能的填充轮廓图
   5、用样本填充测试函数的轮廓图
   6、测试功能的表面图

功能优化的可视化

      函数优化是与寻找函数输入有关的数学领域,该输入导致函数的最佳输出,通常是最小值或最大值。

      对于简单的微分函数来说,优化可能是简单明了的,在该函数中可以通过解析来计算解决方案。但是,我们有兴趣解决应用机器学习中的大多数功能时,它们的行为可能会或可能不会很好,并且可能是复杂的,非线性的,多元的和不可微的。

     因此,重要的是要了解可用于解决功能优化问题的各种不同算法。

     研究函数优化的一个重要方面是了解要优化的目标函数以及了解优化算法随时间的行为。

     在开始进行功能优化时,可视化起着重要作用。我们可以选择简单且易于理解的测试功能来研究优化算法。可绘制这些简单函数的图,以了解目标函数的输入与目标函数的输出之间的关系,并突出显示山丘,山谷和最优峰。此外,通过优化算法从搜索空间中选择的样本也可以绘制在目标函数图的顶部。这些算法行为图可以提供洞察力和直觉,以了解特定的优化算法如何工作以及如何在搜索空间中导航,将来可以推广到新的问题。通常,选择一维或二维函数来研究优化算法,因为它们很容易使用标准图(如线图和曲面图)可视化。在本教程中,我们将对此进行探讨。

   首先,让我们探讨如何可视化一维函数优化。

可视化一维功能优化

        一维函数采用单个输入变量,并输出该输入变量的评估值。输入变量通常是连续的,由实值浮点值表示。 通常,输入域是不受限制的,尽管对于测试问题,我们强加了一个感兴趣的域。

测试函数

      在这种情况下,我们将使用简单的x ^ 2目标函数探索函数可视化:

                                                                                                                 f(x)= x ^ 2
      输入x = 0.0时的最佳值等于0.0。

     下面的示例实现此目标函数并评估单个输入。

# example of a 1d objective function

# objective function
def objective(x):
	return x**2.0

# evaluate inputs to the objective function
x = 4.0
result = objective(x)
print('f(%.3f) = %.3f' % (x, result))

        运行示例将使用目标函数评估值4.0,该值等于16.0。

f(4.000) = 16.000

采样测试函数

     我们可能要对新功能进行的第一件事是定义感兴趣的输入范围,并使用统一的网格对感兴趣的域进行采样。该样本将为以后生成图提供基础。在这种情况下,我们将围绕x = 0.0的最佳值(从x = -5.0到x = 5.0)定义一个感兴趣的域,并以0.1的增量在此范围内的值网格进行采样,例如-5.0,-4.9,-4.8 等

...
# define range for input
r_min, r_max = -5.0, 5.0
# sample input range uniformly at 0.1 increments
inputs = arange(r_min, r_max, 0.1)
# summarize some of the input domain
print(inputs[:5])

       然后,我们可以评估样本中的每个x值。

# compute targets
results = objective(inputs)
# summarize some of the results
print(results[:5])

        最后,我们可以检查一些输入及其对应的输出。

# create a mapping of some inputs to some results
for i in range(5):
	print('f(%.3f) = %.3f' % (inputs[i], results[i]))

      结合在一起,下面列出了采样输入空间并评估样本中所有点的完整示例。

# sample 1d objective function
from numpy import arange

# objective function
def objective(x):
	return x**2.0

# define range for input
r_min, r_max = -5.0, 5.0
# sample input range uniformly at 0.1 increments
inputs = arange(r_min, r_max, 0.1)
# summarize some of the input domain
print(inputs[:5])
# compute targets
results = objective(inputs)
# summarize some of the results
print(results[:5])
# create a mapping of some inputs to some results
for i in range(5):
	print('f(%.3f) = %.3f' % (inputs[i], results[i]))

      首先运行示例将按预期生成统一的输入点样本。 然后使用目标函数评估输入点,最后,我们可以看到输入到目标函数输出的简单映射。

[-5.  -4.9 -4.8 -4.7 -4.6]
[25.   24.01 23.04 22.09 21.16]
f(-5.000) = 25.000
f(-4.900) = 24.010
f(-4.800) = 23.040
f(-4.700) = 22.090
f(-4.600) = 21.160

       现在我们对生成输入样本并使用目标函数进行评估有一定的信心,现在我们可以看看生成函数图。

测试函数曲线

      我们可以对输入空间进行随机采样,但是均匀的点线或网格的好处是可以用来生成平滑图。

      这是平滑的,因为输入空间中的点从最小到最大有序。 正如我们期望的那样(希望)目标函数的输出在值之间具有相似的平滑关系,例如 输入的微小变化会导致函数输出的局部一致(平滑)变化。

      在这种情况下,我们可以使用样本生成目标函数的线图,输入点(x)在图的x轴上,而目标函数输出(结果)在图的y轴上。

# create a line plot of input vs result
pyplot.plot(inputs, results)
# show the plot
pyplot.show()

    完整实例如下:

# line plot of input vs result for a 1d objective function
from numpy import arange
from matplotlib import pyplot

# objective function
def objective(x):
	return x**2.0

# define range for input
r_min, r_max = -5.0, 5.0
# sample input range uniformly at 0.1 increments
inputs = arange(r_min, r_max, 0.1)
# compute targets
results = objective(inputs)
# create a line plot of input vs result
pyplot.plot(inputs, results)
# show the plot
pyplot.show()

      运行示例将创建目标函数的折线图。 我们可以看到函数具有大的U形,称为抛物线。 这是研究曲线时的常见形状,例如 微积分的研究。

python做多目标优化 python多目标优化函数_优化算法

测试功能散点图

      该行是一个构造。 它并不是真正的功能,只是功能的顺利总结。 始终牢记这一点。回想一下,实际上,我们在输入空间中生成了一个点样本,并对这些点进行了相应的评估。这样,创建点的散点图会更准确; 例如:

# scatter plot of input vs result for a 1d objective function
from numpy import arange
from matplotlib import pyplot

# objective function
def objective(x):
	return x**2.0

# define range for input
r_min, r_max = -5.0, 5.0
# sample input range uniformly at 0.1 increments
inputs = arange(r_min, r_max, 0.1)
# compute targets
results = objective(inputs)
# create a scatter plot of input vs result
pyplot.scatter(inputs, results)
# show the plot
pyplot.show()

       运行示例将创建目标函数的散点图。 我们可以看到函数的熟悉形状,但是直接绘制点并没有任何好处。 该线和它提供的点之间的平滑插值更加有用,因为我们可以在该线的顶部绘制其他点,例如最优位置或通过优化算法采样的点。

python做多目标优化 python多目标优化函数_二维_02

带有标记最优值的线图

       接下来,让我们再次绘制折线图,这次绘制一个已知函数最佳点所在的点。这在研究优化算法时可能会有所帮助,因为我们可能希望了解优化算法与最优算法的距离。

       首先,我们必须定义最佳输入,然后评估该点以给出用于绘制的x轴和y轴值。

# define the known function optima
optima_x = 0.0
optima_y = objective(optima_x)

      完整实例如下:

# define the known function optima
optima_x = 0.0
optima_y = objective(optima_x)

      运行示例将创建函数熟悉的折线图,然后创建函数的最佳值,例如 用红色正方形标记导致函数最小输出的输入。

python做多目标优化 python多目标优化函数_二维_03

      这是一个非常简单的函数,并且最容易看到最佳状态的红色正方形。 有时函数可能会更复杂,有许多丘陵和山谷,我们可能想使最优值更加可见。 在这种情况下,我们可以在整个图上画一条垂直线。

# draw a vertical line at the optimal input
pyplot.axvline(x=optima_x, ls='--', color='red')

      完整实例如下:

# line plot of input vs result for a 1d objective function and show optima as line
from numpy import arange
from matplotlib import pyplot

# objective function
def objective(x):
	return x**2.0

# define range for input
r_min, r_max = -5.0, 5.0
# sample input range uniformly at 0.1 increments
inputs = arange(r_min, r_max, 0.1)
# compute targets
results = objective(inputs)
# create a line plot of input vs result
pyplot.plot(inputs, results)
# define the known function optima
optima_x = 0.0
# draw a vertical line at the optimal input
pyplot.axvline(x=optima_x, ls='--', color='red')
# show the plot
pyplot.show()

       运行示例将创建相同的图,这次绘制一条红线清楚地标记了输入空间中标记最优点的点。

python做多目标优化 python多目标优化函数_优化算法_04

样品线图

     最后,我们可能希望绘制由优化算法选择的输入空间的样本。 我们将使用从输入域中抽取的随机点来模拟这些样本。

# simulate a sample made by an optimization algorithm
seed(1)
sample = r_min + rand(10) * (r_max - r_min)
# evaluate the sample
sample_eval = objective(sample)

       然后,我们可以绘制此样本,在这种情况下,使用小的黑色圆圈。

# plot the sample as black circles
pyplot.plot(sample, sample_eval, 'o', color='black')

        下面列出了创建函数的线图的完整示例,该函数的最佳点用红线标记,并且算法示例用小黑点绘制。

# line plot of domain for a 1d function with optima and algorithm sample
from numpy import arange
from numpy.random import seed
from numpy.random import rand
from matplotlib import pyplot

# objective function
def objective(x):
	return x**2.0

# define range for input
r_min, r_max = -5.0, 5.0
# sample input range uniformly at 0.1 increments
inputs = arange(r_min, r_max, 0.1)
# compute targets
results = objective(inputs)
# simulate a sample made by an optimization algorithm
seed(1)
sample = r_min + rand(10) * (r_max - r_min)
# evaluate the sample
sample_eval = objective(sample)
# create a line plot of input vs result
pyplot.plot(inputs, results)
# define the known function optima
optima_x = 0.0
# draw a vertical line at the optimal input
pyplot.axvline(x=optima_x, ls='--', color='red')
# plot the sample as black circles
pyplot.plot(sample, sample_eval, 'o', color='black')
# show the plot
pyplot.show()

       运行示例将创建域的折线图,并像以前一样用红线标记最优值。 这次,用黑点绘制了通过算法选择的域中的样本(实际上是点的随机样本)。 我们可以想象一个真正的优化算法会在从起点下坡搜索时显示出缩小的点。

python做多目标优化 python多目标优化函数_二维_05

     接下来,让我们看看我们如何执行类似的可视化效果以优化二维功能。

可视化2D功能优化

        二维函数是采用两个输入变量的函数,例如 x和y。

测试函数

       我们可以使用相同的x ^ 2函数并将其缩放为二维函数; 例如:

                                                                                                                      f(x,y)= x ^ 2 + y ^ 2
        输入[x = 0.0,y = 0.0]时的最佳值等于0.0。下面的示例实现此目标函数并评估单个输入。

# example of a 2d objective function

# objective function
def objective(x, y):
	return x**2.0 + y**2.0

# evaluate inputs to the objective function
x = 4.0
y = 4.0
result = objective(x, y)
print('f(%.3f, %.3f) = %.3f' % (x, y, result))

         运行示例将评估点[x = 4,y = 4],等于32。

f(4.000, 4.000) = 32.000

        接下来,我们需要一种对域进行采样的方法,以便依次对目标函数进行采样。

样品测试功能

         采样二维函数的一种常见方法是,首先沿每个变量x和y生成一个均匀样本,然后使用这两个均匀样本创建一个样本网格,称为网格。这不是跨输入空间的二维数组。 而是两个二维数组一起使用时,定义了两个输入变量之间的网格。这是通过为每个y样本点复制整个x样本数组并类似地为每个x样本点复制整个y样本数组来实现的。这可以使用meshgrid()NumPy函数来实现。 例如:

# 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)
# summarize some of the input domain
print(x[:5, :5])

        然后,我们可以使用目标函数评估每对点。

# compute targets
results = objective(x, y)
# summarize some of the results
print(results[:5, :5])

         最后,我们可以回顾一些输入到它们对应的输出值的映射。

# create a mapping of some inputs to some results
for i in range(5):
	print('f(%.3f, %.3f) = %.3f' % (x[i,0], y[i,0], results[i,0]))

        下面的示例演示了如何在二维输入空间和目标函数上创建统一的样本网格。

# sample 2d objective function
from numpy import arange
from numpy import meshgrid

# objective function
def objective(x, y):
	return x**2.0 + y**2.0

# 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)
# summarize some of the input domain
print(x[:5, :5])
# compute targets
results = objective(x, y)
# summarize some of the results
print(results[:5, :5])
# create a mapping of some inputs to some results
for i in range(5):
	print('f(%.3f, %.3f) = %.3f' % (x[i,0], y[i,0], results[i,0]))

       运行示例首先总结网格网格中的一些点,然后评估一些点的目标函数。 最后,我们枚举二维输入空间中的坐标及其相应的函数评估。

[[-5.  -4.9 -4.8 -4.7 -4.6]
 [-5.  -4.9 -4.8 -4.7 -4.6]
 [-5.  -4.9 -4.8 -4.7 -4.6]
 [-5.  -4.9 -4.8 -4.7 -4.6]
 [-5.  -4.9 -4.8 -4.7 -4.6]]
[[50.   49.01 48.04 47.09 46.16]
 [49.01 48.02 47.05 46.1  45.17]
 [48.04 47.05 46.08 45.13 44.2 ]
 [47.09 46.1  45.13 44.18 43.25]
 [46.16 45.17 44.2  43.25 42.32]]
f(-5.000, -5.000) = 50.000
f(-5.000, -4.900) = 49.010
f(-5.000, -4.800) = 48.040
f(-5.000, -4.700) = 47.090
f(-5.000, -4.600) = 46.160

       既然我们熟悉了如何对输入空间进行采样并评估点,那么让我们看一下如何绘制函数。

测试功能的轮廓图

       二维函数的流行图形是轮廓图。

       该图为每个x和y坐标创建了目标函数输出的平面表示,其中颜色和轮廓线指示了目标函数输出的相对值或高度。

       这就像可以将高山与山谷区分开的景观等高线图。

      这可以通过使用轮廓()Matplotlib函数来实现,该函数将网格网格和网格网格的评估直接作为输入。

      然后,我们可以指定在轮廓上绘制的级别数和要使用的配色方案。 在这种情况下,我们将使用50个级别和流行的“喷射”配色方案,其中低级使用冷色方案(蓝色),高级使用热色方案(红色)。

# create a contour plot with 50 levels and jet color scheme
pyplot.contour(x, y, results, 50, alpha=1.0, cmap='jet')
# show the plot
pyplot.show()

       结合在一起,下面列出了创建二维目标函数的轮廓图的完整示例。

# create a contour plot with 50 levels and jet color scheme
pyplot.contour(x, y, results, 50, alpha=1.0, cmap='jet')
# show the plot
pyplot.show()

Tying this together, the complete example of creating a contour plot of the two-dimensional objective function is listed below.

# contour plot for 2d objective function
from numpy import arange
from numpy import meshgrid
from matplotlib import pyplot

# objective function
def objective(x, y):
	return x**2.0 + y**2.0

# 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 contour plot with 50 levels and jet color scheme
pyplot.contour(x, y, results, 50, alpha=1.0, cmap='jet')
# show the plot
pyplot.show()

          运行示例将创建轮廓图。 我们可以看到,边缘周围的曲面越弯曲的部分具有更多的轮廓来显示细节,而中间的曲面越少的弯曲部分具有较少的轮廓。 可以看到,域的最低部分是中间部分。

python做多目标优化 python多目标优化函数_函数优化_06

测试功能的填充轮廓图

        对等高线之间的图进行着色以显示更完整的表面也很有帮助。

       同样,颜色只是简单的线性插值,而不是真正的功能评估。 在更复杂的功能上必须牢记这一点,在这些功能上不会显示出详细的细节。

       我们可以使用带有相同参数的函数的contourf()版本填充轮廓图。

# create a filled contour plot with 50 levels and jet color scheme
pyplot.contourf(x, y, results, levels=50, cmap='jet')

        我们还可以在情节上显示最佳值,在这种情况下,它是白色星星,它将在情节最低部分的蓝色背景色中脱颖而出。

# define the known function optima
optima_x = [0.0, 0.0]
# draw the function optima as a white star
pyplot.plot([optima_x[0]], [optima_x[1]], '*', color='white')

      完整实例如下:

# filled contour plot for 2d objective function and show the optima
from numpy import arange
from numpy import meshgrid
from matplotlib import pyplot

# objective function
def objective(x, y):
	return x**2.0 + y**2.0

# 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 filled contour plot with 50 levels and jet color scheme
pyplot.contourf(x, y, results, levels=50, cmap='jet')
# define the known function optima
optima_x = [0.0, 0.0]
# draw the function optima as a white star
pyplot.plot([optima_x[0]], [optima_x[1]], '*', color='white')
# show the plot
pyplot.show()

       运行示例将创建填充轮廓图,该轮廓图可以更好地说明目标函数的形状。 然后,在[x = 0,y = 0]处的最佳状态用白色星号清楚地标记。

python做多目标优化 python多目标优化函数_优化算法_07

用样本填充测试函数的轮廓图

        我们可能想展示优化算法的进展,以了解在目标函数形状的情况下其行为。

        在这种情况下,我们可以在输入空间中模拟具有随机坐标的优化算法选择的点。

# simulate a sample made by an optimization algorithm
seed(1)
sample_x = r_min + rand(10) * (r_max - r_min)
sample_y = r_min + rand(10) * (r_max - r_min)

       然后可以将这些点直接绘制为黑色圆圈,并且它们的上下文颜色可以使它们具有相对的质量。 

# plot the sample as black circles
pyplot.plot(sample_x, sample_y, 'o', color='black')

       完整实例如下:

# filled contour plot for 2d objective function and show the optima and sample
from numpy import arange
from numpy import meshgrid
from numpy.random import seed
from numpy.random import rand
from matplotlib import pyplot

# objective function
def objective(x, y):
	return x**2.0 + y**2.0

# 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)
# simulate a sample made by an optimization algorithm
seed(1)
sample_x = r_min + rand(10) * (r_max - r_min)
sample_y = r_min + rand(10) * (r_max - r_min)
# create a filled contour plot with 50 levels and jet color scheme
pyplot.contourf(x, y, results, levels=50, cmap='jet')
# define the known function optima
optima_x = [0.0, 0.0]
# draw the function optima as a white star
pyplot.plot([optima_x[0]], [optima_x[1]], '*', color='white')
# plot the sample as black circles
pyplot.plot(sample_x, sample_y, 'o', color='black')
# show the plot
pyplot.show()

        运行示例,我们可以像以前一样看到填充的轮廓图,并标记了最佳值。 现在,我们可以看到绘制为黑点的样本及其周围的颜色和与最佳值的相对距离给出了算法(在这种情况下为随机点)与解决问题有多接近的想法。

python做多目标优化 python多目标优化函数_函数优化_08

测试功能的表面图

         最后,我们可能希望创建目标函数的三维图,以更全面地了解函数的曲率。这可以通过使用plot_surface()Matplotlib函数来实现,该函数与轮廓图一样,直接获取网格并进行函数评估。

# 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')

     完整实例如下:

# surface plot for 2d objective function
from numpy import arange
from numpy import meshgrid
from matplotlib import pyplot
from mpl_toolkits.mplot3d import Axes3D

# objective function
def objective(x, y):
	return x**2.0 + y**2.0

# 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()

         运行示例将创建目标函数的三维表面图。

python做多目标优化 python多目标优化函数_优化算法_09

          此外,该图是交互式的,这意味着您可以使用鼠标在周围的表面上拖动透视图,并从不同角度对其进行查看。

python做多目标优化 python多目标优化函数_优化算法_10