Une note sur l'implémentation de la bibliothèque qui explore les hyperparamètres à l'aide de l'optimisation bayésienne en Python

introduction

Optimisation bayésienne (Référence: Introduction to Bayesian Optimization, Introduction to Bayesian Optimization for Machine Learning En utilisant lamantin / detail / id = 59393)), il est possible que vous puissiez rechercher efficacement des hyper paramètres qui doivent être décidés par divers Try & Error pendant l'apprentissage automatique.

Je peux comprendre l'idée etc. grâce à l'augmentation de divers articles de commentaires récemment, mais je n'ai pas pu le trouver sur le Web sous la forme de la bibliothèque GridSearch, donc je l'ai fait cette fois. Je suis sûr que c'est une réinvention des roues, mais je suis heureux que la réinvention soit une expérience d'apprentissage.

Différentes versions utilisées cette fois

code

bayesian_optimizer.py


from itertools import product
from sklearn.gaussian_process import GaussianProcess

# The MIT License (C) 2016 mokemokechicken


class BayesianOptimizer:
    x_list = None
    y_list = None
    yielding_index = None
    k_band = 5
    verbose = False

    def __init__(self, params):
        self.params = params
        self.keys = []
        self.values = []
        for k, v in sorted(self.params.items()):
            self.keys.append(k)
            self.values.append(v)

    @property
    def n_pattern(self):
        return len(list(product(*self.values)))

    def output(self, *args, **kwargs):
        if self.verbose:
            print(*args, **kwargs)
    
    def supply_next_param(self, max_iter=None):
        self.x_list = []
        self.y_list = []
        all_parameters = list(product(*self.values))  # [(0.01, [0, 0], 0, [10, 10]), (0.01, [0, 0], 0, [15, 15]), ...
        index_space = [list(range(len(v))) for v in self.values]  # [[0], [0, 1, 2], [0], [0, 1, 2]]
        all_index_list = list(product(*index_space))  # [(0, 0, 0, 0), (0, 0, 0, 1), ...

        # examine 2 random points initially
        idx = list(range(len(all_index_list)))
        np.random.shuffle(idx)
        searched_index_list = []
        for index in idx[:2]:
            param = self.to_param(all_parameters[index])
            self.yielding_index = all_index_list[index]
            searched_index_list.append(index)
            yield param

        # Bayesian Optimization
        max_iter = int(min(max_iter or max(np.sqrt(self.n_pattern)*4, 20), self.n_pattern))  #Calculez le nombre maximum de recherches de manière appropriée.
        for iteration in range(max_iter):
            k = 1 + np.exp(-iteration / max_iter * 3) * self.k_band  #Réduire progressivement la valeur de k pour mettre l'accent sur la recherche → se concentrer sur l'utilisation
            gp = self.create_gp_and_fit(np.array(self.x_list), np.array(self.y_list))

            mean_array, mse_array = gp.predict(all_index_list, eval_MSE=True)
            next_index, acq_array = self.acquisition(mean_array, mse_array, k, excludes=searched_index_list)

            self.output("--- Most Expected Predictions")
            for acq, ps in sorted(zip(acq_array, all_parameters), reverse=True)[:3]:
                self.output("%.2f: %s" % (acq, list(zip(self.keys, ps))))
            self.output("--- Past Best Results")
            for acq, vs, ps in self.best_results(3):
                self.output("%.2f: %s" % (acq, list(zip(self.keys, vs))))

            if next_index in searched_index_list:
                break
            searched_index_list.append(next_index)
            self.yielding_index = all_index_list[next_index]
            yield self.to_param(all_parameters[next_index])

    @staticmethod
    def create_gp_and_fit(x, y, max_try=100):
        #Méfiant par ici
        theta0 = 0.1
        for i in range(max_try+1):
            try:
                gp = GaussianProcess(theta0=theta0)
                gp.fit(x, y)
                return gp
            except Exception as e:
                theta0 *= 10
                if i == max_try:
                    print(theta0)
                    raise e
            
    def to_param(self, row):
        return dict(zip(self.keys, row))

    def report(self, score):
        self.x_list.append(self.yielding_index)
        self.y_list.append(score)

    def best_results(self, n=5):
        index_list = []
        param_list = []
        for xs in self.x_list:
            values = [self.values[i][x] for i, x in enumerate(xs)]
            index_list.append(values)
            param_list.append(self.to_param(values))
        return sorted(zip(self.y_list, index_list, param_list), reverse=True)[:n]

    @staticmethod
    def acquisition(mean_array, mse_array, k, excludes=None):
        excludes = excludes or []
        values = mean_array + np.sqrt(mse_array) * k
        for_argmax = np.copy(values)
        for ex in excludes:
            for_argmax[ex] = -np.Inf
        return np.argmax(for_argmax), values

Comment utiliser

L'utilisation de base est la suivante.

params = {
    "parameter1": [10, 20, 25, 50],
    "parameter2": ['p1', 'p2'],
    ...
}

bo = BayesianOptimizer(params)  #Passer une combinaison de paramètres dans un dictionnaire

for param in bo.supply_next_param():  #Le paramètre qui doit être vérifié ensuite est passé par dict
    y = unknown_score_function(param)              #Évaluer le paramètre d'une manière ou d'une autre
    bo.report(y)                                    #Je vais vous dire la valeur d'évaluation

print(bo.best_results())                            #Je me souviens de la meilleure valeur de score et des paramètres

Démo dans l'espace 2D

Voici ce que j'ai essayé sur le notebook Jupyter pour voir si cela fonctionne. https://gist.github.com/mokemokechicken/7f3cf33c71d33bf0ec242c37cb3f2a75

