简体   繁体   English

寻求与scipy上的optimize.fmin融合

[英]seeking convergence with optimize.fmin on scipy

I have a function I want to minimize with scipy.optimize.fmin . 我有一个我想用scipy.optimize.fmin最小化的scipy.optimize.fmin Note that I force a print when my function is evaluated. 请注意,我在评估函数时强制print

My problem is, when I start the minimization, the value printed decreases untill it reaches a certain point (the value 46700222.800). 我的问题是,当我开始最小化时,打印的值会减少,直到达到某个点(值46700222.800)。 There it continues to decrease by very small bites, eg, 46700222.797,46700222.765,46700222.745,46700222.699,46700222.688,46700222.678 So intuitively, I feel I have reached the minimum, since the length of each step are minus then 1. But the algorithm keeps running untill I get a " Maximum number of function evaluations has been exceeded " error. 在那里它继续减少非常小的比例,例如,46700222.797,46700222.765,46700222.745,46700222.699,46700222.688,46700222.678因此直观地说,我觉得我已经达到了最小值,因为每一步的长度都减去了1.但是算法一直在运行直到我得到“ Maximum number of function evaluations has been exceeded ”错误。

My question is: how can I force my algorithm to accept the value of the parameter when the function evaluation reaches a value from where it does not really evolve anymore (let say, I don't gain more than 1 after an iteration). 我的问题是:当函数求值达到一个不再真正进化的值时,如何强制我的算法接受参数的值(比方说,迭代后我的收益不会超过1)。 I read that the options ftol could be used but it has absolutely no effect on my code. 我读到可以使用选项ftol ,但它对我的代码完全没有影响。 In fact, I don't even know what value to put for ftol . 事实上,我甚至不知道为ftol什么价值。 I tried everything from 0.00001 to 10000 and there is still no convergence. 我尝试了从0.00001到10000的所有内容,但仍然没有收敛。

There is actually no need to see your code to explain what is happening. 实际上没有必要看到你的代码来解释发生了什么。 I will answer point by point quoting you. 我会一点一点地回答你。

My problem is, when I start the minimization, the value printed decreases untill it reaches a certain point (the value 46700222.800). 我的问题是,当我开始最小化时,打印的值会减少,直到达到某个点(值46700222.800)。 There it continues to decrease by very small bites, eg, 46700222.797,46700222.765,46700222.745,46700222.699,46700222.688,46700222.678 在那里它继续减少非常小的比例,例如,46700222.797,46700222.765,46700222.745,46700222.699,46700222.688,46700222.678

Notice that the difference between the last 2 values is -0.009999997913837433 , ie about 1e-2 . 请注意,最后2个值之间的差异是-0.009999997913837433 ,即大约1e-2 In the convention of minimization algorithm, what you call values is usually labelled x . 在最小化算法的约定中,您所谓的值通常标记为x The algorithm stops if these 2 conditions are respected AT THE SAME TIME at the n -th iteration: 如果在第n次迭代的同一时间遵守这两个条件,则算法停止:

  • convergence on x : the absolute value of the difference between x[n] and the next iteration x[n+1] is smaller than xtol x收敛: x[n]与下一次迭代x[n+1]之差的绝对值小于xtol
  • convergence on f(x) : the absolute value of the difference between f[n] and f[n+1] is smaller than ftol . f(x)上的收敛: f[n]f[n+1]之间的差的绝对值小于ftol

Moreover, the algorithm stops also if the maximum number of iterations is reached. 此外,如果达到最大迭代次数,算法也会停止。

Now notice that xtol defaults to a value of 1e-4 , about 100 times smaller than the value 1e-2 that appears for your case. 现在请注意, xtol默认值为1e-4 ,比您的案例中显示的值1e-2小约100倍。 The algorithm then does not stop, because the first condition on xtol is not respected, until it reaches the maximum number of iterations. 然后算法不会停止,因为xtol上的第一个条件没有得到遵守,直到达到最大迭代次数。

I read that the options ftol could be used but it has absolutely no effect on my code. 我读到可以使用选项ftol,但它对我的代码完全没有影响。 In fact, I don't even know what value to put for ftol. 事实上,我甚至不知道为ftol提供什么价值。 I tried everything from 0.00001 to 10000 and there is still no convergence. 我尝试了从0.00001到10000的所有内容,但仍然没有收敛。

This helped you respecting the second condition on ftol , but again the first condition was never reached. 这有助于你尊重ftol的第二个条件,但是从来没有达到第一个条件。

To reach your aim, increase also xtol . 为了达到你的目标,也增加xtol

The following methods will also help you more in general when debugging the convergence of an optimization routine. 在调试优化例程的收敛时,以下方法也将对您有所帮助。

  • inside the function you want to minimize, print the value of x and the value of f(x) before returning it. 在要最小化的函数内部,在返回之前打印x的值和f(x)的值。 Then run the optimization routine. 然后运行优化例程。 From these prints you can decide sensible values for xtol and ftol . 从这些打印中,您可以确定xtolftol合理值。
  • consider nondimensionalizing the problem. 考虑对问题进行无量纲化。 There is a reason if ftol and xtol default both to 1e-4 . 如果ftolxtol默认为1e-4则有一个原因。 They expect you to formulate the problem so that x and f(x) are of order O(1) or O(10) , say numbers between -100 and +100 . 他们希望你制定问题,使xf(x)的顺序为O(1)O(10) ,比如介于-100+100之间。 If you carry out the nondimensionalization you handle a simpler problem, in the way that you often know what values to expect and what tolerances you are after. 如果你执行无量纲化,你会遇到一个更简单的问题,就像你经常知道期望什么值以及你所遵循的容差一样。
  • if you are interested just in a rough calculation and can't estimate typical values for xtol and ftol , and you know (or you hope) that your problem is well behaved, ie that it will converge, you can run fmin in a try block, pass to fmin only maxiter=20 (say), and catch the error regarding the Maximum number of function evaluations has been exceeded . 如果您对粗略计算感兴趣并且无法估计xtolftol典型值,并且您知道(或者您希望)您的问题表现良好,即它会收敛,您可以在try块中运行fmin ,传递给fmin只有maxiter=20 (比如说),并且捕获了有关Maximum number of function evaluations has been exceeded的错误。

I just spent three hours digging into the source code of scipy.minimize . 我花了三个小时挖掘scipy.minimize的源代码。 In it, the "while" loop in function "_minimize_neldermead" deals with the convergence rule: 在其中,函数“_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" is the variable that stores results from functional evaluation. “fsim”是存储功能评估结果的变量。 However, I found that fsim[0] = f(x0) which is the function evaluation of the initial value, and it never changes during the "while" loop. 但是,我发现fsim [0] = f(x0)是初始值的函数评估,并且在“while”循环期间它永远不会改变。 fsim[1:] updates itself all the time. fsim [1:]一直在更新自己。 The second condition of the while loop was never satisfied. while循环的第二个条件从未得到满足。 It might be a bug. 这可能是一个错误。 But my knowledge of mathematical optimization is far from enough to judge it. 但是我对数学优化的了解还远远不足以判断它。

My current solution: design your own system to control the convergence. 我目前的解决方案:设计自己的系统来控制收敛。 Add this in your function: 在你的函数中添加:

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

Here Q=f(x). 这里Q = f(x)。 Don't forget to give them an initial value. 别忘了给他们一个初始值。

Update 01/30/15 : I got it! 2015年 1月30日更新 :我明白了! This should be the correct code for the second line of the if function (ie remove numpy.absolute): 这应该是if函数第二行的正确代码(即删除numpy.absolute):

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

btw, this is my first debugging of a open source software. 顺便说一句,这是我对开源软件的第一次调试。 I just created an issue on GitHub. 我刚刚在GitHub上创建了一个问题

Update 01/31/15 - 1 : I don't think my previous update is correct. 2015年1月31日更新 - 1 :我不认为我以前的更新是正确的。 Nevertheless, this is the a screenshot of the iterations of a function using the original code. 然而,这是使用原始代码的函数迭代的屏幕截图。 在此输入图像描述

It prints the values of sim and fsim variable for each iteration. 它为每次迭代打印sim和fsim变量的值。 As you can see, the changes of each iteration is less than both of xtol and ftol values, but it just kept going without stopping. 正如您所看到的,每次迭代的变化都小于xtol和ftol值,但它只是不停地继续运行。 The original code compares the difference between fsim[0] and the rest of fsim values, ie the value here is always 87.63228689 - 87.61312213 = .01916476, which is greater than ftol=1e-2. 原始代码比较fsim [0]和其余fsim值之间的差异,即此处的值始终为87.63228689 - 87.61312213 = .01916476,大于ftol = 1e-2。

Update 01/31/15 - 2 : Here is the data and code that I used to reproduce the previous results. 2015年1月31日更新 - 2 :这是我用来重现以前结果的数据和代码 It includes two data files and one iPython Notebook file. 它包括两个数据文件和一个iPython Notebook文件。

From the documentation it looks like you DO want to change the ftol arg. 文档中看起来你想要改变ftol arg。

Post your code so we can look at your progress. 发布您的代码,以便我们查看您的进度。 edit: Try increasing xtol as well. 编辑:尝试增加xtol

Your question is a bit ambiguous. 你的问题有点含糊不清。 Are you printing the value of your function, or the point where it is evaluated? 您是打印功能的值还是打印它的评估点?

My understanding of xtol and ftol is as follows. 我对xtolftol理解如下。 The iteration stops 迭代停止

  • when the change in the value of the function between iterations is less than ftol 当迭代之间函数值的变化小于ftol

AND

  • when the change in x between successive iterations is less than xtol 当连续迭代之间的x变化小于xtol

When you say "...accept the value of the parameter...", this suggests you should change xtol . 当你说“...接受参数的值...”时,这表明你应该改变xtol

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

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