在scipy中优化一个不显式定义梯度的函数

1 投票
2 回答
5185 浏览
提问于 2025-05-01 14:09

我现在正在尝试用scipy来优化一个函数。我对变量有一些限制,从这个链接看:http://docs.scipy.org/doc/scipy-0.14.0/reference/tutorial/optimize.html,SLSQP正好符合我的需求。在他们的例子中,他们有一个明确的公式来表示输入和结果之间的关系,从中可以找到梯度。但是我有一个非常复杂且计算量巨大的函数,它计算电磁场如何在金属墙上反弹,这个函数无法用简单的公式表达(如果你感兴趣,我在使用MEEP FDTD Python模拟)。请问scipy中有没有类似的函数,可以帮我找到一个函数的梯度,然后进行优化?或者说,scipy中有没有其他函数(任何基本的Python库也可以)可以帮我找到一个函数的梯度,我再把这个梯度传入优化程序?任何建议都非常感谢。

暂无标签

2 个回答

0

看起来 scipy.optimize.minimize 的 SLSQP 方法并不一定需要梯度。可以看看这个开源项目,arch,在大约 738-748 行的代码中,他们使用了 SLSQP,但并没有提供梯度。就像这样:

opt = minimize(
                func,
                sv,
                args=args,
                method="SLSQP",
                bounds=bounds,
                constraints=ineq_constraints,
                tol=tol,
                callback=_callback,
                options=options,
            )

另外,在版本 1.8.0 中,下面的代码片段也能正常工作:

import scipy.optimize
res = scipy.optimize.minimize(
        lambda x: x[0]**2, [3.],
        method='SLSQP', bounds=[(1., None)])
print(res.success)  #: True

这也证明了这一点。

我没有深入研究 scipy 的代码,但我猜如果你不提供解析梯度,它会计算数值梯度。

5

因为你可能很难轻松计算梯度,所以使用一种不需要梯度的优化算法可能会更有效。下面是一些在SciPy中可用的算法概述:

http://scipy-lectures.github.io/advanced/mathematical_optimization/#gradient-less-methods

还有一种叫做“盆地跳跃”的算法,它和模拟退火有点相似,但在上面的页面没有提到:

http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.basinhopping.html

撰写回答