Structures de sauvegarde de modèle de machine learning : le format hdf5
Lors de la construction d’une application en science de données, l’une des étapes les plus importantes concerne la sauvegarde et le chargement de modèles de machine learning. Cela permet de stocker des modèles entraînés pour une utilisation ultérieure et facilite le partage et le déploiement de modèles avec d’autres utilisateurs. En Python cette tache est relativement simple puisqu’il dispose de plusieurs structures de sauvegarde de modèles de machine learning, chacune offrant ses avantages et inconvénients.
Dans une série de 4 articles, nous explorerons ensemble certaines des structures de sauvegarde de modèles de machine learning les plus couramment utilisées en Python, ainsi que leurs caractéristiques et leur utilisation pratique. Il s’agit des structures HDF5 (Hierarchical Data Format 5), PICKLE, JOBLIB et ONNX.
Dans ce premier article, nous allons voir une structure de sauvegarde de donnée pas très connu mais pourtant très efficace. HDF5 (Hierarchical Data Format 5) est un format de fichier qui permet de stocker et gérer les données de manière hiérarchique et structurée. Il est couramment utilisé en science des données pour stocker des tableaux multidimensionnels, des images, des vidéos. Mais il peut aussi être utilisé pour sauvegarder et charger des modèles de machine learning.
En python c’est le module h5py qui permet de manipuler les fichiers au format HDF5. Avec la distribution python Anaconda, il peut être installé simplement avec la commande pip install ou conda install (par exemple en tapant la commande dans le anaconda prompt si on utilise Windows ou dans un invite de commande si on est sous linux en précisant éventuellement le canal d’installation comme par exemple conda-forge).
En théorie
Il existe principalement trois types d’objets de base pour le format HDF5: groupe, dataset et attribut.
L’organisation de ces objets peut être assimilé à des fichiers organisés dans un dossier sur votre bureau.
Groupe
Ce sont des objets qui permettent de regrouper les autres types d’objets à savoir des datasets, attributs ou des sous groupes. Ils peuvent être vue comme des dossiers dans un système d’organisation de fichiers.
Un groupe est composé d’attributs et des objets HDF5 (un groupe étant lui-même un objet peut être contenu dans un autre).
En utilisant les groupes, les données peuvent être organisées en une hiérarchie facilement navigable et organisée de manière logique, ce qui facilite l’accès et la gestion des données stockées dans le fichier HDF5.
Dataset
Les datasets sont des tableaux multidimensionnels contenant des données d’un même type qui peut être numérique, booléen, chaîne de caractère,… Ils peuvent être assimilés à des fichiers.
Les datasets peuvent être créés dans des groupes ou directement sous le niveau racine du fichier HDF5. Ils peuvent avoir des formes arbitraires c’est-à-dire n’importe quel nombre de dimensions de n’importe quels longueurs.
Un datastet est composé comme suit :
– le type données stocké, identifié par datatype
– le nombre de dimension du dataset, identifié par dataspace
– le format de stockage, qui peut être linéaire ou non
Attribut
Dans un fichier HDF5, les attributs sont des métadonnées associées à un groupe ou à un dataset. Ils fonctionne sous le principe d’une valeur associée à un nom. Un attribut est composé d’une valeur et d’un datatype.
Les attributs sont similaires aux variables, mais ils sont stockés directement dans le groupe ou le jeu de données auquel ils sont associés, plutôt que d’être stockés dans un tableau séparé. Ils peuvent être de différents types, comme par exemple des chaînes de caractères, des entiers, des flottants et des tableaux multidimensionnels.
Les attributs sont utiles pour stocker des informations supplémentaires sur les données, qui pourrait être utile pour comprendre les données stockées dans le fichier HDF5. Ils peuvent aussi être utilisés pour stocker de petites valeurs.
En pratique
Pour créer un nouveau fichier HDF5, nous pouvons utiliser la fonction File de la bibliothèque h5py en lui spécifiant le “répertoire/nom” où doit être créé le fichier et le mode d’accès qui peut être en écriture ou lecture et écriture avec les options ‘w’, ‘x’ ou ‘a’ :
import h5py # Créer un nouveau fichier HDF5 f = h5py.File('mon_fichier.hdf5', 'w')
Dans cet exemple, nous créons un nouveau fichier HDF5 appelé mon_fichier.hdf5. Nous utilisons ‘w’ pour indiquer que nous allons écrire dans le fichier.
Une fois que nous avons créé un fichier HDF5, nous pouvons ajouter des groupes et des datasets à l’intérieur.
# Créer un groupe dans le fichier HDF5 g = f.create_group('groupe1') # Créer un ensemble de données dans le groupe dset = g.create_dataset('donnees', (10,), dtype='f')
Dans cet exemple, nous créons un groupe appelé groupe1 dans le fichier HDF5, puis nous créons un dataset appelé donnees à l’intérieur du groupe. Le dataset a une forme de (10,), ce qui signifie qu’il s’agit d’un tableau d’une dimension de taille 10, et le type de données est ‘f’, qui représente des nombres à virgule flottante.
Nous pouvons maintenant ajouter des données au dataset en utilisant l’indexation :
# Ajouter des données à l'ensemble de données dset[0] = 1.0 dset[1] = 2.0 dset[2] = 3.0
Dans cet exemple, nous ajoutons des valeurs au dataset en utilisant l’indexation. Les valeurs sont stockées dans le dataset dans l’ordre dans lequel qu’elles sont ajoutées.
Nous pouvons maintenant créé un modèle simple de régression linéaire, le sauvegarder et le charger :
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np np.random.seed(seed=123) # Définir les variables d'entrée et de sortie X_train = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [2, 3, 4], [5, 6, 7], [8, 9, 10], [3, 4, 5], [6, 7, 8], [9, 10, 11]]) y_train = np.array([3, 6, 9, 4, 7, 10, 5, 8, 11]) X_test = np.array([[1, 5, 7], [3, 6, 10], [2, 8, 9], [4, 5, 11], [7, 6, 4], [1, 9, 2], [6, 3, 8], [5, 10, 1], [9, 2, 7]]) y_test = np.array([3, 7, 9, 6, 4, 4, 7, 9, 10]) # Instancier un modèle de régression linéaire model = LinearRegression() # Entraîner le modèle sur les données d'entrée et de sortie model.fit(X_train, y_train) # Obtenir les prédictions du modèle pour les données d'entrainement et de test y_pred_train = model.predict(X_train) y_pred_test = model.predict(X_test)
On peut ensuite crée un graphique 3D pour visualiser les données et leurs prédictions :
# Créer un graphique 3D fig = plt.figure(figsize=(12, 5)) # Afficher les données d'entrainement et leurs prédictions sur le premier sous-graphique ax1 = fig.add_subplot(121, projection='3d') ax1.scatter(X_train[:, 0], X_train[:, 1], y_train, color='blue', marker='o', label='Train Data') ax1.scatter(X_train[:, 0], X_train[:, 1], y_pred_train, color='red', marker='^', label='Predictions') ax1.set_xlabel('X1') ax1.set_ylabel('X2') ax1.set_zlabel('Y') ax1.set_title('Training Data and Predictions') ax1.legend(loc='upper left') # Afficher les données de test et leurs prédictions sur le deuxième sous-graphique ax2 = fig.add_subplot(122, projection='3d') ax2.scatter(X_test[:, 0], X_test[:, 1], y_test, color='blue', marker='o', label='Test Data') ax2.scatter(X_test[:, 0], X_test[:, 1], y_pred_test, color='red', marker='^', label='Predictions') ax2.set_xlabel('X1') ax2.set_ylabel('X2') ax2.set_zlabel('Y') ax2.set_title('Test Data and Predictions') ax2.legend(loc='upper left') # Afficher les graphiques plt.show()
On peut maintenant sauvegarder le modèle de régression dans un fichier HDF5 en sauvegardant les poids et les biais :
# Sauvegarder le modèle dans un fichier HDF5 import h5py model_file = "linear_regression_model.h5" with h5py.File(model_file, "w") as f: # Enregistrer les poids et biais du modèle f.create_dataset("weights", data=model.coef_) f.create_dataset("bias", data=model.intercept_) # print(f["weights"].shape) # print(f["bias"].shape)
On peut ensuite chargé le modèle depuis le fichier HDF5 crée précédemment :
# Charger le modèle depuis le fichier HDF5 with h5py.File(model_file, "r") as f: # Récupérer les poids et biais du modèle weights = f["weights"][()] bias = f["bias"][()] # Instancier un nouveau modèle de régression linéaire avec les poids et biais enregistrés loaded_model = LinearRegression() loaded_model.coef_ = weights loaded_model.intercept_ = bias
On peut vérifier que nous avons bien notre modèle en affichant les poids et en faisant des prédictions sur les données train et test utilisés précédemment sans avoir besoin de l’entraîner au préalable :
# Le modèle chargé model = loaded_model # Obtenir les prédictions du modèle pour les données d'entrainement et de test y_pred_train = model.predict(X_train) y_pred_test = model.predict(X_test) # Créer un graphique 3D fig = plt.figure(figsize=(12, 5)) # Afficher les données d'entraiment et leurs prédictions sur le premier sous-graphique ax1 = fig.add_subplot(121, projection='3d') ax1.scatter(X_train[:, 0], X_train[:, 1], y_train, color='blue', marker='o', label='Train Data') ax1.scatter(X_train[:, 0], X_train[:, 1], y_pred_train, color='red', marker='^', label='Predictions') ax1.set_xlabel('X1') ax1.set_ylabel('X2') ax1.set_zlabel('Y') ax1.set_title('Training Data and Predictions') ax1.legend(loc='upper left') # Afficher les données de test et leurs prédictions sur le deuxième sous-graphique ax2 = fig.add_subplot(122, projection='3d') ax2.scatter(X_test[:, 0], X_test[:, 1], y_test, color='blue', marker='o', label='Test Data') ax2.scatter(X_test[:, 0], X_test[:, 1], y_pred_test, color='red', marker='^', label='Predictions') ax2.set_xlabel('X1') ax2.set_ylabel('X2') ax2.set_zlabel('Y') ax2.set_title('Test Data and Predictions') ax2.legend(loc='upper left') # Afficher les graphiques plt.show()
On peut constater que le modèle a bien été chargé.
En conclusion, le format de fichier HDF5 est une solution efficace et portable pour la sauvegarde et le chargement de modèles de machine learning. Ce format présente tout de même quelques inconvénients telles que la comptabilité car il n’est pas pris en charge par toutes les bibliothèques. Cela peut poser des problèmes si vous devez utiliser votre modèle avec une bibliothèque qui ne prend pas en charge le format HDF5. Aussi dans le cas des modèles de deep learning, ces fichiers peuvent devenir très vite trop volumineux.
Nous voilà arrivez à la fin de ce premier article. On retrouve très bientôt pour parler d’une des structures de sauvegarde les plus populaires : le format PICKLE.
Laisser un commentaire