Scipy 最小化 returns 比最小值更高的值
Scipy minimize returns a higher value than minimum
作为多起点优化的一部分,我是 运行 差分进化 (DE),我将其输出作为初始值提供给 scipy 使用 SLSQP 进行最小化(我需要约束) .
我正在测试 Ackley 函数上的程序。即使在 DE returns 最佳(零)的情况下,scipy 最小化偏离最佳初始值 并且 returns 的值高于处于最佳状态。
你知道如何使 scipy 最小化 return 最优吗? 我注意到它有助于指定 scipy 最小化的公差,但它并没有完全解决问题。缩放 objective 函数会使事情变得更糟。 COBYLA 求解器不存在此问题。
优化步骤如下:
# Set up
x0min = -20
x0max = 20
xdim = 4
fun = ackley
bounds = [(x0min,x0max)] * xdim
tol = 1e-12
# Get a DE solution
result = differential_evolution(fun, bounds,
maxiter=10000,
tol=tol,
workers = 1,
init='latinhypercube')
# Initialize at DE output
x0 = result.x
# Estimate the model
r = minimize(fun, x0, method='SLSQP', tol=1e-18)
在我的例子中产生
result.fun = -4.440892098500626e-16
r.fun = 1.0008238682246429e-09
result.x = array([0., 0., 0., 0.])
r.x = array([-1.77227927e-10, -1.77062108e-10, 4.33179228e-10, -2.73031830e-12])
这里是 Ackley 函数的实现:
def ackley(x):
# Computes the value of Ackley benchmark function.
# ACKLEY accepts a matrix of size (dim,N) and returns a vetor
# FVALS of size (N,)
# Parameters
# ----------
# x : 1-D array size (dim,) or a 2-D array size (dim,N)
# Each row of the matrix represents one dimension.
# Columns have therefore the interpretation of different points at which
# the function is evaluated. N is number of points to be evaluated.
# Returns
# -------
# fvals : a scalar if x is a 1-D array or
# a 1-D array size (N,) if x is a 2-D array size (dim,N)
# in which each row contains the function value for each column of X.
n = x.shape[0]
ninverse = 1 / n
sum1 = np.sum(x**2, axis=0)
sum2 = np.sum(np.cos(2 * np.pi * x), axis=0)
fvals = (20 + np.exp(1) - (20 * np.exp(-0.2 * np.sqrt( ninverse * sum1)))
- np.exp( ninverse * sum2))
return fvals
减少 SLSQP 选项中的“用于雅可比行列式数值逼近的步长”为我解决了这个问题。
作为多起点优化的一部分,我是 运行 差分进化 (DE),我将其输出作为初始值提供给 scipy 使用 SLSQP 进行最小化(我需要约束) .
我正在测试 Ackley 函数上的程序。即使在 DE returns 最佳(零)的情况下,scipy 最小化偏离最佳初始值 并且 returns 的值高于处于最佳状态。
你知道如何使 scipy 最小化 return 最优吗? 我注意到它有助于指定 scipy 最小化的公差,但它并没有完全解决问题。缩放 objective 函数会使事情变得更糟。 COBYLA 求解器不存在此问题。
优化步骤如下:
# Set up
x0min = -20
x0max = 20
xdim = 4
fun = ackley
bounds = [(x0min,x0max)] * xdim
tol = 1e-12
# Get a DE solution
result = differential_evolution(fun, bounds,
maxiter=10000,
tol=tol,
workers = 1,
init='latinhypercube')
# Initialize at DE output
x0 = result.x
# Estimate the model
r = minimize(fun, x0, method='SLSQP', tol=1e-18)
在我的例子中产生
result.fun = -4.440892098500626e-16
r.fun = 1.0008238682246429e-09
result.x = array([0., 0., 0., 0.])
r.x = array([-1.77227927e-10, -1.77062108e-10, 4.33179228e-10, -2.73031830e-12])
这里是 Ackley 函数的实现:
def ackley(x):
# Computes the value of Ackley benchmark function.
# ACKLEY accepts a matrix of size (dim,N) and returns a vetor
# FVALS of size (N,)
# Parameters
# ----------
# x : 1-D array size (dim,) or a 2-D array size (dim,N)
# Each row of the matrix represents one dimension.
# Columns have therefore the interpretation of different points at which
# the function is evaluated. N is number of points to be evaluated.
# Returns
# -------
# fvals : a scalar if x is a 1-D array or
# a 1-D array size (N,) if x is a 2-D array size (dim,N)
# in which each row contains the function value for each column of X.
n = x.shape[0]
ninverse = 1 / n
sum1 = np.sum(x**2, axis=0)
sum2 = np.sum(np.cos(2 * np.pi * x), axis=0)
fvals = (20 + np.exp(1) - (20 * np.exp(-0.2 * np.sqrt( ninverse * sum1)))
- np.exp( ninverse * sum2))
return fvals
减少 SLSQP 选项中的“用于雅可比行列式数值逼近的步长”为我解决了这个问题。