[PYTHON] Application de l'optimisation bayésienne au modèle Keras DNN

Application de l'optimisation bayésienne au modèle Keras DNN

Non limité à l'apprentissage en profondeur, l'ajustement des paramètres est une tâche difficile lors de la création de modèles d'apprentissage automatique. La précision du modèle d'apprentissage automatique dépend des paramètres, mais le nombre et la plage de paramètres sont larges et il est difficile de trouver la solution optimale.

Par exemple, lors de l'examen d'un modèle de réseau neuronal pour la couche cachée 3, de nombreux facteurs doivent être déterminés, tels que le nombre de neurones, le taux d'abandon, la taille du lot et le numéro d'époque qui sont les sorties de chaque couche, et la plage est large. Il existe différentes manières de déterminer chaque paramètre, mais voici des exemples de valeurs numériques possibles.

--Nombre de neurones: entier supérieur ou égal à 1

Selon le réseau neuronal, il peut y avoir des valeurs numériques appropriées, mais honnêtement, l'ajustement des paramètres est gênant car il existe des valeurs appropriées en fonction des données et du modèle de réseau neuronal. De plus, vous ne pouvez pas dire si le paramètre est bon ou mauvais tant que vous ne l'avez pas essayé.

Plus tôt, j'ai présenté comment rechercher des paramètres avec GridSearchCV. http://qiita.com/cvusk/items/285e2b02b0950537b65e

Dans cette méthode, j'ai essayé toutes les combinaisons des choix de paramètres que j'ai définis pour trouver le paramètre optimal. La difficulté avec cette méthode est que lorsque le nombre de paramètres augmente, le nombre de combinaisons à essayer augmente par multiplication.

Cette fois, nous allons introduire l'optimisation bayésienne comme méthode d'ajustement des paramètres plus puissante.

Que faire cette fois

Je vais vous montrer comment optimiser un modèle écrit en Keras en utilisant l'optimisation bayésienne. Le modèle utilisé comme exemple est MNIST.

1.JPG

Je voudrais optimiser les paramètres suivants dans un modèle à trois couches avec une couche d'entrée, une couche cachée et une couche de sortie.

--Nombre de sorties dans la couche d'entrée

À propos de l'optimisation bayésienne

L'explication de l'optimisation bayésienne est détaillée ici.

Dans l'optimisation bayésienne, les paramètres sont saisis, la précision de vérification du modèle (fonction de perte, rapport de précision, etc.) est sortie et les fonctions (modèles) intermédiaires sont des boîtes noires. La fonction de boîte noire est [processus gaussien](https://ja.wikipedia.org/wiki/%E3%82%AC%E3%82%A6%E3%82%B9%E9%81%8E%E7%A8% En supposant que 8B) est suivi, la distribution postérieure est recherchée et les paramètres sont optimisés en répétant la vérification.

outil

En Python, vous pouvez effectuer une optimisation bayésienne avec un outil appelé GPyOpt. Cliquez ici pour plus de détails sur son utilisation. Package d'optimisation Bayes GPyOpt avec Python

Code et utilisation

Le code que j'ai écrit cette fois est ici. https://github.com/shibuiwilliam/keras_gpyopt

J'expliquerai le contenu. Tout d'abord, définissez le modèle de MNIST.

# Import libraries

import GPy, GPyOpt
import numpy as np
import pandas as pds
import random
from keras.layers import Activation, Dropout, BatchNormalization, Dense
from keras.models import Sequential
from keras.datasets import mnist
from keras.metrics import categorical_crossentropy
from keras.utils import np_utils
from keras.optimizers import Adam
from keras.callbacks import EarlyStopping

# MNIST class
class MNIST():
    def __init__(self, first_input=784, last_output=10,
                 l1_out=512, 
                 l2_out=512, 
                 l1_drop=0.2, 
                 l2_drop=0.2, 
                 batch_size=100, 
                 epochs=10, 
                 validation_split=0.1):
        self.__first_input = first_input
        self.__last_output = last_output
        self.l1_out = l1_out
        self.l2_out = l2_out
        self.l1_drop = l1_drop
        self.l2_drop = l2_drop
        self.batch_size = batch_size
        self.epochs = epochs
        self.validation_split = validation_split
        self.__x_train, self.__x_test, self.__y_train, self.__y_test = self.mnist_data()
        self.__model = self.mnist_model()
        
    # load mnist data from keras dataset
    def mnist_data(self):
        (X_train, y_train), (X_test, y_test) = mnist.load_data()
        X_train = X_train.reshape(60000, 784)
        X_test = X_test.reshape(10000, 784)
​
        X_train = X_train.astype('float32')
        X_test = X_test.astype('float32')
        X_train /= 255
        X_test /= 255
​
        Y_train = np_utils.to_categorical(y_train, 10)
        Y_test = np_utils.to_categorical(y_test, 10)
        return X_train, X_test, Y_train, Y_test
    
    # mnist model
    def mnist_model(self):
        model = Sequential()
        model.add(Dense(self.l1_out, input_shape=(self.__first_input,)))
        model.add(Activation('relu'))
        model.add(Dropout(self.l1_drop))
        model.add(Dense(self.l2_out))
        model.add(Activation('relu'))
        model.add(Dropout(self.l2_drop))
        model.add(Dense(self.__last_output))
        model.add(Activation('softmax'))
        model.compile(loss='categorical_crossentropy',
                      optimizer=Adam(),
                      metrics=['accuracy'])
