scipy.optimize.minimize('SLSQP') 给定 2000 个暗淡变量时太慢

2024-01-06

我有一个带有约束和上/下界的非线性优化问题,所以使用 scipy 我必须使用 SLSQP。问题显然不是凸的。 我让雅可比函数的目标函数和约束函数都能正常工作(结果很好/快,最多 300 个输入向量)。所有功能均经过矢量化并调整为运行速度非常快。问题是使用 1000 多个输入向量需要很长时间,尽管我可以看到最小化器没有大量调用我的函数(目标/约束/梯度)并且似乎将大部分处理时间花费在内部。我在某处读到 SLSQP 的性能是 O(n^3)。

对于 python 的此类问题,是否有更好/更快的 SLSQP 实现或其他方法?我尝试了 nlopt 并以某种方式返回了错误的结果,因为它与我在 scipy 中使用的完全相同的函数(使用包装器来适应其方法签名)。我也未能将 ipopt 与 pyipopt 包一起使用,无法让 ipopt 二进制文件与 python 包装器一起使用。

更新:如果有帮助的话,我的输入变量基本上是(x,y)元组或代表坐标的二维表面中的点的向量。有了 1000 个点,我最终得到了 2000 个暗淡的输入向量。我想要优化的函数会考虑点之间的关系和其他约束来计算点之间的最佳位置。所以问题并不稀疏。

谢谢...


在我看来 scipy.minimze 提供了一个直观的优化界面。我发现加速成本函数(最终是梯度函数)可以给你带来很好的加速。

以 N 维 Rosenbrock 函数为例:

import numpy as np
from scipy.optimize import minimize


def rosenbrock(x, N):
    out = 0.0
    for i in range(N-1):
        out += 100.0 * (x[i+1] - x[i]**2)**2 + (1 - x[i])**2
    return out

# slow optimize
N = 20
x_0 = - np.ones(N)
%timeit minimize(rosenbrock, x_0, args=(N,), method='SLSQP', options={'maxiter': 1e4})
res = minimize(rosenbrock, x_0, args=(N,), method='SLSQP', options={'maxiter': 1e4})
print(res.message)

优化收益的时机

102 ms ± 1.86 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Optimization terminated successfully.

现在您可以使用以下命令加速目标函数numba http://numba.pydata.org,并提供一个简单的函数来计算梯度,如下所示:

from numba import jit, float64, int64

@jit(float64(float64[:], int64), nopython=True, parallel=True)
def fast_rosenbrock(x, N):
    out = 0.0
    for i in range(N-1):
        out += 100.0 * (x[i+1] - x[i]**2)**2 + (1 - x[i])**2
    return out


@jit(float64[:](float64[:], int64), nopython=True, parallel=True)
def fast_jac(x, N):
    h = 1e-9
    jac = np.zeros_like(x)
    f_0 = fast_rosenbrock(x, N)
    for i in range(N):
        x_d = np.copy(x)
        x_d[i] += h
        f_d = fast_rosenbrock(x_d, N)
        jac[i] = (f_d - f_0) / h
    return jac

这基本上只是向目标函数添加一个装饰器,从而允许并行计算。现在我们可以再次计时优化:

print('with fast jacobian')
%timeit minimize(fast_rosenbrock, x_0, args=(N,), method='SLSQP', options={'maxiter': 1e4}, jac=fast_jac)
print('without fast jacobian')
%timeit minimize(fast_rosenbrock, x_0, args=(N,), method='SLSQP', options={'maxiter': 1e4})
res = minimize(fast_rosenbrock, x_0, args=(N,), method='SLSQP', options={'maxiter': 1e4}, jac=fast_jac)
print(res.message)

尝试两者,提供或不提供快速雅可比函数。其输出是:

with fast jacobian
9.67 ms ± 488 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
without fast jacobian
27.2 ms ± 2.4 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Optimization terminated successfully.

只需很少的努力即可实现大约 10 倍的加速。您可以由此实现的改进在很大程度上取决于您的成本函数的低效率。我有一个包含多个计算的成本函数,并且能够获得大约 10^2 - 10^3 的加速。

这种方法的优点是它的工作量很小,并且您可以继续使用 scipy 及其漂亮的界面。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

scipy.optimize.minimize('SLSQP') 给定 2000 个暗淡变量时太慢 的相关文章

