2016-10-10 31 views
2

我試圖優化使用scipy basinhopping算法的函數的輸出。scipy.optimize.basinhopping不會調用accept_test。爲什麼?

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的問題。 這是由於使用的參數值無效。 我試圖通過使用驗收標準來防止這種情況。 但流域購買例程不會調用accept_test函數。 因此,標準保持不變。

任何人都可以幫我解釋爲什麼流域購買不會調用accept_test函數嗎?

感謝

編輯: 響應@薩沙的評論, 有參數的分數冪,並且在功能1 /參數方面。 在這種情況下,不限制允許參數值的範圍會給出複數和inf值。 它實際上是一個特徵值問題,我試圖最小化一組18 * 18矩陣的特徵值的軌跡。 矩陣元素以複雜的方式依賴於7個參數,並帶有數十個非線性項。

我從來沒有做過比多項式迴歸更復雜的任何事情,所以我不熟悉算法或它們的適用性。 但是,只要避免極點附近的參數值,我試圖最小化的函數是平滑的;由1 /參數和1 /(參數n常數)項引起。

EDIT2: 問題澄清 這裏的問題與流域購物算法的適用性無關。

這就是爲什麼它的具體實現,在Python版本的Python和scipy,沒有調用accept_test函數?

+1

也許是因爲它之前破了?您的函數是否符合此算法的有效函數?如果有nan和inf,我想它是不光滑的?盆地購物不是爲此而建! – sascha

+0

你是什麼意思「之前破碎」? –

+0

我不確定,你的錯誤是什麼。你說過,一些回調沒有被調用。我不知道在調用這個回調之前,你的算法是否以某種錯誤狀態結束。這就是我想說的。另外:'''然而,我試圖最小化的函數是平滑的,只要你避免極點附近的參數值對我來說聽起來很不光滑:-)。我不熟悉特徵值問題,但其中一些問題在數值問題方面很麻煩。我認爲你應該堅持一些更簡單的本地優化器,並檢查它們是否正常工作 – sascha

回答

1

我不能說,爲什麼你的例子不工作,但這裏有一個類似的,但最小的例子,其中它調用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() 
1

我知道這個帖子是老,但它仍然出現在谷歌搜索這個問題上。

我遇到了同樣的問題,所以我通過在這裏修改代碼並添加一個計數器來運行測試。我的代碼減少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) 

花了大約100次迭代進入acceptance_criteria功能之前。

如果您正在優化需要很長時間才能運行的函數(因爲我是),那麼您可能只需要給它更多的時間來進入acceptance_test。

相關問題