​
        return model
    
    # fit mnist model
    def mnist_fit(self):
        early_stopping = EarlyStopping(patience=0, verbose=1)
        
        self.__model.fit(self.__x_train, self.__y_train,
                       batch_size=self.batch_size,
                       epochs=self.epochs,
                       verbose=0,
                       validation_split=self.validation_split,
                       callbacks=[early_stopping])
    
    # evaluate mnist model
    def mnist_evaluate(self):
        self.mnist_fit()
        
        evaluation = self.__model.evaluate(self.__x_test, self.__y_test, batch_size=self.batch_size, verbose=0)
        return evaluation

# function to run mnist class
def run_mnist(first_input=784, last_output=10,
              l1_out=512, l2_out=512, 
              l1_drop=0.2, l2_drop=0.2, 
              batch_size=100, epochs=10, validation_split=0.1):
    
    _mnist = MNIST(first_input=first_input, last_output=last_output,
                   l1_out=l1_out, l2_out=l2_out, 
                   l1_drop=l1_drop, l2_drop=l2_drop, 
                   batch_size=batch_size, epochs=epochs, 
                   validation_split=validation_split)
    mnist_evaluation = _mnist.mnist_evaluate()
    return mnist_evaluation

Effectuez ensuite une optimisation bayésienne en utilisant le modèle MNIST ci-dessus.


# Bayesian Optimization
#Définissez le choix et la plage de chaque paramètre.
#Remarque: le paramètre est type: continuous、type:Doit être écrit dans un ordre discret.
#Sinon, une erreur se produira dans le processus suivant.
bounds = [{'name': 'validation_split', 'type': 'continuous',  'domain': (0.0, 0.3)},
          {'name': 'l1_drop',          'type': 'continuous',  'domain': (0.0, 0.3)},
          {'name': 'l2_drop',          'type': 'continuous',  'domain': (0.0, 0.3)},
          {'name': 'l1_out',           'type': 'discrete',    'domain': (64, 128, 256, 512, 1024)},
          {'name': 'l2_out',           'type': 'discrete',    'domain': (64, 128, 256, 512, 1024)},
          {'name': 'batch_size',       'type': 'discrete',    'domain': (10, 100, 500)},
          {'name': 'epochs',           'type': 'discrete',    'domain': (5, 10, 20)}]

#Définissez une fonction pour l'optimisation bayésienne (boîte noire décrite ci-dessus).
#x est l'entrée et la sortie est renvoyée.
def f(x):
    print(x)
    evaluation = run_mnist(
        l1_drop = float(x[:,1]), 
        l2_drop = float(x[:,2]), 
        l1_out = int(x[:,3]),
        l2_out = int(x[:,4]), 
        batch_size = int(x[:,5]), 
        epochs = int(x[:,6]), 
        validation_split = float(x[:,0]))
    print("loss:{0} \t\t accuracy:{1}".format(evaluation[0], evaluation[1]))
    print(evaluation)
    return evaluation[0]

#Effectuez une recherche préliminaire.
opt_mnist = GPyOpt.methods.BayesianOptimization(f=f, domain=bounds)

#Recherchez les meilleurs paramètres.
opt_mnist.run_optimization(max_iter=10)
print("optimized parameters: {0}".format(opt_mnist.x_opt))
print("optimized loss: {0}".format(opt_mnist.fx_opt))

GPyOpt.methods.BayesianOptimization définit les méthodes d'optimisation bayésienne. Avec cela, vous pouvez rechercher le paramètre que vous avez défini, le paramètre qui donne la fonction de perte optimale dans les limites, mais il y a une mise en garde. Choix des paramètres, la plage est écrite avec dict, et type: continu et type: discrete définissent la valeur continue ou le choix. Si vous n'écrivez pas ici dans l'ordre continu et discret, une erreur se produira avec ʻopt_mnist = GPyOpt.methods.BayesianOptimization (f = f, domain = bounds) `. Je ne savais pas comment écrire cela, et j'y ai été accro pendant environ deux jours.

Trouvez le meilleur paramètre avec ʻopt_mnist.run_optimization (max_iter = 10) . Spécifiez la limite supérieure du nombre d'exécutions d'apprentissage pour la recherche avec max_iter`. Nous chercherons jusqu'à 10 fois ici, mais s'il converge tôt, il sera complété en un plus petit nombre de fois.

Le résultat de l'exécution du programme est le suivant. 3.JPG

Ici, vous pouvez voir que la recherche est terminée en 4 fois. L'optimisation bayésienne peut être utilisée pour automatiser le réglage des paramètres et réduire l'effort.

Recommended Posts

Application de l'optimisation bayésienne au modèle Keras DNN
Introduction à l'optimisation bayésienne
Pré-traitement pour construire un modèle seq2seq à l'aide de l'API fonctionnelle de Keras
Comment utiliser Keras ~ De la simple génération de modèle à CNN ~
J'ai créé un code pour convertir illustration2vec en modèle Keras
Découvrez Wasserstein GAN avec le modèle Keras et l'optimisation TensorFlow
J'ai essayé de passer par l'optimisation bayésienne. (Avec des exemples)
J'ai essayé l'optimisation bayésienne!
[TF] Comment charger / enregistrer le modèle et le paramètre dans Keras