Utilisez les modèles Keras Deep Learning avec Scikit-Learn en Python
Keras est l'une des bibliothèques d'apprentissage profond en Python les plus populaires pour la recherche et le développement en raison de sa simplicité et de sa facilité d'utilisation.
La bibliothèque scikit-learn est la bibliothèque la plus populaire pour l'apprentissage automatique général en Python.
Dans cet article, vous découvrirez comment utiliser les modèles d'apprentissage profond de Keras avec la bibliothèque scikit-learn en Python.
Cela vous permettra d'exploiter la puissance de la bibliothèque scikit-learn pour des tâches telles que l'évaluation du modèle et l'optimisation des hyper-paramètres du modèle.
Démarrez votre projet avec mon nouveau livre Deep Learning With Python, comprenant des tutoriels pas à pas et les fichiers code source Python pour tous exemples.
Commençons.
- Mai/2016 : message original
- Mise à jour d'octobre 2016 : exemples mis à jour pour Keras 1.1.0 et scikit-learn v0.18.
- Mise à jour janvier 2017 : correction d'un bug lors de l'impression des résultats de la recherche par grille.
- Mise à jour de mars 2017 : exemple mis à jour pour Keras 2.0.2, TensorFlow 1.0.1 et Theano 0.9.0.
- Mise à jour de mars 2018 : ajout d'un lien alternatif pour télécharger l'ensemble de données, car l'original semble avoir été supprimé.
- Mise à jour de juin 2022 : code mis à jour pour TensorFlow 2.x et SciKeras.
Aperçu
Keras est une bibliothèque populaire pour l'apprentissage profond en Python, mais la bibliothèque se concentre sur les modèles d'apprentissage profond. En fait, il s’efforce d’atteindre le minimalisme, en se concentrant uniquement sur ce dont vous avez besoin pour définir et construire rapidement et simplement des modèles d’apprentissage profond.
La bibliothèque scikit-learn en Python est construite sur la pile SciPy pour un calcul numérique efficace. Il s'agit d'une bibliothèque complète pour l'apprentissage automatique général et fournit de nombreux utilitaires utiles pour développer des modèles d'apprentissage profond. Parmi eux, les moins importants sont :
- Évaluation des modèles à l'aide de méthodes de rééchantillonnage telles que la validation croisée k-fold
- Recherche et évaluation efficaces des hyper-paramètres du modèle
Il y avait un wrapper dans la bibliothèque TensorFlow/Keras pour créer des modèles d'apprentissage en profondeur utilisés comme estimateurs de classification ou de régression dans scikit-learn. Mais récemment, ce wrapper a été supprimé pour devenir un module Python autonome.
Dans les sections suivantes, vous examinerez des exemples d'utilisation du wrapper KerasClassifier pour un réseau neuronal de classification créé dans Keras et utilisé dans la bibliothèque scikit-learn.
Le problème de test est l’ensemble de données de classification de l’apparition du diabète chez les Indiens Pima. Il s'agit d'un petit ensemble de données avec tous les attributs numériques avec lequel il est facile de travailler. Téléchargez l'ensemble de données et placez-le directement dans votre travail actuel sous le nom pima-indians-diabetes.csv (mise à jour : télécharger à partir d'ici).
Les exemples suivants supposent que vous avez installé avec succès TensorFlow 2.x, SciKeras et scikit-learn. Si vous utilisez le système pip
pour vos modules Python, vous pouvez les installer avec :
pip install tensorflow scikeras scikit-learn
Évaluer les modèles d'apprentissage profond avec la validation croisée
Les classes KerasClassifier et KerasRegressor dans SciKeras prennent un argument model
qui est le nom de la fonction à appeler pour obtenir votre modèle.
Vous devez définir une fonction appelée comme vous le souhaitez qui définit votre modèle, le compile et le renvoie.
Dans l'exemple ci-dessous, vous définirez une fonction create_model()
qui crée un réseau neuronal multicouche simple pour le problème.
Vous transmettez ce nom de fonction à la classe KerasClassifier par l'argument model
. Vous transmettez également des arguments supplémentaires de nb_epoch=150
et batch_size=10
. Ceux-ci sont automatiquement regroupés et transmis à la fonction fit()
, qui est appelée en interne par la classe KerasClassifier.
Dans cet exemple, vous utiliserez scikit-learn StratifiedKFold pour effectuer une validation croisée stratifiée 10 fois. Il s'agit d'une technique de rééchantillonnage qui peut fournir une estimation robuste des performances d'un modèle de machine learning sur des données invisibles.
Ensuite, utilisez la fonction scikit-learn cross_val_score()
pour évaluer votre modèle à l'aide du schéma de validation croisée et imprimer les résultats.
# MLP for Pima Indians Dataset with 10-fold cross validation via sklearn
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from scikeras.wrappers import KerasClassifier
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import cross_val_score
import numpy as np
# Function to create model, required for KerasClassifier
def create_model():
# create model
model = Sequential()
model.add(Dense(12, input_dim=8, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# Compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
return model
# fix random seed for reproducibility
seed = 7
np.random.seed(seed)
# load pima indians dataset
dataset = np.loadtxt("pima-indians-diabetes.csv", delimiter=",")
# split into input (X) and output (Y) variables
X = dataset[:,0:8]
Y = dataset[:,8]
# create model
model = KerasClassifier(model=create_model, epochs=150, batch_size=10, verbose=0)
# evaluate using 10-fold cross validation
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)
results = cross_val_score(model, X, Y, cv=kfold)
print(results.mean())
Remarque : Vos résultats peuvent varier en raison de la nature stochastique de l'algorithme ou de la procédure d'évaluation, ou des différences de précision numérique. Pensez à exécuter l’exemple plusieurs fois et comparez le résultat moyen.
L'exécution de l'exemple affiche les compétences du modèle pour chaque époque. Au total, 10 modèles sont créés et évalués, et la précision moyenne finale est affichée.
0.646838691487
En comparaison, ce qui suit est une implémentation équivalente avec un modèle de réseau neuronal dans scikit-learn :
# MLP for Pima Indians Dataset with 10-fold cross validation via sklearn
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import cross_val_score
from sklearn.neural_network import MLPClassifier
import numpy as np
# fix random seed for reproducibility
seed = 7
np.random.seed(seed)
# load pima indians dataset
dataset = np.loadtxt("pima-indians-diabetes.csv", delimiter=",")
# split into input (X) and output (Y) variables
X = dataset[:,0:8]
Y = dataset[:,8]
# create model
model = MLPClassifier(hidden_layer_sizes=(12,8), activation='relu', max_iter=150, batch_size=10, verbose=False)
# evaluate using 10-fold cross validation
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)
results = cross_val_score(model, X, Y, cv=kfold)
print(results.mean())
Le rôle du KerasClassifier
est de fonctionner comme un adaptateur pour faire fonctionner le modèle Keras comme un objet MLPClassifier
de scikit-learn.
Paramètres du modèle d'apprentissage profond de recherche dans la grille
L'exemple précédent a montré à quel point il est facile d'encapsuler votre modèle d'apprentissage profond de Keras et de l'utiliser dans les fonctions de la bibliothèque scikit-learn.
Dans cet exemple, vous irez plus loin. La fonction que vous spécifiez à l'argument model
lors de la création du wrapper KerasClassifier peut prendre des arguments. Vous pouvez utiliser ces arguments pour personnaliser davantage la construction du modèle. De plus, vous savez que vous pouvez fournir des arguments à la fonction fit()
.
Dans cet exemple, vous utiliserez une recherche par grille pour évaluer différentes configurations de votre modèle de réseau neuronal et générer un rapport sur la combinaison qui fournit les performances les mieux estimées.
La fonction create_model()
est définie pour prendre deux arguments, optimizer
et init
, qui doivent tous deux avoir des valeurs par défaut. Cela vous permettra d'évaluer l'effet de l'utilisation de différents algorithmes d'optimisation et schémas d'initialisation de poids pour votre réseau.
Après avoir créé votre modèle, définissez les tableaux de valeurs pour le paramètre que vous souhaitez rechercher, notamment :
- Optimiseurs pour rechercher différentes valeurs de poids
- Initialiseurs pour préparer les pondérations du réseau en utilisant différents schémas
- Époques de formation du modèle pour un nombre différent d'expositions à l'ensemble de données de formation
- Lots permettant de faire varier le nombre d'échantillons avant une mise à jour du poids
Les options sont spécifiées dans un dictionnaire et transmises à la configuration de la classe scikit-learn de GridSearchCV. Ce cours évaluera une version de votre modèle de réseau neuronal pour chaque combinaison de paramètres (2 x 3 x 3 x 3 pour les combinaisons d'optimiseurs, d'initialisations, d'époques et de lots). Chaque combinaison est ensuite évaluée en utilisant la validation croisée stratifiée par défaut en 3 volets.
Cela représente beaucoup de modèles et beaucoup de calculs. Ce n’est pas un programme que vous souhaitez utiliser à la légère en raison du temps que cela prendra. Il peut être utile de concevoir de petites expériences avec un sous-ensemble plus petit de vos données et qui se termineront dans un délai raisonnable. Ceci est raisonnable dans ce cas en raison du petit réseau et du petit ensemble de données (moins de 1 000 instances et neuf attributs).
Enfin, les performances et la combinaison de configurations pour le meilleur modèle sont affichées, suivies par les performances de toutes les combinaisons de paramètres.
# MLP for Pima Indians Dataset with grid search via sklearn
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from scikeras.wrappers import KerasClassifier
from sklearn.model_selection import GridSearchCV
import numpy as np
# Function to create model, required for KerasClassifier
def create_model(optimizer='rmsprop', init='glorot_uniform'):
# create model
model = Sequential()
model.add(Dense(12, input_dim=8, kernel_initializer=init, activation='relu'))
model.add(Dense(8, kernel_initializer=init, activation='relu'))
model.add(Dense(1, kernel_initializer=init, activation='sigmoid'))
# Compile model
model.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])
return model
# fix random seed for reproducibility
seed = 7
np.random.seed(seed)
# load pima indians dataset
dataset = np.loadtxt("pima-indians-diabetes.csv", delimiter=",")
# split into input (X) and output (Y) variables
X = dataset[:,0:8]
Y = dataset[:,8]
# create model
model = KerasClassifier(model=create_model, verbose=0)
print(model.get_params().keys())
# grid search epochs, batch size and optimizer
optimizers = ['rmsprop', 'adam']
init = ['glorot_uniform', 'normal', 'uniform']
epochs = [50, 100, 150]
batches = [5, 10, 20]
param_grid = dict(optimizer=optimizers, epochs=epochs, batch_size=batches, model__init=init)
grid = GridSearchCV(estimator=model, param_grid=param_grid)
grid_result = grid.fit(X, Y)
# summarize results
print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
means = grid_result.cv_results_['mean_test_score']
stds = grid_result.cv_results_['std_test_score']
params = grid_result.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
print("%f (%f) with: %r" % (mean, stdev, param))
Notez que dans le dictionnaire param_grid
, model__init
a été utilisé comme clé pour l'argument init
de notre create_model()
. fonction. Le préfixe model__
est requis pour les modèles KerasClassifier
dans SciKeras afin de fournir des arguments personnalisés.
Cela peut prendre environ 5 minutes sur votre poste de travail exécuté sur le CPU (plutôt que sur le GPU). L’exécution de l’exemple montre les résultats ci-dessous.
Remarque : Vos résultats peuvent varier en raison de la nature stochastique de l'algorithme ou de la procédure d'évaluation, ou des différences de précision numérique. Pensez à exécuter l’exemple plusieurs fois et comparez le résultat moyen.
Vous pouvez voir que la recherche sur la grille a découvert que l'utilisation d'un schéma d'initialisation uniforme, d'un optimiseur rmsprop, de 150 époques et d'une taille de lot de 10 permettait d'obtenir le meilleur score de validation croisée d'environ 77 % sur ce problème.
Pour un exemple plus complet de réglage des hyperparamètres avec Keras, consultez le didacticiel :
- Comment griller les hyperparamètres de recherche pour les modèles d'apprentissage profond en Python avec Keras
Best: 0.772167 using {'batch_size': 10, 'epochs': 150, 'model__init': 'normal', 'optimizer': 'rmsprop'}
0.691359 (0.024495) with: {'batch_size': 5, 'epochs': 50, 'model__init': 'glorot_uniform', 'optimizer': 'rmsprop'}
0.690094 (0.026691) with: {'batch_size': 5, 'epochs': 50, 'model__init': 'glorot_uniform', 'optimizer': 'adam'}
0.704482 (0.036013) with: {'batch_size': 5, 'epochs': 50, 'model__init': 'normal', 'optimizer': 'rmsprop'}
0.727884 (0.016890) with: {'batch_size': 5, 'epochs': 50, 'model__init': 'normal', 'optimizer': 'adam'}
0.709600 (0.030281) with: {'batch_size': 5, 'epochs': 50, 'model__init': 'uniform', 'optimizer': 'rmsprop'}
0.694067 (0.019733) with: {'batch_size': 5, 'epochs': 50, 'model__init': 'uniform', 'optimizer': 'adam'}
0.720134 (0.038867) with: {'batch_size': 5, 'epochs': 100, 'model__init': 'glorot_uniform', 'optimizer': 'rmsprop'}
0.743536 (0.022213) with: {'batch_size': 5, 'epochs': 100, 'model__init': 'glorot_uniform', 'optimizer': 'adam'}
0.744809 (0.022928) with: {'batch_size': 5, 'epochs': 100, 'model__init': 'normal', 'optimizer': 'rmsprop'}
0.734360 (0.024717) with: {'batch_size': 5, 'epochs': 100, 'model__init': 'normal', 'optimizer': 'adam'}
0.742127 (0.035137) with: {'batch_size': 5, 'epochs': 100, 'model__init': 'uniform', 'optimizer': 'rmsprop'}
0.729225 (0.035580) with: {'batch_size': 5, 'epochs': 100, 'model__init': 'uniform', 'optimizer': 'adam'}
0.717537 (0.033634) with: {'batch_size': 5, 'epochs': 150, 'model__init': 'glorot_uniform', 'optimizer': 'rmsprop'}
0.724039 (0.033990) with: {'batch_size': 5, 'epochs': 150, 'model__init': 'glorot_uniform', 'optimizer': 'adam'}
0.753926 (0.016855) with: {'batch_size': 5, 'epochs': 150, 'model__init': 'normal', 'optimizer': 'rmsprop'}
...
Résumé
Dans cet article, vous avez découvert comment envelopper vos modèles d'apprentissage profond Keras et les utiliser dans la bibliothèque générale d'apprentissage automatique scikit-learn.
Vous pouvez constater que l'utilisation de scikit-learn pour des opérations d'apprentissage automatique standard telles que l'évaluation de modèles et l'optimisation des hyperparamètres de modèles peut permettre de gagner beaucoup de temps par rapport à la mise en œuvre vous-même de ces schémas.
L'emballage de votre modèle vous a permis d'exploiter les outils puissants de scikit-learn pour intégrer vos modèles d'apprentissage en profondeur dans votre processus général d'apprentissage automatique.
Avez-vous des questions sur l'utilisation des modèles Keras dans scikit-learn ou sur cet article ? Posez votre question dans les commentaires et je ferai de mon mieux pour y répondre.