[PYTHON] Ajuster les hyper paramètres avec l'optimisation bayésienne

Qu'est-ce que l'optimisation bayésienne?

(Divers) ** A. Comment trouver le meilleur endroit tout en sautant les expériences autant que possible. ** **

En utilisant la méthode "** régression de processus gaussien **" pour estimer statistiquement une certaine fonction $ f $, observez la valeur de $ y = f (x) $ uniquement là où elle semble bonne ** et $ Comment trouver la valeur optimale de f $.

Cet article est facile à comprendre comme exemple d'utilisation réelle. Faites le meilleur liège avec l'optimisation bayésienne - il a l'air délicieux

Étant donné que j'ai eu la chance de l'utiliser récemment, je voudrais vous présenter ce que j'ai étudié à cette fin et le calcul que j'ai fait comme expérience préliminaire. Des discussions mathématiques détaillées peuvent être trouvées en lisant le chapitre 6 de PRML et le chapitre 6 de "Processus gaussien et apprentissage automatique", donc cet article présentera une histoire d'image et des résultats expérimentaux. .. (Le code d'exécution a un lien GitHub à la fin)

Qu'est-ce que la régression de processus gaussien?

Supposons que vous vouliez vous attendre à une fonction comme la ligne noire dans la figure ci-dessous. La fonction réelle est $ y = \ frac {1} {16} x ^ 4-x ^ 2 + \ frac {5} {16} x $, mais je ne connais pas la forme de la fonction. Il est difficile de tout vérifier de bout en bout, alors obtenons 5 points (cercle bleu) et prédisons le tout à partir d'ici.

image.png

Ici, si vous entrez les informations de ce point dans "Régression du processus gaussien" et faites une prédiction, ce sera comme suit [^ nan].

image.png

[^ nan]: Si ces 5 points étaient obtenus sous forme d'observations, quel type de fonction serait une telle fonction, comme le bruit suivant une distribution gaussienne ou une forme sous laquelle la fonction peut être obtenue dans une certaine expression. La distribution de probabilité est dérivée en faisant les hypothèses ci-dessus.

Dans la régression de processus gaussien, la prédiction se présente comme une "distribution de probabilité de fonctions". Ce sont des informations sur la probabilité de passer ici. La ligne bleue de la figure est la valeur moyenne de cette distribution de probabilité, et la partie remplie de bleu clair est le degré de variation de la probabilité (ici, deux fois l'écart type. $ 2 \ sigma $, donc la probabilité d'être dans cette plage est de 95%. ) Est montré. La fonction réelle $ y = \ frac {1} {16} x ^ 4-x ^ 2 + \ frac {5} {16} x $ est bien dans la plage d'erreur, et la plage d'erreur autour du point d'observation Vous pouvez voir que c'est petit et que la plage d'erreur augmente à mesure que la distance du point augmente.

Si vous ajoutez quelques points supplémentaires, image.png On dirait. Il est maintenant possible de prédire assez précisément dans la plage de $ x = -3 à 1 $.

Comment déterminer "un endroit qui a l'air bien"

Considérant le problème de "je n'ai pas besoin de connaître la forme de toutes les fonctions, donc je veux trouver seulement la valeur minimale". Je pense qu'il est inutile d'observer l'endroit (autour de $ x = -1 à 1 $) dont on sait qu'il augmente à mesure que la valeur augmente. Vous souhaitez rechercher de préférence les lieux où la valeur semble faible. Aussi, je voudrais ajouter un peu plus de points où il y a beaucoup d'incertitude (autour de $ x = 3 $) que je n'ai pas encore beaucoup cherché.

De cette manière, la «fonction d'acquisition» consiste à marquer de manière équilibrée les «lieux susceptibles d'avoir la valeur optimale» et les «lieux encore incertains». Cependant, celle sur laquelle il faut mettre l'accent dépend du cas, il existe donc différentes fonctions d'acquisition en fonction de la stratégie.

etc...

image.png Lorsque je trace chacun d'eux, cela ressemble à ceci, et je prédis que le prochain point à observer est d'environ -2,7 $.

BayesianOptimization Comme il est difficile d'écrire un tel calcul à chaque fois, j'utilise un package Python appelé optimisation bayésienne. La cible utilise la même forme que ci-dessus, $ y = x ^ 4-16x ^ 2 + 5x $ [^ stf].

[^ stf]: Cette fonction est souvent utilisée comme un benchmark d'optimisation en tant que fonction avec plusieurs minimums dans la dimension générale. FONCTION STYBLINSKI-TANG

