繁体   English   中英

寻求与scipy上的optimize.fmin融合

[英]seeking convergence with optimize.fmin on scipy

我有一个我想用scipy.optimize.fmin最小化的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的所有内容,但仍然没有收敛。

实际上没有必要看到你的代码来解释发生了什么。 我会一点一点地回答你。

我的问题是,当我开始最小化时,打印的值会减少,直到达到某个点(值46700222.800)。 在那里它继续减少非常小的比例,例如,46700222.797,46700222.765,46700222.745,46700222.699,46700222.688,46700222.678

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

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

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

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

我读到可以使用选项ftol,但它对我的代码完全没有影响。 事实上,我甚至不知道为ftol提供什么价值。 我尝试了从0.00001到10000的所有内容,但仍然没有收敛。

这有助于你尊重ftol的第二个条件,但是从来没有达到第一个条件。

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

在调试优化例程的收敛时,以下方法也将对您有所帮助。

  • 在要最小化的函数内部,在返回之前打印x的值和f(x)的值。 然后运行优化例程。 从这些打印中,您可以确定xtolftol合理值。
  • 考虑对问题进行无量纲化。 如果ftolxtol默认为1e-4则有一个原因。 他们希望你制定问题,使xf(x)的顺序为O(1)O(10) ,比如介于-100+100之间。 如果你执行无量纲化,你会遇到一个更简单的问题,就像你经常知道期望什么值以及你所遵循的容差一样。
  • 如果您对粗略计算感兴趣并且无法估计xtolftol典型值,并且您知道(或者您希望)您的问题表现良好,即它会收敛,您可以在try块中运行fmin ,传递给fmin只有maxiter=20 (比如说),并且捕获了有关Maximum number of function evaluations has been exceeded的错误。

我花了三个小时挖掘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)

顺便说一句,这是我对开源软件的第一次调试。 我刚刚在GitHub上创建了一个问题

2015年1月31日更新 - 1 :我不认为我以前的更新是正确的。 然而,这是使用原始代码的函数迭代的屏幕截图。 在此输入图像描述

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

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

文档中看起来你想要改变ftol arg。

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

你的问题有点含糊不清。 您是打印功能的值还是打印它的评估点?

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM