2012-03-20 33 views
2

我试图使用SciPy的内尔德-Mead单纯的搜索功能找到一个最小的非线性函数。看起来我的单形是卡住的,因为它起始于一个最初的单形太小。不幸的是,我没有在scipy中看到任何地方可以改变一些单形参数(例如最初的单形大小)。有没有办法?我错过了什么吗?或者NM单工的其他实现?SciPy的优化 - FMIN内尔德-Mead单纯

由于

+0

通过“卡住”你的意思,你已经找到了一个当地的最低? – Bort 2012-03-20 14:48:33

+1

尝试x0的其他初始条件,例如随机数在适当的范围内,找到其他最小值 – Bort 2012-03-20 14:55:23

+0

我的意思是卡住,因为它总是返回到我给它的初始值。很可能是因为它搜索的本地空间没有任何价值变化 – tomas 2012-03-20 14:58:41

回答

1

从参考在http://docs.scipy.org/doc/

方法内尔德-米德采用单纯形算法[R123],[R124]。该算法在许多应用中已经成功,但是使用一阶和/或二阶导数信息的其他算法可能因其更好的性能和一般的鲁棒性而被优选。

可推荐使用完全不同的算法,然后。请注意:

方法BFGS使用Broyden,Fletcher,Goldfarb和Shanno(BFGS)的准牛顿法[R127]第136页。它仅使用一阶导数。即使对于不平滑的优化,BFGS也证明了良好的性能。此方法还返回Hessian逆的近似值,作为hess_inv存储在OptimizeResult对象中。

BFGS听起来更强大,更快的整体。

为内尔德 - 米德ParagonRG

+0

呃...谢谢。我也尝试BFGS方法。不幸的是,它使用了一阶导数,必须使用一阶差分来估计我的函数。所以不知道它会更好。这可能是肯定的。 – tomas 2012-03-20 14:46:50

2

两个建议:

1)管理所有x到网格,说.01,内部功能:

x = np.round(x/grid) * grid 
f = ... 

这可以作为一个简单的噪声高维过滤 (在2D或3D,不要打扰)。

2)最好的d + 1的2D + 1个附近的点开始, 而不是通常的d + 1:

def neard1(func, x, h, verbose=1): 
    """ eval func at 2d+1 points x, x +- h 
     sort 
     -> f[ d+1 best values ], X[ d+1 ] 
     to start or restart Nelder-Mead 
    """ 
    dim = len(x) 
    I = np.eye(dim) 
    np.fill_diagonal(I, h) # scalar or vec 
    X = x + np.vstack((np.zeros(dim), I, - I)) 
    fnear = np.array([ func(x) for x in X ]) # 2d+1 
    f0 = fnear[0] 
    up = np.argsort(fnear) # vec func: |fnear| 
    if verbose: 
     print "neard1: f %g +- %s around x %s" % ( 
      f0, fnear[up] - f0, x) 
    bestd1 = up[:dim+1] 
    return fnear[bestd1], X[bestd1] 

这也是个不错的主意,看看neard1() Nelder-Mead之后的值, 以了解func()的外观。
如果任何邻居都比N-M“最好”更好,那么从该新单例重新启动N-M。 (可以交替使用neard1,N-M,neard1,N-M:简单但是非常依赖于问题。)

你有多少个变量,以及你的函数有多嘈杂?

希望这会有帮助