image.png ノイズを含んでいます。

Premièrement, si vous prenez 3 points et effectuez une régression de processus gaussien, les fonctions de prédiction et d'acquisition seront comme ceci. J'ai décidé que la ligne verticale rouge devait être observée ensuite [^ gp]. image.png

[^ gp]: la fonction d'acquisition utilise la stratégie EI

Observez ceci «x = 0,5», ajoutez un point et répétez la régression. L'incertitude autour de «x = 0» a été considérablement réduite. image.png

Si ce cycle est répété environ 20 fois, ce sera comme suit. image.png

La valeur de x, qui prend la valeur minimale, était estimée à "-2,59469813". La vraie solution est "-2.9035 ...", donc c'est assez différent, mais c'est bruyant, donc ça ne peut pas être aidé dans une certaine mesure.

Dans le cas de 2 dimensions

En général, des recherches optimisées peuvent également être effectuées dans des espaces de plus grande dimension. image.png image.png Depuis FONCTION STYBLINSKI-TANG De même, essayez de le minimiser avec une fonction de ce type.

À la suite de l'exécution appropriée de la régression de processus gaussien avec 5 points, la valeur moyenne, l'écart type et la fonction d'acquisition sont les suivants. image.png Cela ressemble à ceci lorsque je le trace en 3D. (Le bleu est la moyenne, le vert est l'écart type ±) image.png

De même, si 55 cycles d'observation sont effectués image.png image.png

La forme est très proche d'une vraie fonction. La valeur de x, qui prend la valeur minimale, a été prédite comme «(-2,79793531, -2,91749935)». Il semble que la précision soit meilleure qu'avant. Si vous recherchez x et y de -5 à 5 par incréments de 0,1, vous devrez effectuer 100 expériences avec 10x10, afin de pouvoir enregistrer le nombre d'expériences.

Optimisation des hyperparamètres

L'optimisation bayésienne est efficace lorsque le coût d'observation des valeurs individuelles est élevé et que la dimension de l'espace de recherche est grande. Appliquons cela au réglage des paramètres de l'apprentissage automatique, qui augmente le temps de calcul à chaque fois que le nombre de données devient énorme.

Paramètres Kerne Ridge Hyper-

Le modèle d'apprentissage automatique appelé régression Kernel Ridge a deux hyper paramètres, «alpha» et «gamma» (paramètres qui ne sont pas automatiquement déterminés et doivent être donnés en externe en fonction des données) [^ hyper]. .. ʻAlpha est la force de la régularisation (travail pour empêcher le sur-apprentissage), et gamma` est un paramètre qui détermine la forme de la fonction à appliquer.

[^ hyper]: En fait, il existe un moyen de déterminer les paramètres théoriquement appropriés, mais ici nous chercherons au hasard sans y penser.

Trouvons les paramètres qui maximisent la précision du modèle qui prédit les prix des maisons avec l'ensemble de données boston contenu dans sklearn.datasets.

Tout d'abord, vérifions la précision avec les valeurs des paramètres par défaut.

KernelRidge(kernel='rbf').fit(train_x, train_y).score(test_x, test_y)
#=> 0.4802674032751879

Il est devenu 0,48.

Le chiffre du paramètre pouvant changer considérablement, effectuez la recherche de paramètre en créant chaque numéro de journal.

def get_score_KR(x):
    alpha, gamma = x
    predictor = KernelRidge(kernel='rbf', alpha=alpha, gamma=gamma)
    return cross_val_score(predictor, train_x, train_y, cv=5).mean()
def get_score_KR_log(x):
    print(x)
    return get_score_KR((10**x[0][0], 10**x[0][1]))

Une telle fonction vérifie la précision du modèle pour l'alpha et le gamma et l'utilise comme une expérience de rétroaction.


import GPyOpt
bounds = [{'name': 'log alpha', 'type': 'continuous', 'domain': (-4,2)},
         {'name': 'log gamma', 'type': 'continuous', 'domain': (-4,2)}]
bo = GPyOpt.methods.bayesian_optimization.BayesianOptimization(
    f=get_score_KR_log, domain=bounds, model_type='GP', acquisition_type='EI', initial_design_numdata=5, maximize=True)
bo.run_optimization()
bo.plot_acquisition()

image.png image.png Les 5 premiers points ressemblent à ceci.

image.png image.png Après 11 cycles, cela ressemble à ceci.

image.png image.png Cela ressemble à ceci dans 51 cycles. [^ alpha] La valeur optimale de x est «[-1,97439296, -0,25720405]», c'est-à-dire alpha = 0,0106, gamma = 0,553.

