web-dev-qa-db-fra.com

scipy.optimize.fmin_l_bfgs_b renvoie 'ABNORMAL_TERMINATION_IN_LNSRCH'

J'utilise scipy.optimize.fmin_l_bfgs_b pour résoudre un problème de mélange gaussien. Les moyennes des distributions de mélanges sont modélisées par des régressions dont les poids doivent être optimisés à l'aide de l'algorithme EM.

sigma_sp_new, func_val, info_dict = fmin_l_bfgs_b(func_to_minimize, self.sigma_vector[si][pj], 
                       args=(self.w_vectors[si][pj], Y, X, E_step_results[si][pj]),
                       approx_grad=True, bounds=[(1e-8, 0.5)], factr=1e02, pgtol=1e-05, epsilon=1e-08)

Mais parfois, un avertissement 'ABNORMAL_TERMINATION_IN_LNSRCH' est apparu dans le dictionnaire d'informations: 

func_to_minimize value = 1.14462324063e-07
information dictionary: {'task': b'ABNORMAL_TERMINATION_IN_LNSRCH', 'funcalls': 147, 'grad': array([  1.77635684e-05,   2.87769808e-05,   3.51718654e-05,
         6.75015599e-06,  -4.97379915e-06,  -1.06581410e-06]), 'nit': 0, 'warnflag': 2}

RUNNING THE L-BFGS-B CODE

           * * *

Machine precision = 2.220D-16
 N =            6     M =           10
 This problem is unconstrained.

At X0         0 variables are exactly at the bounds

At iterate    0    f=  1.14462D-07    |proj g|=  3.51719D-05

           * * *

Tit   = total number of iterations
Tnf   = total number of function evaluations
Tnint = total number of segments explored during Cauchy searches
Skip  = number of BFGS updates skipped
Nact  = number of active bounds at final generalized Cauchy point
Projg = norm of the final projected gradient
F     = final function value

           * * *

   N    Tit     Tnf  Tnint  Skip  Nact     Projg        F
    6      1     21      1     0     0   3.517D-05   1.145D-07
  F =  1.144619474757747E-007

ABNORMAL_TERMINATION_IN_LNSRCH                              

 Line search cannot locate an adequate point after 20 function
  and gradient evaluations.  Previous x, f and g restored.
 Possible causes: 1 error in function or gradient evaluation;
                  2 rounding error dominate computation.

 Cauchy                time 0.000E+00 seconds.
 Subspace minimization time 0.000E+00 seconds.
 Line search           time 0.000E+00 seconds.

 Total User time 0.000E+00 seconds.

Je ne reçois pas cet avertissement à chaque fois, mais parfois. (La plupart reçoivent 'CONVERGENCE: NORM_OF_PROJECTED_GRADIENT _ <= _ PGTOL' ou 'CONVERGENCE: REL_REDUCTION_OF_F _ <= _ FACTR * EPSMCH').

Je sais que cela signifie que le minimum peut être atteint dans cette itération. J'ai googlé ce problème. Quelqu'un a dit que cela se produit souvent parce que les fonctions objectif et gradient ne correspondent pas. Mais ici, je ne fournis pas de fonction de gradient parce que j'utilise 'approx_grad'.

Quelles sont les raisons possibles pour lesquelles je devrais enquêter? Qu'est-ce que cela signifie par "erreur d'arrondi dominant le calcul"?

======

Je trouve également que le log-vraisemblance n'augmente pas de façon monotone:

########## Convergence !!! ##########
log_likelihood_history: [-28659.725891322563, 220.49993177669558, 291.3513633060345, 267.47745327823907, 265.31567762171181, 265.07311121000367, 265.04217683341682]

Il commence généralement à diminuer à la deuxième ou à la troisième itération, même si 'ABNORMAL_TERMINATION_IN_LNSRCH' ne se produit pas. Je ne sais pas si ce problème est lié au précédent.

12
Munichong

Scipy appelle l'implémentation L-BFGS-B d'origine. Ce qui est du type fortran77 (ancien mais beau et ultra-rapide) et notre problème est que la direction de la descente est en train de monter. Le problème commence à la ligne 2533 (lien vers le code en bas)

Gd = ddot(n,g,1,d,1)
  if (ifun .eq. 0) then
     gdold=Gd
     if (Gd .ge. zero) then
c                               the directional derivative >=0.
c                               Line search is impossible.
        if (iprint .ge. 0) then
            write(0,*)' ascent direction in projection Gd = ', Gd
        endif
        info = -4
        return
     endif
  endif

En d'autres termes, vous lui dites de descendre la colline en la montant. Le code essaie quelque chose qui s'appelle chercher en ligne 20 fois au total dans la direction de la descente que vous indiquez et réalise que vous ne lui dites PAS de descendre, mais de monter. Tous les 20 fois.

Le gars qui l'a écrit (Jorge Nocedal, qui est d'ailleurs un type très intelligent) a mis 20 parce que c'est à peu près suffisant. Machine epsilon est 10E-16, je pense que 20, c’est un peu trop. Donc, mon argent pour la plupart des gens ayant ce problème est que votre dégradé ne correspond pas à votre fonction .

Maintenant, il se pourrait aussi que "2. les erreurs d'arrondi dominent le calcul". Il veut dire par là que votre fonction est une surface très plate dont les augmentations sont de l’ordre de la machine epsilon (auquel cas vous pourriez peut-être redimensionner la fonction), une troisième option, quand votre fonction est trop bizarre. Oscillations? Je pouvais voir quelque chose comme $\sin ({\ frac {1} {x}}) $ causant ce genre de problème. Mais je ne suis pas un type intelligent, alors ne présumez pas qu'il y a un troisième cas.

Je pense donc que la solution du PO devrait être que votre fonction soit trop plate. Ou regardez le code fortran.

https://github.com/scipy/scipy/blob/master/scipy/optimize/lbfgsb/lbfgsb.f

Voici la recherche en ligne pour ceux qui veulent le voir. https://en.wikipedia.org/wiki/Line_search

Remarque. C'est 7 mois trop tard. Je le mets ici pour l'avenir.

47
Wilmer E. Henao

J'ai aussi eu l'erreur "ABNORMAL_TERMINATION_IN_LNSRCH" en utilisant l'optimiseur L-BFGS-B.

Tandis que ma fonction de gradient pointait dans la bonne direction, j'ai redimensionné le gradient actuel de la fonction par sa norme L2. Le supprimer ou l’ajout d’un autre type de recalage approprié a fonctionné. Auparavant, je suppose que la pente était si grande qu’elle a immédiatement dépassé les limites.

Le problème de l'OP était illimité si je lisais correctement, donc cela ne va certainement pas aider à régler ce problème. Toutefois, si vous recherchez l'erreur "ABNORMAL_TERMINATION_IN_LNSRCH" dans Google, cette page est l'un des premiers résultats. Elle pourrait donc aider les autres ...

0
gebbissimo

Comme indiqué dans la réponse de Wilmer E. Henao, le problème réside probablement dans la pente. Puisque vous utilisez approx_grad=True, le dégradé est calculé numériquement. Dans ce cas, il peut être utile de réduire la valeur de epsilon, qui est la taille de pas utilisée pour calculer numériquement le gradient.

0
toliveira