2016-10-10 6 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 в моей функции вычисления. Это связано с неправильными значениями параметров, которые используются. Я попытался предотвратить это, используя критерии приемки. Но процедура basinhopping не вызывает функцию accept_test. Таким образом, критерии остаются незавершенными.

Может ли кто-нибудь помочь мне в том, почему basinhopping не вызывает функцию accept_test?

Благодаря

EDIT: в ответ на @ Sascha замечание, Есть дробные степени параметров и 1 члены/параметров в функции. Не ограничивая диапазон допустимых значений параметров, в этом случае приводятся комплексные значения и значения inf. Фактически это проблема с собственным значением, где я пытаюсь минимизировать след собственных значений набора из 18 * 18 матриц. Матричные элементы комплексно связаны с 7 параметрами с десятками нелинейных членов.

Я никогда не работал над чем-то более сложным, чем полиномиальная регрессия, поэтому я не знаком с алгоритмами или их применимостью вообще. Однако функция/s, которую я пытаюсь свести к минимуму, является гладкой, если вы избегаете значений параметров вблизи полюсов; вызванных 1/параметром и 1/(параметром^n-констант).

EDIT2: ВОПРОС О ЗАЯВЛЕНИИ Вопрос здесь не имеет ничего общего с применимостью алгоритма basinhopping.

Именно поэтому конкретная реализация его в версии версии python и scipy версии 2.7 не вызывает функцию accept_test?

+1

Возможно, потому что он сломан раньше? Является ли ваша функция квалифицированной как действительная функция для этого алгоритма? Если есть nan и inf, я полагаю, что он негладкий? Basinhopping для этого не построен! – sascha

+0

Что значит «сломанный раньше»? –

+0

Я не был уверен, что именно ваша ошибка. Вы сказали, что некоторая обратная связь не называется. Я не знаю, заканчивается ли ваш алгоритм с некоторым состоянием ошибки перед вызовом этого обратного вызова или нет. Это я и собирался сказать.Кроме того: '' 'Тем не менее, функция/s, которую я пытаюсь свести к минимуму, является гладкой, если вы избегаете значения параметров возле полюсов'', звучит довольно негладко для меня :-). Я не знаком с проблемами собственных значений, но некоторые из них связаны с численными проблемами. Я думаю, вы должны сначала придерживаться более простого локального оптимизатора и проверить, правильно ли они работают. – 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

Я знаю, что этот пост старый , но он по-прежнему обнаруживает этот вопрос в Googling.

У меня была такая же проблема, поэтому я проверил тест, немного изменив код и добавив счетчик. Мой код минимизирует 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.

Если вы оптимизируете функцию, которая требует много времени для запуска (как и я), вам просто нужно дать ей больше времени для входа в accept_test.