[PYTHON] Arrêtez l'optimisation avec Early Stopper de scikit-Optimize

Préface

Il y a un article la dernière fois. Optimisation Bayes très facile avec Python

Si vous pouvez continuer l'échantillonnage pendant une longue période, mais que vous voulez vous arrêter lorsqu'une certaine valeur d'évaluation est atteinte, vous devez l'arrêter avec le rappel fourni dans scikit-Optimize ou il ne s'arrêtera pas tant que le nombre d'échantillons spécifié à l'avance ne sera pas terminé. Hmm. Si vous tuez le processus, il s'arrêtera, mais vous ne pourrez pas recevoir et gérer les résultats jusqu'à ce point.

Donc, je veux utiliser scikit-Optimize.callbacks.EarlyStopper pour interrompre l'optimisation dans toutes les conditions, mais ce EarlyStopper n'est pas expliqué en détail. Il dit de le voir dans help (), mais il sort au même niveau que le lien ci-dessous.

Donc, dans cet article, je voudrais savoir comment l'utiliser en japonais.

skopt.callbacks.EarlyStopper

In [0]:from skopt.callbacks import EarlyStopper
In [1]:help(EarlyStopper)
Help on class EarlyStopper in module skopt.callbacks:

class EarlyStopper(builtins.object)
 |  Decide to continue or not given the results so far.
 |  
 |  The optimization procedure will be stopped if the callback returns True.
 |  
 |  Methods defined here:
 |  
 |  __call__(self, result)
 |      Parameters
 |      ----------
 |      result : `OptimizeResult`, scipy object
 |          The optimization as a OptimizeResult object.
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)

Code source complet

Puisqu'il est également expliqué dans Dernière fois, je vais l'expliquer en extrayant la partie modifiée.

import numpy as np
from skopt import gp_minimize
from skopt.callbacks import EarlyStopper

class Stopper(EarlyStopper):
    def __call__(self, result):
        ret = False
        if result.fun < -1.0:
            ret = True
        return ret

def func(param=None):
    ret = np.cos(param[0] + 2.34) + np.cos(param[1] - 0.78)
    return -ret

if __name__ == '__main__':
    x1 = (-np.pi, np.pi)
    x2 = (-np.pi, np.pi)
    x = (x1, x2)
    result = gp_minimize(func, x, 
                          n_calls=30,
                          noise=0.0,
                          model_queue_size=1,
                          callback=[Stopper()],
                          verbose=True)

Classe d'héritage EarlyStopper

from skopt.callbacks import EarlyStopper

class Stopper(EarlyStopper):
    def __call__(self, result):
        ret = False
        if result.fun < -1.0:
            ret = True
        return ret

D'une manière ou d'une autre, j'ai pu le prédire, mais j'ai décidé d'en hériter et de le mettre en œuvre moi-même. C'est pourquoi j'ai importé EarlyStopper et créé ma propre classe Stopper. Je ne connais pas le constructeur, mais je n'ai pas besoin de le remplacer. Tout ce que vous avez à faire est de remplacer «call». À ce stade, l'argument «résultat» est fourni dans «call», mais le dernier «résultat» est transmis à chaque fois pendant l'optimisation. Cette fois, j'ai fait référence au membre «fun» dans ce «résultat», et si cette valeur est inférieure à -1,0, elle renvoie True, sinon elle renvoie False. ** Si ce __call__ retourne True, il sera interrompu, et s'il est False, il continuera. ** **

Définir sur gp_minimize

    result = gp_minimize(func, x, 
                          n_calls=30,
                          noise=0.0,
                          model_queue_size=1,
                          callback=[Stopper()],
                          verbose=True)

Passez une instance de la classe Stopper à l'argument callback qui n'a pas été défini dans Dernière fois. À ce stade, la raison du passage dans List est qu'il est possible d'accepter plusieurs rappels. Passez ne serait-ce qu'une seule liste. A part ça, c'est la même chose que la dernière fois. Avec cela, le nombre d'échantillonnages doit être de 30 ou moins, mais bien sûr, il ne s'arrêtera pas tant qu'il n'atteindra pas le seuil de -1,0.

résultat

Iteration No: 1 started. Evaluating function at random point.
Iteration No: 1 ended. Evaluation done at random point.
Time taken: 0.0000
Function value obtained: -0.9218
Current minimum: -0.9218
Iteration No: 2 started. Evaluating function at random point.
Iteration No: 2 ended. Evaluation done at random point.
Time taken: 0.0000
Function value obtained: 0.9443
Current minimum: -0.9218
Iteration No: 3 started. Evaluating function at random point.
Iteration No: 3 ended. Evaluation done at random point.
Time taken: 0.0000
Function value obtained: 1.6801
Current minimum: -0.9218
Iteration No: 4 started. Evaluating function at random point.
Iteration No: 4 ended. Evaluation done at random point.
Time taken: 0.0000
Function value obtained: -0.0827
Current minimum: -0.9218
Iteration No: 5 started. Evaluating function at random point.
Iteration No: 5 ended. Evaluation done at random point.
Time taken: 0.0000
Function value obtained: -1.1247
Current minimum: -1.1247
Iteration No: 6 started. Evaluating function at random point.

Lors du 5ème échantillonnage, les valeurs d'évaluation étaient inférieures à -1.1247 et -1.0, alors j'ai arrêté d'essayer de faire le 6ème échantillonnage. Succès. Eh bien, je l'ai fixé à un seuil qui serait certainement attrapé ...

Serpentin

Il existe divers autres rappels disponibles dans scikit-Optimize, mais ** Early Stopper` est la seule option pour ** dans toutes les conditions **. Donc, je pense que ce «Early Stopper» est le seul qui doit probablement être hérité et implémenté par lui-même. D'autres devraient pouvoir être définis de la même manière que cette fois-ci si vous définissez les paramètres lors de la création de l'instance. Je ne l'utilise pas car il est difficile de comprendre à quoi penser ...

skopt.callbacks

Recommended Posts

Arrêtez l'optimisation avec Early Stopper de scikit-Optimize
Python en optimisation
Arrêter une instance avec une balise spécifique dans Boto3
Aménagement routier par optimisation
Introduction à l'optimisation