### 在scipy.optimize.minimize中使用整数步长

我有一个计算机视觉算法,我想使用scipy.optimize.minimize来调整。我目前只想调整两个参数,但参数的数量可能会增加,所以我想使用一种能够进行高维梯度搜索的技术。SciPy中的Nelder-Mead实现似乎是一个不错的选择。

我已经设置好了代码,但看起来minimize函数非常希望使用小于1的浮点值作为步长。当前的参数集都是整数,一个参数的步长为1,另一个参数的步长为2(即该值必须是奇数,如果不是,我试图优化的对象会将其转换为奇数)。大致来说,一个参数是像素中的窗口大小,另一个参数是一个阈值(从0到255的值)。

值得一提的是,我使用的是从git仓库中新构建的scipy。有人知道如何告诉scipy为每个参数使用特定的步长吗?我是否可以自己编写梯度函数?有没有scipy的标志可以帮助我?我知道这可以通过简单的参数扫描来完成,但我最终希望将此代码应用于更大的一组参数。

代码本身非常简单:

import numpy as npfrom scipy.optimize import minimizefrom ScannerUtil import straightenImg import bsondef doSingleIteration(parameters):    # 进行一些机器视觉魔法    # 返回我的值与真实值之间的差异parameters = np.array([11,10])res = minimize( doSingleIteration, parameters, method='Nelder-Mead',options={'xtol': 1e-2, 'disp': True,'ftol':1.0,}) #不确定这些参数是否有用print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"print res

这是我的输出看起来的样子。正如你所见,我们重复了很多次运行,但在最小化方面没有取得任何进展。

*+++++++++++++++++++++++++++++++++++++++++[ 11.  10.]  <-- scipy minimize的输出{'block_size': 11, 'degree': 10} <-- 输入到我的算法中并四舍五入为整数+++++++++++++++++++++++++++++++++++++++++120  <-- 我试图最小化的函数的输出+++++++++++++++++++++++++++++++++++++++++[ 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}+++++++++++++++++++++++++++++++++++++++++120Optimization 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*

回答:

假设要最小化的函数是任意复杂的(非线性的),这通常是一个非常困难的问题。除非你尝试了所有可能的选项,否则无法保证得到最优解。我不知道是否有任何整数约束的非线性优化器(我对此有些怀疑),我假设你知道如果它是一个连续函数,Nelder-Mead应该可以很好地工作。

编辑:考虑到@Dougal的评论,我在这里补充一点:首先设置一个粗略加精细的网格搜索,如果你然后想尝试你的Nelder-Mead是否工作(并且收敛得更快),下面的几点可能会有所帮助…

但也许有些点可以帮助你:

  1. 考虑到整个整数约束非常困难,也许可以考虑做一些简单的插值来帮助优化器。它仍然应该收敛到一个整数解。当然,这需要计算额外的点,但它可能会解决许多其他问题。(据我所知,即使在线性整数规划中,通常也是先解决无约束系统)
  2. Nelder-Mead从N+1个点开始,这些点在scipy中是硬编码的(至少在旧版本中)为(1+0.05) * x0[j](对于所有维度的j,除非x0[j]为0),你会在你的第一次评估步骤中看到这些。也许在新版本中可以提供这些,否则你可以简单地更改/复制scipy代码(它是纯Python的)并将其设置为更合理的值。或者如果你觉得这样更简单,可以将所有输入变量缩小,使得(1+0.05)*x0的大小合理。
  3. 也许你应该缓存所有函数评估,因为如果你使用Nelder-Mead,我猜你总是会遇到重复评估(至少在最后)。
  4. 你必须检查Nelder-Mead是否会仅仅收缩到一个值然后放弃,因为它总是找到相同的结果。
  5. 你通常必须检查你的函数在所有情况下是否表现良好…如果函数在参数空间上不平滑变化,这个优化注定会失败,即使如此,如果你有局部最小值,它也可能很容易陷入其中。(因为你缓存了所有评估 – 见2. – 你至少可以绘制这些并查看错误景观,而无需进行任何额外的评估)

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注