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 :
- É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.
- Apprenez à connaître le fonctionnement du Itérateur de répertoire travaux.
- 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.
- 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 .
- 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.)
- 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=..., ...)