在 scipy 上寻求与 optimize.fmin 的融合

seeking convergence with optimize.fmin on scipy

我有一个函数想用 scipy.optimize.fmin 最小化。请注意,我在计算函数时强制使用 print

我的问题是,当我开始最小化时,打印的值会减少,直到达到某个点(值 46700222.800)。在那里它继续减少非常小的咬合,例如 46700222.797,46700222.765,46700222.745,46700222.699,46700222.688,46700222.678 所以直觉上,我觉得我已经达到了最小值,因为每一步的长度都减去 1。但是算法保持 运行 直到我得到一个“Maximum number of function evaluations has been exceeded”错误。

我的问题是:当函数评估达到一个不再真正进化的值时,我如何强制我的算法接受参数值(假设,我在之后获得的收益不超过 1一次迭代)。我读到选项 ftol 可以使用,但它对我的代码绝对没有影响。事实上,我什至不知道 ftol 的值是多少。我尝试了从 0.00001 到 10000 的一切,仍然没有收敛。

documentation 看来您确实想要更改 ftol 参数。

Post 您的代码,以便我们查看您的进度。 编辑:也尝试增加 xtol

你的问题有点模棱两可。您是打印函数的值还是计算函数的点?

我对xtolftol的理解如下。迭代停止

  • 当迭代之间函数值的变化小于ftol

  • 当连续迭代之间 x 的变化小于 xtol

当您说“...接受参数的值...”时,这表明您应该更改 xtol

我刚刚花了三个小时深入研究 scipy.minimize 的源代码。其中,函数“_minimize_neldermead”中的"while"循环处理收敛规则:

if (numpy.max(numpy.ravel(numpy.abs(sim[1:] - sim[0]))) <= xtol and
               numpy.max(numpy.abs(fsim[0] - fsim[1:])) <= ftol):
    break"

"fsim" 是存储功能评估结果的变量。但是,我发现 fsim[0] = f(x0) 是初始值的函数评估,并且在 "while" 循环期间它永远不会改变。 fsim[1:] 一直在自我更新。 while 循环的第二个条件永远不会满足。这可能是一个错误。但是我的数学优化知识远远不足以判断它。

我目前的解决方案:设计自己的系统来控制收敛。将此添加到您的函数中:

global x_old, Q_old
if (np.absolute(x_old-x).sum() <= 1e-4) and (np.absolute(Q_old-Q).sum() <= 1e-4):
    return None
x_old = x; Q_old = Q

这里Q=f(x)。不要忘记给它们一个初始值。

2015 年 1 月 30 日更新: 我知道了!这应该是 if 函数第二行的正确代码(即删除 numpy.absolute):

numpy.max(fsim[0] - fsim[1:]) <= ftol)

btw,这是我第一次调试开源软件。我刚刚在 GitHub 上创建了一个 issue

2015 年 1 月 31 日更新 - 1: 我认为我之前的更新不正确。尽管如此,这是使用原始代码迭代函数的屏幕截图。

它为每次迭代打印 sim 和 fsim 变量的值。正如您所看到的,每次迭代的变化都小于 xtol 和 ftol 值,但它一直在继续,没有停止。原始代码比较 fsim[0] 与其余 fsim 值之间的差异,即此处的值始终为 87.63228689 - 87.61312213 = .01916476,大于 ftol=1e-2。

2015 年 1 月 31 日更新 - 2: 这是我用来重现以前结果的 data and code。它包括两个数据文件和一个 iPython 笔记本文件。

实际上不需要看你的代码来解释发生了什么。我会引用你的话逐条回答。

My problem is, when I start the minimization, the value printed decreases untill it reaches a certain point (the value 46700222.800). There it continues to decrease by very small bites, e.g., 46700222.797,46700222.765,46700222.745,46700222.699,46700222.688,46700222.678

请注意,最后两个值之间的差异是 -0.009999997913837433,即大约 1e-2。在最小化算法的约定中,你所说的值通常被标记为x。如果在第 n 次迭代中同时满足这两个条件,算法将停止:

  • 收敛于xx[n]与下一次迭代x[n+1]的差值绝对值小于xtol
  • 收敛于f(x)f[n]f[n+1]的差值绝对值小于ftol.

此外,如果达到最大迭代次数,算法也会停止。

现在请注意,xtol 默认值为 1e-4,比您的案例显示的值 1e-2100 倍。然后算法不会停止,因为 xtol 上的第一个条件没有得到遵守,直到达到最大迭代次数。

I read that the options ftol could be used but it has absolutely no effect on my code. In fact, I don't even know what value to put for ftol. I tried everything from 0.00001 to 10000 and there is still no convergence.

这帮助您满足 ftol 上的第二个条件,但同样从未达到第一个条件。

为了达到你的目标,还要增加 xtol

在调试优化例程的收敛性时,以下方法也将在一般情况下为您提供更多帮助。

  • 在你想要最小化的函数中,在返回之前打印x的值和f(x)的值。然后 运行 优化例程。从这些印刷品中,您可以确定 xtolftol.
  • 的合理值
  • 考虑将问题无量纲化。 ftolxtol 都默认为 1e-4 是有原因的。他们希望您制定问题,使 xf(x) 的顺序为 O(1)O(10),比如 -100+100 之间的数字。如果您执行无量纲化,您会处理一个更简单的问题,因为您通常知道期望值是什么以及您所追求的公差是多少。
  • 如果您只对粗略计算感兴趣而无法估计 xtolftol 的典型值,并且您知道(或希望)您的问题表现良好,即它会收敛,你可以 运行 fmintry 块中,仅传递给 fmin maxiter=20 (例如),并捕获有关 Maximum number of function evaluations has been exceeded.