Optimisation bayésienne très simple avec Python

2020.09.22 J'ai écrit un article qui suit cet article. Abandonner l'optimisation avec Early Stopper de scikit-Optimize

Préface

Étant donné que j'optimise parfois les paramètres au travail et que je reçois souvent des consultations sur des problèmes d'optimisation au travail, je vais résumer gp_minimize de scikit-Optimize, qui peut effectuer une optimisation bayésienne très facilement. Je le pense.

scikit-optimize.gp_minimize

Installation

Installation facile avec pip

pip install scikit-optimize

Code source complet

Le texte intégral de ce code source. Ici, seuls les points clés, il y a en fait des codes de dessin.

import numpy as np
from skopt import gp_minimize

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,
                          verbose=True)

Autour de l'importation

import numpy as np
from skopt import gp_minimize

Seulement numpy et gp_minimize. S'il est détourné, changez-le si nécessaire.

Fonction d'optimisation

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

Cette fois, le problème était de recevoir deux entrées et de trouver la valeur d'entrée qui maximise la somme de chaque valeur de fonction cosinus. Parce que c'est facile à comprendre. Cependant, comme c'était trop maladroit, j'ai ajouté un décalage (0,34, -0,78) à la valeur d'entrée. Si ce décalage est finalement décalé (-0,34, 0,78), on peut dire que l'optimisation est réussie.

Comme le nom gp_minimize le suggère, il ne peut être minimisé **, donc la valeur de retour est définie sur une valeur négative en ajoutant-pour maximiser la minimisation.

Paramètres de l'espace de recherche

    x1 = (-np.pi, np.pi)
    x2 = (-np.pi, np.pi)
    x = (x1, x2)

Puisque nous savons que c'est une fonction cosinus cette fois, l'espace des deux variables d'entrée est le même, et la plage que (-π à π) peut prendre. Puisqu'il est nécessaire de spécifier le minimum et le maximum qui peuvent être pris pour chaque variable avec List ou Tuple, et enfin les passer ensemble à une List ou Tuple, ils sont combinés en un à la fin.

optimisation

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

Avec cela seul, l'échantillonnage commence. Pour l'instant, seuls les paramètres susceptibles d'être utilisés sont spécifiés cette fois.

Les premiers func et x spécifient la fonction d'optimisation et l'espace de recherche. n_calls est le nombre d'échantillons. Si «noise» n'est pas spécifié, le bruit de la distribution gaussienne sera recherché, changez-le si nécessaire. Cette fois, il est évalué à 0,0 sans bruit. model_queue_size is gp_minimize utilise GaussianProcessRegressor of scikit-learn pour prédire la valeur d'évaluation de l'espace et rechercher le prochain point d'échantillonnage, donc le nombre pour contenir une instance de GaussianProcessRegressor à chaque fois. .. Si vous ne le spécifiez pas, tout sera laissé, donc cela consommera de plus en plus de mémoire. Cette fois, j'ai spécifié 1 pour ne garder que la dernière version. verbose n'a qu'une sortie standard pendant l'échantillonnage. Si False est spécifié, rien ne sera généré.

Le résultat de cette optimisation est renvoyé dans "result".

À propos du contenu du résultat

Si vous faites référence au contenu avec la fonction dir, les membres suivants existent.

In [1]:dir(result)
Out[1]: 
['fun',
 'func_vals',
 'models',
 'random_state',
 'space',
 'specs',
 'x',
 'x_iters']

En général, l'interprétation suivante semble suffisante.

