Python scipy.optimize.basinhopping不';t调用accept_测试。为什么?

Python scipy.optimize.basinhopping不';t调用accept_测试。为什么?,python,scipy,mathematical-optimization,Python,Scipy,Mathematical Optimization,我正在尝试使用scipy算法优化函数的输出 def acceptance_criteria(self,**kwargs): print "kwargs " print kwargs x = kwargs["x_new"] beta = x[0] alpha = [x[1],x[2],x[3],x[4],x[5],x[6]] print x inputnow= raw_input() beta_gamma_pass = beta

我正在尝试使用scipy算法优化函数的输出

def acceptance_criteria(self,**kwargs): 
    print "kwargs "
    print kwargs

    x = kwargs["x_new"]
    beta = x[0]
    alpha = [x[1],x[2],x[3],x[4],x[5],x[6]]
    print x
    inputnow= raw_input()
    beta_gamma_pass = beta != self.gamma
    beta_zero_pass = beta >= 0.0
    alpha1_pass = alpha[0] > 0.0
    alpha2_pass = alpha[1] > 0.0
    alpha3_pass = alpha[2] > 0.0
    alpha4_pass= alpha[3] > 0.0
    alpha5_pass= alpha[4] > 0.0
    alpha6_pass= alpha[5] > 0.0
    return  beta_gamma_pass,beta_zero_pass,alpha1_pass,alpha2_pass,alpha3_pass,alpha4_pass,alpha5_pass,alpha6_pass

def variational_calculation(self):
    minimizer_kwargs = {"method": "BFGS"}

    initial_paramater_guesses = [2,1.0,1.0/2.0,1.0/3.0,1.0/4.0,1.0/5.0,1.0/6.0]
    ret = basinhopping(self.Calculate, initial_paramater_guesses, minimizer_kwargs=minimizer_kwargs, niter=200, accept_test=self.acceptance_criteria)
我的计算函数中的Nans和infs出现问题。 这是由于使用了无效的参数值。 我试图通过使用验收标准来防止这种情况。 但是basinhopping例程不调用accept_test函数。 因此,这些标准仍然没有得到执行

有人能帮我解释一下为什么basinhopping没有调用accept\u测试函数吗

谢谢

编辑: 针对@sascha的评论, 函数中有参数的分数次幂和1/参数项。 在这种情况下,不限制允许的参数值的范围会给出复杂的inf值。 这实际上是一个特征值问题,我试图最小化一组18*18矩阵的特征值轨迹。 矩阵元素以一种复杂的方式依赖于7个参数,包含数十个非线性项

我以前从未做过比多项式回归更复杂的工作,所以我对算法或它们的适用性一点也不熟悉。 但是,我尝试最小化的函数是平滑的,只要您避免靠近极点的参数值;由1/参数和1/(参数^n-常数)项引起

编辑2: 问题澄清 这里的问题与basinhopping算法的适用性无关

def acceptance_criteria(self,**kwargs): 
    print "kwargs "
    print kwargs

    x = kwargs["x_new"]
    beta = x[0]
    alpha = [x[1],x[2],x[3],x[4],x[5],x[6]]
    print x
    inputnow= raw_input()
    beta_gamma_pass = beta != self.gamma
    beta_zero_pass = beta >= 0.0
    alpha1_pass = alpha[0] > 0.0
    alpha2_pass = alpha[1] > 0.0
    alpha3_pass = alpha[2] > 0.0
    alpha4_pass= alpha[3] > 0.0
    alpha5_pass= alpha[4] > 0.0
    alpha6_pass= alpha[5] > 0.0
    return  beta_gamma_pass,beta_zero_pass,alpha1_pass,alpha2_pass,alpha3_pass,alpha4_pass,alpha5_pass,alpha6_pass

def variational_calculation(self):
    minimizer_kwargs = {"method": "BFGS"}

    initial_paramater_guesses = [2,1.0,1.0/2.0,1.0/3.0,1.0/4.0,1.0/5.0,1.0/6.0]
    ret = basinhopping(self.Calculate, initial_paramater_guesses, minimizer_kwargs=minimizer_kwargs, niter=200, accept_test=self.acceptance_criteria)

