【发布时间】:2012-08-24 05:36:40
【问题描述】:
我想使用scipy.optimize.minimize 调整计算机视觉算法。现在我只想调整两个参数,但参数的数量最终可能会增加,所以我想使用一种可以进行高维梯度搜索的技术。 SciPy 中的 Nelder-Mead 实现似乎很合适。
我把代码都设置好了,但似乎最小化函数真的想使用步长小于 1 的浮点值。当前的参数集都是整数,一个参数的步长为 1另一个的步长为 2(即该值必须是奇数,如果不是我要优化的东西,会将其转换为奇数)。大致一个参数是以像素为单位的窗口大小,另一个参数是阈值(0-255 的值)。
值得我使用来自 git repo 的全新 scipy 版本。有谁知道如何告诉 scipy 为每个参数使用特定的步长?有什么方法可以滚动我自己的渐变函数吗?有没有可以帮助我的 scipy 标志?我知道这可以通过简单的参数扫描来完成,但我最终希望将此代码应用于更大的参数集。
代码本身非常简单:
import numpy as np
from scipy.optimize import minimize
from ScannerUtil import straightenImg
import bson
def doSingleIteration(parameters):
# do some machine vision magic
# return the difference between my value and the truth value
parameters = np.array([11,10])
res = minimize( doSingleIteration, parameters, method='Nelder-Mead',options={'xtol': 1e-2, 'disp': True,'ftol':1.0,}) #not sure if these params do anything
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
print res
这就是我的输出的样子。如您所见,我们重复了很多次运行,但在最小化过程中没有任何进展。
*+++++++++++++++++++++++++++++++++++++++++
[ 11. 10.] <-- Output from scipy minimize
{'block_size': 11, 'degree': 10} <-- input to my algorithm rounded and made int
+++++++++++++++++++++++++++++++++++++++++
120 <-- output of the function I am trying to minimize
+++++++++++++++++++++++++++++++++++++++++
[ 11.55 10. ]
{'block_size': 11, 'degree': 10}
+++++++++++++++++++++++++++++++++++++++++
120
+++++++++++++++++++++++++++++++++++++++++
[ 11. 10.5]
{'block_size': 11, 'degree': 10}
+++++++++++++++++++++++++++++++++++++++++
120
+++++++++++++++++++++++++++++++++++++++++
[ 11.55 9.5 ]
{'block_size': 11, 'degree': 9}
+++++++++++++++++++++++++++++++++++++++++
120
+++++++++++++++++++++++++++++++++++++++++
[ 11.1375 10.25 ]
{'block_size': 11, 'degree': 10}
+++++++++++++++++++++++++++++++++++++++++
120
+++++++++++++++++++++++++++++++++++++++++
[ 11.275 10. ]
{'block_size': 11, 'degree': 10}
+++++++++++++++++++++++++++++++++++++++++
120
+++++++++++++++++++++++++++++++++++++++++
[ 11. 10.25]
{'block_size': 11, 'degree': 10}
+++++++++++++++++++++++++++++++++++++++++
120
+++++++++++++++++++++++++++++++++++++++++
[ 11.275 9.75 ]
{'block_size': 11, 'degree': 9}
+++++++++++++++++++++++++++++++++++++++++
120
+++++++++++++++++++++++++++++++++++++++++
~~~
SNIP
~~~
+++++++++++++++++++++++++++++++++++++++++
[ 11. 10.0078125]
{'block_size': 11, 'degree': 10}
+++++++++++++++++++++++++++++++++++++++++
120
Optimization terminated successfully.
Current function value: 120.000000
Iterations: 7
Function evaluations: 27
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
status: 0
nfev: 27
success: True
fun: 120.0
x: array([ 11., 10.])
message: 'Optimization terminated successfully.'
nit: 7*
【问题讨论】:
-
根据文档,SciPy 的 Nelder-Mead 方法使用 Simplex 线性规划算法。它依赖于使用非整数点/步长来优化函数。我一般不熟悉 SciPy,所以可能有一个配置选项可以让它做你想做的事。您可能还想研究整数编程 (en.wikipedia.org/wiki/Integer_programming),因为这听起来像是您想要完成的工作。
-
@EricG 实际上我认为这只是一个名称混淆,Nelder-Mead “Simplex”与 Simplex 的几何结构一起使用。它与线性规划中的Simplex算法无关,无论如何这是非线性优化。
-
由于这样的问题,ML 算法的参数调整通常只通过网格搜索完成(通常在对数网格上,但您的参数似乎没有必要)。您可以先进行粗网格搜索以找到一个好的区域,然后在该区域中进行更细粒度的网格搜索。
标签: python optimization numpy machine-learning scipy