2 votes

Comment alimenter plusieurs tableaux NumPy à un réseau d'apprentissage profond dans Keras ?

J'ai environ 13 tableaux NumPy stockés sous forme de fichiers qui occupent environ 24 gigaoctets sur le disque. Chaque fichier concerne un seul sujet et se compose de deux tableaux : l'un contenant les données d'entrée (une liste de matrices 2D, les lignes représentant le temps séquentiel), et l'autre contenant les étiquettes des données.

Mon objectif final est de transmettre toutes les données à un réseau d'apprentissage profond que j'ai écrit en Keras pour classer les nouvelles données. Mais je ne sais pas comment le faire sans manquer de mémoire.

J'ai lu des articles sur les générateurs de données de Keras, mais je ne trouve pas de moyen de les utiliser dans ma situation.

J'ai également consulté HDF5 et h5py, mais je ne sais pas comment ajouter toutes les données à un seul tableau (dataset en HDF5) sans manquer de mémoire.

2voto

Djib2011 Points 828

Ce qu'il faut faire, c'est mettre en place un générateur pour alimenter petit à petit votre modèle en données. Keras dispose d'une Générateur de séries chronologiques mais je ne pense pas que vous puissiez l'utiliser car il vous oblige à charger d'abord l'ensemble des données en mémoire. Heureusement, keras dispose d'un générateur d'images (appelé Générateur de données d'image ), sur lequel nous allons baser notre générateur personnalisé.

Deux mots d'abord sur son fonctionnement. Vous avez deux classes principales : la ImageDataGenerator classe (qui s'occupe principalement de tout prétraitement que vous souhaitez effectuer sur chaque image) et la classe DirectoryIterator qui, en fait, fait tout le travail. C'est cette dernière que nous allons modifier pour obtenir ce que nous voulons. Ce qu'elle fait essentiellement est :

  • Héritages de keras.preprocessing.image.Iterator qui implémente de nombreuses méthodes qui initialisent et génèrent un tableau appelé index_array qui contient les indices des images qui sont utilisées dans chaque lot. Ce tableau est modifié à chaque itération, tandis que les données dont il s'inspire sont mélangées à chaque époque. Nous allons construire notre générateur sur cette base, afin de maintenir sa fonctionnalité.
  • Recherche toutes les images sous un répertoire ; les étiquettes sont déduites de la structure du répertoire. Il stocke le chemin vers chaque image et son étiquette dans deux variables de classe appelées filenames y classes respectivement. Nous utiliserons ces mêmes variables pour stocker les emplacements des séries temporelles et leurs classes.
  • Il possède une méthode appelée _get_batches_of_transformed_samples() qui accepte un index_array charge les images dont les indices correspondent à ceux du tableau et retourne un lot de ces images et un autre contenant leurs classes.

Ce que je vous suggère de faire est :

  1. Écrivez un script qui structure vos données de séries temporelles comme vous êtes censé structurer les images lorsque vous utilisez l'ImageDataGenerator. Cela implique la création d'un répertoire pour chaque classe et de placer chaque série temporelle séparément dans ce répertoire. Bien que cela nécessite probablement plus de stockage que votre option actuelle, les données ne seront pas chargées en mémoire pendant l'entraînement du modèle.
  2. Apprenez à connaître le fonctionnement du Itérateur de répertoire travaux.
  3. Définissez votre propre classe de générateur (par ex. MyTimeseriesGenerator ). Assurez-vous qu'il hérite de de la Itérateur classe mentionnée ci-dessus.
  4. Modifiez-le de manière à ce qu'il recherche le format de fichiers que vous souhaitez (par ex. HDF5 , npy ) et non des formats d'image (par exemple png , jpeg ) comme il le fait actuellement. Ceci est fait dans les lignes 1733-1763. Vous Ne le fais pas. il faut le faire fonctionner sur plusieurs threads comme le fait le DirectoryIterator de keras, car cette procédure est effectuée une seule fois .
  5. Changez le _get_batches_of_transformed_samples() afin qu'elle lise le type de fichier que vous souhaitez, au lieu de lire les images (lignes 1774-1788). Retirer toute autre fonctionnalité liée aux images dont dispose le DirectoryIterator (transformation des images, normalisation, enregistrement, etc.)
  6. Assurez-vous que le tableau renvoyé par la méthode ci-dessus correspond à ce que vous voulez que votre modèle accepte. Je suppose qu'il devrait être dans les lignes de (batch_size, n_timesteps) o (batch_size, n_timesteps, n_feature) pour les données et (batch_size, n_classes) pour les étiquettes.

C'est à peu près tout ! Cela semble plus difficile que ça ne l'est en réalité. Une fois que vous vous serez familiarisé avec le Itérateur de répertoire tout le reste est trivial.

Utilisation prévue (après modification du code) :

from custom_generator import MyTimeseriesGenerator  # assuming you named your class 
                                                    # MyTimeseriesGenerator and you
                                                    # wrote it in a python file 
                                                    # named custom_generator

train_dir = 'path/to/your/properly/structured/train/directory'
valid_dir = 'path/to/your/properly/structured/validation/directory'

train_gen = MyTimeseriesGenerator(train_dir, batch_size=..., ...)
valid_gen = MyTimeseriesGenerator(valid_dir, batch_size=..., ...)

# instantiate and compile model, define hyper-parameters, callbacks, etc.

model.fit_generator(train_gen, validation_data=valid_gen, epochs=..., ...)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X