这就是为什么在python和scipy的2.7版本中,它的具体实现不调用accept_test函数的原因?

我不能说为什么您的示例不起作用,但这里有一个类似但最小的示例,它调用accept_test,也许您可以看出区别

import scipy
import numpy as np
from scipy.optimize import basinhopping

class MyClass:
    def Calculate(self, x):
        return np.dot(x, x)

    def acceptance_criteria(self, **kwargs):
        print("in accept test")
        return True

    def run(self):
        minimizer_kwargs = {"method": "BFGS"}

        initial_paramater_guesses = [2,1.0,1.0/2.0,1.0/3.0,1.0/4.0,1.0/5.0,1.0/6.0]
        ret = basinhopping(self.Calculate,
                           initial_paramater_guesses,
                           minimizer_kwargs=minimizer_kwargs,
                           niter=200,
                           accept_test=self.acceptance_criteria)

my_class = MyClass()
my_class = my_class.run()

我知道这篇文章很老了,但它仍然出现在谷歌搜索这个问题上

我也遇到了同样的问题,所以我通过稍微修改这里的代码并添加一个计数器来运行测试。我的代码最小化了5个变量,但要求所有值都大于0.5

import numpy as np
from scipy.optimize import basinhopping
n = 0

def acceptance_criteria(**kwargs):
    print("in accept test")
    X = kwargs['x_new']
    for x in X:
        if x < .5:
            print('False!')
            return False
    return True

def f(x):
    global n
    print(n)
    n += 1
    return (x[0]**2-np.sin(x[1])*4+np.cos(x[2]**2)+np.sin(x[3]*5.0)-(x[4]**2 -3*x[4]**3))**2

if __name__ == '__main__':
    res = basinhopping(f,[.5]*5,accept_test=acceptance_criteria)
将numpy导入为np
从scipy.optimize导入basinhopping
n=0
def验收标准(**kwargs):
打印(“接受测试中”)
X=kwargs['X_new']
对于x中的x:
如果x小于0.5:
打印('False!')
返回错误
返回真值
def f(x):
全球n
打印(n)
n+=1
返回(x[0]**2-np.sin(x[1])*4+np.cos(x[2]**2)+np.sin(x[3]*5.0)-(x[4]**2-3*x[4]**3))**2
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
res=基本要求(f,[5]*5,验收试验=验收标准)
在进入acceptance_criteria函数之前,需要大约100次迭代


如果您正在优化一个需要很长时间才能运行的函数(就像我一样),那么您可能只需要给它更多的时间来进入验收测试。

可能是因为它以前坏了?您的函数是否符合此算法的有效函数?如果有nan和inf,我想它是非光滑的?贝辛霍普不是为这个而建的!你说“以前坏过”是什么意思?我不确定,你的错误到底是什么。你说,某个回调没有被调用。我不知道在调用此回调之前,您的算法是否以某种错误状态终止。这就是我想说的。另外:
但是,只要避免极点附近的参数值,我尝试最小化的函数是平滑的;
听起来非常不平滑:-)。我对特征值问题不太熟悉,但其中一些是数值问题的麻烦。我认为您应该首先使用一些更简单的局部优化器,并检查这些优化器是否正常工作问题是basinhopping根本不调用accept_测试函数。可以进行多次迭代,然后选择需要避免的参数值。尽管accept_test函数会为这些值返回False,但还是选择了它们。然后遇到非有效值。如果basinhopping为参数运行accept_test函数,然后仅在参数有效时才继续,那么就不会有问题。未调用accept_test函数,尽管已指定它应该这样做。要使用的
accept_test
用作某种Metropolis标准。即使您的实现将调用此函数(拒绝无效值),也可能会导致失去basinhopping算法的所有理论保证。再次强调:它是为平滑功能而设计的。