membre valeur Interprétation
fun -1.9999999997437237 Meilleure valeur d'évaluation lors de l'optimisation
func_vals array([ 0.72436992, -0.2934671 ,・ ・ ・ ・ ・ ・ ・-1.99988708, -1.99654543]) Valeur de retour (valeur d'évaluation) de la fonction à chaque fois pendant l'optimisation
models list(GaussianProcessRegressor) Conservé comme expliqué ci-dessusGaussianProcessRegressorListe des instances de
random_state RandomState(MT19937) at 0x22023222268 Graine aléatoire
space Space([
Real(low=-3.141592653589793, high=3.141592653589793, prior='uniform', transform='normalize'),
Real(low=-3.141592653589793, high=3.141592653589793, prior='uniform', transform='normalize')])
Objets spatiaux d'exploration
specs (Omis car il y en a beaucoup)
Contient un dictionnaire
Il semble que les spécifications d'optimisation soient incluses ensemble
x [-2.3399919472084387, 0.7798573940377893] Valeur de la variable d'entrée optimisée
x_iters (Omis car il y en a beaucoup)
List
Contient la valeur échantillonnée à chaque fois

Résumé des résultats

Enfin, collez celui tracé en utilisant la valeur contenue dans result. C'est un peu difficile à voir, mais la figure de gauche est la carte de chaleur réelle, l'axe vertical est x1 et l'axe horizontal est x2, donc l'axe vertical est en bas et l'axe horizontal est légèrement à droite (valeur minimale ( Puisque le positif et le négatif sont inversés, il y a en fait la valeur maximale).

La figure de droite est le résultat de l'optimisation, mais la couleur de la carte thermique elle-même est également faite avec la valeur prédite de GaussianProcessRegressor. En échantillonnant 30 fois, il était possible de créer quelque chose qui était presque identique à l'espace réel, et la valeur optimale pouvait également être obtenue. Le marqueur ○ est un point d'échantillonnage pour chaque temps, ce qui est difficile à comprendre, mais il semble que les bords sont échantillonnés et que la zone proche de la valeur minimale est focalisée après que l'espace puisse être prédit dans une certaine mesure. La valeur optimale pour laquelle le marqueur ☆ a finalement été trouvé. Figure_1.png

Comment utiliser le rappel

Bien qu'il existe peu d'articles sur l'utilisation de scikit-Optimize, j'ai écrit ceci cette fois parce que je n'ai trouvé aucun article japonais expliquant comment utiliser Callback. Donc, je vais écrire un article séparé sur la façon d'utiliser Callback et mettre un lien ici.

2020.09.22 Je l'ai écrit. Abandonner l'optimisation avec Early Stopper de scikit-Optimize

Recommended Posts

Optimisation bayésienne très simple avec Python
[Analyse de co-occurrence] Analyse de co-occurrence facile avec Python! [Python]
Compilation facile de Python avec NUITKA-Utilities
Serveur HTTP facile avec Python
[Python] Estimation bayésienne avec Pyro
Ajuster les hyper paramètres avec l'optimisation bayésienne
[Python] Traitement parallèle facile avec Joblib
GPyOpt, un package d'optimisation bayésienne en Python
Programmation facile Python + OpenCV avec Canopy
Transmission de courrier facile avec Hâte Python3
Visualisez facilement vos données avec Python seaborn.
Exécution parallèle facile avec le sous-processus python
Extraction de mots-clés facile avec TermExtract pour Python
[Python] Test super facile avec instruction assert
[Python] Vérification simple du type d'argument avec la classe de données
Introduction facile de la reconnaissance vocale avec Python
J'ai essayé d'utiliser l'optimisation bayésienne de Python
[Easy Python] Lecture de fichiers Excel avec openpyxl
Application Web facile avec Python + Flask + Heroku
Traitez facilement des images en Python avec Pillow
[Easy Python] Lecture de fichiers Excel avec des pandas
Scraping Web facile avec Python et Ruby
[Python] Essayez facilement l'apprentissage amélioré (DQN) avec Keras-RL
FizzBuzz en Python3
Grattage avec Python
Python est facile
Statistiques avec python
Grattage avec Python
Python avec Go
Intégrer avec Python
AES256 avec python
Testé avec Python
python commence par ()
avec syntaxe (Python)
Bingo avec python
Zundokokiyoshi avec python
Excel avec Python
Micro-ordinateur avec Python
Cast avec python
[Python] Introduction facile à l'apprentissage automatique avec python (SVM)
Sortie CSV de la recherche Google avec [Python]! 【Facile】
Optimisation de portefeuille avec Python (modèle de distribution moyenne de Markovitz)
Analyse de régression LASSO facile avec Python (pas de théorie)
✨ Facile avec Python ☆ Temps écoulé estimé après la mort ✨
Communication série avec Python
Zip, décompressez avec python
Jugement des nombres premiers avec Python
Python avec eclipse + PyDev.
Communication de socket avec Python
Analyse de données avec python 2
Easy Grad-CAM avec pytorch-gradcam
Grattage en Python (préparation)
Essayez de gratter avec Python.
Recherche séquentielle avec Python
"Orienté objet" appris avec python
Exécutez Python avec VBA
Résolvez AtCoder 167 avec python
Communication série avec python
[Python] Utiliser JSON avec Python