具有相似参数的重复一维最小化(scipy)

计算科学 优化 Python 凸优化 scipy
2021-12-06 18:36:37

我有一个函数f(x,k1,k2),我试图将它最小化为 2d 网格上的x不同值,(k1,k2)就像这样

for i,k1 in enumerate(np.logspace(-3.3,-1,20)):
    for j,k2 in enumerate(np.logspace(-3.3,-1,20)):
        if j==0:
            initial_guess = best_x_0
        else:
            initial_guess = best_x
        res = minimize(f,initial_guess,args=(k1,k2),bounds=((0.001,1),),tol=0.01,method='L-BFGS-B')

因为(k1,k2)这是一个 1d 问题,并且该函数的表现相对较好,只有 1 个最小值。但是,评估它的成本非常高,根据参数的不同,从几秒钟到大约 10 分钟不等。显然,必须有一种比将其视为许多独立的最小化问题更有效的方法来解决这个问题。如果这些点(k1,k2)足够接近,并且我已经有一个点的最小值,那么它周围的点的最小值应该不会有很大不同。

我查看了 Scipy 提供的功能,但没有找到适合此目的的任何东西。

中的函数scipy.optimize.minimize_scalar不需要初始猜测,所以我不知道如何利用 2d 网格结构。

我也遇到了'L-BFGS-B'使用scipy.optimize.minimize. 例如,使用k1=k2=0.000501187233627和它的初始猜测在 8 个函数评估中x=0.02收敛。x=0.022114610909但是,如果我使用与 相同的初始猜测k1=k2= np.logspace(-3.3,-1,20)[0] = 0.000501187233627272527534957103,那么当显然不应该有任何差异时,它会卡在x=0.01999926424执行无用的评估上,例如x=0.019966155,0.01999995105,0.0199951834.

实现这一目标的最佳方法是什么?

2个回答

一种方法是策略性地设置初始值以及评估 k1 和 k2 的网格值的顺序。特别是,您从 k1、k2 的最低和最高值的 2x2 网格开始。然后考虑,在网格值之间的中点,使用相邻网格点的 x 解的平均值作为新网格点的 initial_guess。您现在拥有 3x3 网格和解决方案。转到中点,获得 5x5 网格等。您当然需要保存所有这些解决方案,而不是其中最好的。

关于优化方法:因为你有一个一维问题,如果可能的话,我会尝试使用明确计算的一阶和二阶导数的“Newton-CG”。这通常会加速收敛。

只是一个猜测,但是对于 2 个参数的 1d 最小化,最佳拟合可能是 k1,k2 空间中的单个全局最小值,形状像一个 2d 碗(取决于函数)。如果为真,那是您唯一的本地分钟。(查找凸函数与凹函数可能会有所帮助;最大值也是负最小值。)因此,猜测参数的初始值,以便您可以在尝试另一个参数的 4 个索引值时保持一个参数不变 - 每个参数一个大方向。然后改变下一个参数,同时以相同的方式保持前一个参数不变。如果优化误差在任何方向上减小,那么您就知道这是您的最小值的方向。您可以将其放入带有 if 条件的迭代器中(如果错误增加则通过)并让它运行;您只关心存在全局最小值的最小值的子区间。您甚至可以使用每个参数波动的优化误差变化来了解截止范围。(虽然我认为其他答案中的 scipy 优化例程更方便知道如何。)