Espace de recherche

Après avoir fait plusieurs ondulations avec sin et cos sur le plan 50 x 50 suivant, préparez un espace bidimensionnel légèrement inégal avec du bruit.

i1.png

La partie avec le point rouge (ligne = 3, col = 29) est le point avec la valeur la plus élevée.

chercher

Je vais procéder ainsi. Le nombre de recherches est de 200.

Stade précoce

Tout d'abord, j'étudie l'espace dans son ensemble. Un peu Go-like w. s1.png

Stade précoce 2

Heureusement, il semble avoir cherché plusieurs fois près de son favori au milieu. a2.png

Milieu de terrain

Le point favori a été longuement étudié. s3.png

Taille moyenne 2

Vérifiez soigneusement l'autre montagne en bas à gauche qui a l'air bien. La zone autour du favori au milieu est également couverte.

s4.png

Stade tardif

Vérifiez les espaces vides pour tout ce qui semble bon.

s5.png

État final

Il n'y a rien d'autre qui semble particulièrement bon et ça se termine. Eh bien, même si les humains le font, ça ressemble à ça. s6.png

Impressions

à la fin

Quand je le fais, il semble qu'il puisse être utilisé dans une grande variété de scènes. La vie est comme ça.

Recommended Posts

Une note sur l'implémentation de la bibliothèque qui explore les hyperparamètres à l'aide de l'optimisation bayésienne en Python
J'ai essayé d'utiliser l'optimisation bayésienne de Python
Une note utile lors de l'utilisation de Python après une longue période
Implémentation python de la classe de régression linéaire bayésienne
Ecrire un histogramme à l'échelle logarithmique sur l'axe des x en python
Utiliser l'API de recherche de la Bibliothèque du Parlement national en Python
Un mémorandum sur la mise en œuvre des recommandations en Python
[Internal_math version (2)] Décodage de la bibliothèque AtCoder ~ Implémentation en Python ~
Remarque sur le comportement par défaut de collate_fn dans PyTorch
Publication d'une bibliothèque qui masque les données de caractères dans les images Python
Une note quand j'ai touché l'API de reconnaissance faciale de Microsoft avec Python
[Note] Importation de fichiers dans le répertoire parent en Python
Essayez de créer un réseau de neurones en Python sans utiliser de bibliothèque
Contrôlez le moteur avec un pilote de moteur en utilisant python sur Raspberry Pi 3!
Jouez des sons en Python en supposant que le clavier est un clavier de piano
Utilisez networkx, une bibliothèque qui gère les graphiques en python (Partie 2: Tutoriel)
Facile! Implémenter un bot Twitter qui s'exécute sur Heroku en Python
GPyOpt, un package d'optimisation bayésienne en Python
À propos de psd-tools, une bibliothèque capable de traiter des fichiers psd en Python
Une fonction qui mesure le temps de traitement d'une méthode en python
[Ev3dev] Créez un programme qui capture LCD (écran) en utilisant python
[Python] J'ai essayé de créer un programme simple qui fonctionne sur la ligne de commande en utilisant argparse
Remarques sur l'utilisation de la saisie semi-automatique lors de l'exécution interactive de Python sous Windows
[python] Une note que j'ai commencé à comprendre le comportement de matplotlib.pyplot
Une note sur mock (bibliothèque fictive Python)
Obtenez le nombre de lecteurs d'articles sur Mendeley en Python
Essayez d'utiliser APSW, une bibliothèque Python que SQLite peut prendre au sérieux
[Édition DSU] Lecture de la bibliothèque AtCoder avec un codeur vert ~ Implémentation en Python ~
Estimer la probabilité qu'une pièce apparaisse en utilisant MCMC
Fonction Eval () qui calcule une chaîne de caractères comme expression en python
Une note sur les fonctions de la bibliothèque Linux standard qui gère le temps
Créer un enregistrement avec des pièces jointes dans KINTONE à l'aide du module de requêtes Python
Lecture de code de faker, une bibliothèque qui génère des données de test en Python
J'ai écrit FizzBuzz en python en utilisant la machine à vecteurs de support (bibliothèque LIVSVM).
[Python] Note: Fonction auto-conçue pour trouver la zone de distribution normale
Essayez d'utiliser l'API Kraken avec Python
Ecrire le test dans la docstring python
Installez la bibliothèque python sur Lambda à l'aide de [/ tmp]
Tweet à l'aide de l'API Twitter en Python
Exécuter l'interpréteur Python dans le script
Qu'est-ce que "mahjong" dans la bibliothèque Python? ??
Scraping de sites Web à l'aide de JavaScript en Python
Dessinez une structure arborescente en Python 3 à l'aide de graphviz
Un programme qui utilise Python pour lire des fichiers indésirables
Essayez d'utiliser Platypus, une bibliothèque d'optimisation polyvalente
[Python] Une barre de progression sur le terminal
[Python] Un programme qui arrondit le score
[2015/11/19] Comment enregistrer un service localement à l'aide du SDK python avec naoqi os
J'ai enregistré PyQCheck, une bibliothèque qui peut effectuer QuickCheck avec Python, dans PyPI.
J'ai essayé d'utiliser la bibliothèque Python "pykakasi" qui peut convertir des kanji en romaji.
Notez que je comprends l'algorithme des moindres carrés. Et je l'ai écrit en Python.
[Python] Un programme qui trouve les valeurs minimales et maximales sans utiliser de méthodes
[Python] Un programme qui calcule la différence entre les valeurs totales diagonales