如何在scipy.optimize函数上强制执行更大的步骤?

时间:2013-12-09 19:25:43

标签: python optimization numpy scipy gaussian

我有一个函数compare_images(k, a, b),用于比较两个二维数组ab

在功能内部,我将gaussian_filtersigma=k一起应用于a我的想法是估计我必须平滑图像a以使其成为多少类似于图片b

问题是,我的函数compare_images只会在k变体超过0.5时返回不同的值,如果我fmin(compare_images, init_guess, (a, b),它通常会卡在init_guess上1}}值。

我认为问题是fmin(并且minimize)往往以非常小的步骤开始,在我的情况下会重现compare_images完全相同的返回值,因此方法认为它已经找到了最低限度。它只会尝试几次。

有没有办法强制fminscipy中的任何其他最小化功能采取更大的步骤?还是有更适合我需要的方法吗?

修改 我找到了临时解决方案。 首先,根据建议,我使用xtol=0.5和更高版本作为fmin的参数。 即便如此,我仍然遇到了一些问题,并且有几次fmin会返回init_guess。 然后我创建了一个简单的循环,这样如果fmin == init_guess,我会生成另一个,随机init_guess并再次尝试。

当然,这很慢,但现在我开始运行了。为我的所有数据运行它需要20个左右,但我不需要再做一次。

无论如何,为那些仍然有兴趣寻找更好解决方案的人更好地解释问题:

  • 我有2张图片AB,其中包含一些科学数据。
  • A看起来像一个带有可变值的点(它是一个矩阵,其中每个有价值的点代表事件发生的位置和强度)
  • B看起来像一个平滑的热图(它是观察到的出现密度)
  • B看起来就像是将高斯滤波器应用于A并带有一点半随机噪声。
  • 我们通过应用具有常量Bsigma的高斯滤波器来近似A。这个sigma是视觉上选择的,但仅适用于某类图像。
  • 我正在尝试为每张图片获取最佳sigma,所以稍后我会发现sigma的某些关系以及每张图片中显示的事件类别。

无论如何,谢谢你的帮助!

3 个答案:

答案 0 :(得分:4)

快速检查:您可能真的是fmin(compare_images, init_guess, (a,b))

如果gaussian_filter表现得像你说的那样,你的函数是分段常数,这意味着依赖于导数(即大多数)的优化器都不存在。您可以尝试使用anneal之类的全局优化器,或在k的合理范围内进行强力搜索。

但是,正如您所描述的那样,如果compare_imagesb的平滑版本,则通常只有a的明确全局最小值。如果您想确定a的平滑量,使两个图像最相似,那么您的方法是有意义的。

如果问题是“图像有多相似”,那么我认为像素化比较(可能有一点平滑)是要走的路。根据我们所谈论的图像,可能需要首先对齐图像(例如,用于比较照片)。请澄清: - )

修改:可能有所帮助的另一个想法:重写compare_images,以便计算两个平滑版本 - a - 一个使用sigma = floor(k),另一个使用{{ 1}}(即将k舍入到下一个较低/较高的int)。然后计算ceil(k),其中a_smooth = a_floor*(1-kfrac)+a_ceil*kfrackfrac的小数部分。这样,比较函数变为连续w.r.t k

祝你好运!

答案 1 :(得分:2)

Basin hopping可能会做得更好一些,因为它很有可能在高原停留时无论如何都会继续。

我在这个示例函数中发现它在低温下表现得相当不错:

>>> opt.basinhopping(lambda (x,y): int(0.1*x**2 + 0.1*y**2), (5,-5), T=.1)
    nfev: 409
     fun: 0
       x: array([ 1.73267813, -2.54527514])
 message: ['requested number of basinhopping iterations completed successfully']
    njev: 102
     nit: 100

答案 2 :(得分:2)

我意识到这是一个古老的问题,但是我找不到很多类似主题的讨论。我遇到scipy.optimize.least_squares的类似问题。我发现xtol对我没有多大帮助。它似乎根本没有改变步长。产生重大变化的是diff_step。这设置了根据公式step_size = x_i*diff_step对Jacobian进行数值估计时所采用的步长,其中x_i是每个自变量。您正在使用fmin,所以您没有计算雅可比行列式,但是,如果您针对同一问题使用了另一个minimize之类的scipy函数,则可能会对您有所帮助。