随机推荐

  • JQuery中动态元素的绑定点击事件

    我有一个 div 在通过 html 属性调用 AJAX 调用后动态填充 gallery html imagesHtml insdie imagesHtml 我有 2 个名为 pre btn 和 btn 的按钮 现在我尝试在 JQuery 中
  • VB中如何从long指定的地址获取字符串

    在vba中 有一个由long类型保存的地址 它指向一个以空结尾的字符串 但我找不到从该地址获取字符串的方法 long str address string str 您能解释一下吗 I use CopyMemory这边走 Private De
  • 为什么我的基本默认 .acceptbutton 不起作用?

    我拥有的 我有两个组框 每个组框内都有一个文本框 第三个文本框放置在两个组框的外部 按钮 1 是表单加载时的默认接受按钮 我需要的 当单击按钮 1 或按下 Enter 键 时 我需要按钮 2 成为默认接受按钮 我的问题 尽管我的代码如此 但
  • 通过 HTTP 跟踪 Web 服务器上的文本文件

    寻找有关如何解决以下问题的意见 我的 ColdFusion 9 应用程序有一个简单的记录器 可以将文本写入文件 在我的开发机器上 该文件是本地的 因此我可以使用 tail f 或 CFB 的 TailView 来观看它 我想要一个工具来在它
  • 调用函数:张量“对象”不可调用

    假设我有一个名为test如下 def test X W do stuff return stuff 我称之为使用model test X W 当我第一次调用该函数时 没有收到错误 但是 如果我再次调用该函数 则会收到错误 Tensor ob
  • 如何使用 boost::random_device 生成加密安全的 64 位整数?

    我想做这样的事情 boost random device rd boost random mt19937 64 gen rd boost random uniform int distribution
  • 使用静态数据集作为数据源

    在我的应用程序中 我有一个数据集 其中包含在我的应用程序中以不同形式使用的表 为了能够保持表单之间的并发性 并且不必每次用户打开新表单时都从数据库获取数据 我将 DataSet 作为程序类中的静态字段 如下所示 static class P
  • 在 Haskell 中创建一个列表来计算帕斯卡三角形

    我正在尝试创建一个接受整数的函数m并返回帕斯卡三角形的行数mth row 我已经构建了一个choose函数 它接受两个整数 n 和 k 并返回值 n 选择 k 例如 choose 3 2返回 3 到目前为止 我已经 pascal 0 1 p
  • 为什么饱和度和色调的最大值分别为 240 和 239?

    在 ColorDialog 中 为什么饱和度和色调的最大值分别为 240 和 239 它们对应什么 在 Windows 中 HSL 和 HSV 空间通常会重新映射到 0 到 240 之间的比例 以便可以用 32 位值表示颜色 See htt
  • 在 SVG 中缓和 animateMotion

    我想对 animateMotion 标签应用缓动 我对哪些属性与动画形状相关感到困惑 如果我理解得很好的话计算模式 样条线 是必需的 同时还需要定义keyTimes and 关键样条线 但是使用怎么样关键样条线 and values 但是
  • 如何在php中获取准确的IST时间?

    在 php 中 我使用了日期函数 例如 date Y m d h m s 它不会显示当前时间请帮助我 你想要印度时间 这是我的解决方案 您可以使用Asia Calcutta or Asia Kolkata 两者将同时返回 date defa
  • Visual Studio Code 高级搜索要包含的文件中的通配符

    我正在尝试为具有特定文件名条件的所有文件找到一行代码 我正在尝试利用高级搜索Visual Studio Code 的方法是将wildcard in the 要包含的文件搜索领域 但我没能做到这一点 我尝试使用asterisk 符号 但我认为
  • 更好的 ruby​​ markdown 解释器?

    我正在尝试找到一个可以在 rakefile 中使用的 markdown 解释器类 模块 到目前为止我已经找到了maruku http maruku rubyforge org 但我对测试版有点警惕 有人遇到过 maruku 的问题吗 或者
  • 使用 Graph API 时出现“租户 guid 的租户不存在” - 用户类型为会员的事件

    我正在尝试使用 Microsoft Graph API 访问电子邮件 当我尝试访问电子邮件时 出现以下错误 Microsoft Graph ServiceException 代码 OrganizationFromTenantGuidNotF
  • 如何确定处理器运行的字节序模式?

    如何仅使用汇编语言确定 ARM 处理器运行的字节序模式 我可以很容易地看到 Thumb ARM 状态读取 CPSR 的第 5 位 但我不知道 CPSR 或其他地方是否有对应的位用于字节序 silly example trying to ex
  • 设置 Actionbarsherlock 选项卡的样式

    因此 我尝试设置 Actionbar 选项卡的样式 这是我使用 ActionBarSherlock 库实现的 这是我的代码
  • 无法使用正确的电子邮件和姓名登录

    我正在使用 AJAX 创建登录表单 我基本上在 PHP 上工作 我对 ajax 没有太多了解 请大家帮助我解决我的疑问 当我在电子邮件 ID 和名称中输入任何值时 它就会被记录进入该页面 假设如果我给出了错误的姓名和电子邮件 那么我不会抛出
  • Java - 使用一个函数处理多个事件?

    首先 我是一个十足的Java NOOB 我想用一个函数处理多个按钮按下 并根据单击的按钮执行某些操作 我正在使用Netbeans 并且我添加了一个具有绑定功能的事件 默认情况下 该函数会发送一个 ActionEvent 如何获取单击的对象以
  • 无法从 putty 运行 .py 文件,语法错误:单词意外(需要“)”)

    我对 Python 和 Linux 都很陌生 因此要求尽可能使用最少的假设知识进行简单的解释 但是我非常愿意投入时间和精力来学习 我有一个运行 Linux 的 Raspberry Pi 2 型号 B V1 1 我通过 putty 与这个 p
  • scipy.optimize.minimize('SLSQP') 给定 2000 个暗淡变量时太慢

    我有一个带有约束和上 下界的非线性优化问题 所以使用 scipy 我必须使用 SLSQP 问题显然不是凸的 我让雅可比函数的目标函数和约束函数都能正常工作 结果很好 快 最多 300 个输入向量 所有功能均经过矢量化并调整为运行速度非常快