[^ alpha]: Il semble que alpha ait été basculé du côté le plus petit, mais c'est probablement parce que le nombre de données est petit. Si l'alpha est trop petit, la régularisation ne fonctionnera pas et les performances de généralisation chuteront, nous limiterons donc notre recherche à ce point.

predictor_opt = KernelRidge(kernel='rbf', alpha=10**bo.x_opt[0], gamma=10**bo.x_opt[1])
predictor_opt.fit(train_x, train_y)

predictor_opt.score(test_x ,test_y)
#=> 0.8114250068143878

Lorsque j'ai vérifié à nouveau la précision en utilisant cette valeur, le résultat était de 0,81, ce qui était considérablement amélioré par rapport à avant l'optimisation. Tu l'as fait.

Comparaison avec la recherche de grille

En général, il existe de nombreux documents qui utilisent la "recherche de grille" pour rechercher uniformément l'espace pour l'ajustement des hyper paramètres [^ gs]. De même, explorons l'espace des paramètres de $ 10 ^ {-4} à 10 ^ 2 $.

[^ gs]: Exemple: Recherche de grille et optimisation de paramètres aléatoires dans le document Scikit-learn 3.2. Réglage des hyper-paramètres d'un estimateur Est introduit, et il y a une description que la recherche de grille est largement utilisée.

from sklearn.model_selection import GridSearchCV
parameters = {'alpha':[i*10**j for j in [-4, -3, -2, -1, 0, 1] for i in [1, 2, 4, 8]], 
              'gamma':[i*10**j for j in [-4, -3, -2, -1, 0, 1] for i in [1, 2, 4, 8]]}
gcv = GridSearchCV(KernelRidge(kernel='rbf'), parameters, cv=5)
gcv.fit(train_x, train_y)

bes = gcv.best_estimator_
bes.fit(train_x, train_y)
bes.score(test_x, test_y)
#=> 0.8097198949264954

image.png

La forme est presque la même que la surface courbe prévue dans l'optimisation gaussienne. Dans cette recherche de grille, «l'expérience» est effectuée avec 24 points chacun pour alpha et gamma, pour un total de 576 points, c'est donc difficile dans les situations où le nombre de données est important et le calcul prend du temps.

Résumé

C'est pourquoi nous avons pu trouver les paramètres qui montrent la même précision que la recherche de grille avec l'optimisation bayésienne dans environ 1/10 du nombre d'expériences!

Si vous avez des erreurs ou des questions, veuillez commenter.

Le code d'exécution et la progression de chaque section sont répertoriés ci-dessous.

Qu'est-ce que l'optimisation bayésienne? : BayesianOptimization_Explain BayesianOptimization:BayesianOptimization_Benchmark Optimisation des hyperparamètres: BayesianOptimization_HyperparameterSearch

Les références

Traduit par C.M. Bishop, Hiroshi Motoda et al. (2012) "Reconnaissance de formes et apprentissage automatique Prédiction statistique par la théorie des bases supérieures et inférieures" Maruzen Publishing Daichi Mochihashi, Seisei Ohba (2019) "Processus de Gauss et apprentissage automatique" Kodansha Package d'optimisation Bayes GPyOpt avec Python Mathématiques de l'optimisation bayésienne Créez le meilleur bouchon avec l'optimisation bayésienne Scikit-learn: Machine Learning in Python, Pedregosa et al., JMLR 12, pp. 2825-2830, 2011. GPyOpt

Recommended Posts

Ajuster les hyper paramètres avec l'optimisation bayésienne
Optimisation bayésienne très simple avec Python
Introduction à l'optimisation
J'ai essayé l'optimisation bayésienne!
Ajustez les axes avec matplotlib
J'ai essayé de passer par l'optimisation bayésienne. (Avec des exemples)
Essayez l'optimisation des fonctions avec Optuna
Hyper réglage des paramètres avec LightGBM Tuner
Jeux de regroupement avec optimisation des combinaisons
Restaurez les photos décousues avec l'optimisation!
Optimisation combinée avec recuit quantique
Optimisation globale à usage général avec Z3
[Python] Estimation bayésienne avec Pyro
Introduction à l'optimisation bayésienne
Recherche en grille d'hyper paramètres avec Scikit-learn
Maximisez les ventes des restaurants grâce à l'optimisation combinée
GPyOpt, un package d'optimisation bayésienne en Python
Optimisation apprise avec OR-Tools Part0 [Introduction]
Résolution de la théorie des jeux avec l'optimisation des combinaisons