我应该如何优化具有边界的多变量和不可微函数?



我遇到了以下优化问题:

目标函数是一个多变量且不可微分的函数,它将标量列表作为参数并返回标量。它是不可微分的,因为函数内的计算是基于熊猫和一系列滚动、标准等动作的。

伪代码如下:

def target_function(x: list) -> float:
# calculations
return output

此外,x 参数的每个分量都有自己的边界,定义为元组(最小值、最大值(。那么我应该如何使用 scipy.optimize 库来查找此函数的全局最小值呢?还有其他图书馆可以提供帮助吗?

我已经尝试过scipy.optimize.brute,这让我永远喜欢和scipy.optimize.minimize,它从来没有产生一个看似正确的答案。

basinhoppingbrutedifferential_evolution是可用于全局优化的方法。 正如您已经发现的那样,暴力全局优化不会特别有效。

差分进化是一种随机方法,应该比蛮力更好,但可能仍然需要大量的目标函数评估。 如果你想使用它,你应该使用参数,看看什么最适合你的问题。 如果您知道目标函数不是"平滑的",这往往比其他方法更有效:函数或其导数可能存在不连续性。

另一方面,跳盆进行随机跳跃,但也在每次跳跃后使用局部放松。 如果目标函数具有许多局部最小值,但由于使用了局部松弛,则此功能非常有用,该函数应该是平滑的。 如果您不能轻松获得函数的梯度,您仍然可以尝试使用不需要此信息的本地最小化器之一进行跳盆。

scipy.optimize.basinhopping例程的优点是它非常可定制。 您可以使用take_step来定义自定义随机跳转,accept_test覆盖用于决定是继续还是放弃随机跳转和松弛结果的测试,minimizer_kwargs用于调整局部最小化行为。 例如,您可以覆盖take_step以保持在边界内,然后选择 L-BFGS-B 最小化器,它可以以数字方式估计函数的梯度以及对参数进行边界。 如果你给它一个梯度,L-BFGS-B 确实效果更好,但我在没有梯度的情况下使用它,它仍然能够很好地最小化。 请务必阅读有关局部和全局优化例程的所有参数,并在可接受的范围内调整公差等内容以提高性能。

最新更新