L'optimisation bayésienne est une méthode d'optimisation de certaines fonctions à l'aide d'une méthode d'apprentissage automatique appelée processus gaussien, qui effectue une régression du noyau bayésien. Les avantages de cette optimisation bayésienne sont divers, par exemple, elle peut être appliquée à des fonctions dont les entrées ne sont pas continues (non différentiables), et elle est forte pour les fonctions avec des solutions locales. En raison de ces mérites, on considère qu'il peut être appliqué à divers problèmes à l'avenir. Ici, nous expliquerons comment utiliser GPyOpt, qui est un package qui effectue une optimisation bayésienne en Python.
Utilisez anaconda comme environnement. Vous avez besoin des derniers packages scipy et GPy (processus gaussien).
$ conda update scipy
$ pip install GPy
$ pip install gpyopt
Tout d'abord, optimisons une fonction non linéaire dont l'entrée est unidimensionnelle. Cette fois, nous minimiserons la fonction de $ f (x) = \ cos (1,5x) + 0,1x $ dans la plage de $ 0 \ leq x \ leq 10 $.
L'optimisation bayésienne échantillonne d'abord au hasard certaines entrées dans une plage donnée. Ensuite, passez l'échantillon d'entrée à travers la fonction et récupérez l'échantillon de sortie. Ensuite, en utilisant cet échantillon, nous effectuons une régression dans le processus gaussien. Dans cette figure, le vert est la fonction que vous souhaitez optimiser et le bleu est la fonction qui se répète dans le processus gaussien. 
Voyons maintenant où la fonction est minimisée. Ce que nous faisons est de déterminer le plus petit x et de trouver le y, et ainsi de suite. Il existe différents critères pour savoir où x est susceptible d'être le minimum, mais cette fois, x qui s'étend jusqu'au plus petit y dans la zone bleue de cette figure est défini sur x qui est probablement le minimum. Je vais. Cette zone bleue est la zone susceptible de contenir une ligne verte étant donné uniquement les données des points rouges.
Maintenant, échantillonnons-en un par cette méthode. Après en avoir échantillonné un, l'important est que la zone bleue change. Ensuite, dans cet état, en effectuant un échantillonnage → mise à jour de la zone bleue → échantillonnage → mise à jour de la zone bleue → ..., il sera possible de trouver x qui sera le minimum de $ f (x) $.
Ensuite, la figure après un certain échantillonnage est affichée. Un grand nombre d'échantillons sont en fait échantillonnés autour de $ x = 2 $, et la solution optimale est celle où $ f (x) $ est en fait minimisé dans cet échantillonnage.
Faisons-le avec GPyOpt.
Tout d'abord, importez.
import GPy
import GPyOpt
import numpy as np
Définissez ensuite la fonction que vous souhaitez optimiser. Ici, vous pouvez spécifier la fonction numpy.
def f(x):
'''
Fonction non linéaire à optimiser cette fois
'''
return np.cos(1.5*x) + 0.1*x
Maintenant, définissons d'abord la zone de définition de x. 'type': 'continu' indique qu'il est continu, et 'domain': (0,10) indique qu'il est $ 0 \ leq x \ leq 10 $. La deuxième ligne obtient l'objet pour l'optimisation bayésienne. f est la fonction que vous souhaitez optimiser, domain est la zone de définition définie précédemment et initial_design_numdata est le nombre d'échantillons à acquérir en premier. Et acquisition_type fait référence à la façon de sélectionner x à échantillonner ensuite («LCB» consiste à sélectionner l'endroit où la zone bleue est minimisée).
bounds = [{'name': 'x', 'type': 'continuous', 'domain': (0,10)}]
myBopt = GPyOpt.methods.BayesianOptimization(f=f, domain=bounds,initial_design_numdata=5,acquisition_type='LCB')
Ensuite, répétez l'échantillonnage avec la commande suivante pour optimiser. max_iter indique le nombre d'échantillons.
myBopt.run_optimization(max_iter=15)
La solution optimale s'affiche.
print(myBopt.x_opt) #[ 2.05769988]
print(myBopt.fx_opt) #[-0.79271554]
Autres variables de fonction pouvant être utilisées
myBopt.model.model #Modèle de processus gaussien utilisé dans l'optimisation bayésienne(Objet GPy)
myBopt.model.model.predict #Fonction de régression de processus gaussien
myBopt.X,myBopt.Y #X et y échantillonnés
L'optimisation bayésienne peut également être appliquée dans plusieurs dimensions. Ici, nous effectuons une optimisation bayésienne bidimensionnelle. De plus, comme la variable d'entrée peut être une variable discrète, j'utiliserai une variable discrète pour une dimension.
La fonction est $ f (x) = \ log (10,5-x_0) + 0,1 \ sin (15x_0) $ quand $ x_1 = 0 $, et $ f (x) = \ cos (quand $ x_1 = 1 $). 1,5x_0) + 0,1x_0 $. De plus, nous le minimiserons dans la plage $ 0 \ leq x_1 \ leq 10 $ ($ x_0 $ vaut 0 ou 1).
Après l'optimisation, cela ressemblera à l'image suivante.
Faisons-le avec GPyOpt.
import GPy
import GPyOpt
import numpy as np
def f(x):
'''
Fonction non linéaire à optimiser cette fois
'''
x0,x1 = x[:,0],x[:,1]
f0 = np.log(10.5-x0) + 0.1*np.sin(15*x0)
f1 = np.cos(1.5*x0) + 0.1*x0
return (1-x1)*f0 + x1*f1
bounds = [{'name': 'x0', 'type': 'continuous', 'domain': (0,10)},
{'name': 'x1', 'type': 'discrete', 'domain': (0,1)}]
myBopt = GPyOpt.methods.BayesianOptimization(f=f, domain=bounds)
myBopt.run_optimization(max_iter=30)
Ce n'est pas si différent du cas unidimensionnel. Ce qui a changé, c'est que la fonction a également deux entrées et que les bornes sont une liste avec deux éléments. 'type': 'discrete' représente un choix, 0 ou 1.
La solution optimale s'affiche.
print(myBopt.x_opt) #[ 2.0539031 1. ]
print(myBopt.fx_opt) #[-0.7927657]
Recommended Posts