[PYTHON] [Version compatible TensorFlow 2.x] Comment entraîner une grande quantité de données à l'aide de TFRecord et DataSet dans TensorFlow (Keras)

introduction

Ceci est une version mise à jour de l'article précédent. Comment entraîner une grande quantité de données avec TFRecord & DataSet dans TensorFlow & Keras-Qiita

Une chose que je veux faire est "Je veux un moyen efficace d'entraîner d'énormes données qui ne tiennent pas dans la mémoire." C'est une méthode qui permet de traiter la lecture des données CPU et le calcul GPU en parallèle. Apprenez efficacement à partir des données enregistrées dans un format spécifique à l'aide de l'API DataSet.

Avec la sortie de TensorFlow 2, les noms des modules ont changé par rapport aux versions précédentes de l'article, et certains traitements sont devenus plus faciles à écrire. Dans cet article, je présenterai comment écrire dans TensorFlow 2, en me concentrant sur les différences par rapport au précédent. De plus, je changerai Keras pour utiliser celui inclus dans TensorFlow.

Préparation préalable

Cet article utilise Python 3.6.9 + TensorFlow 2.1.0 sous Linux (Ubuntu 18.04).

À partir de TensorFlow 1.15 / 2.1, les versions CPU et GPU du package pip ont été intégrées. Par conséquent, il y a des gens qui veulent l'essayer facilement avec le CPU et des gens qui veulent le transformer sérieusement avec le GPU.

pip3 install tensorflow==2.1.0

C'est acceptable. Veuillez noter que si vous souhaitez utiliser le GPU, vous devez configurer CUDA 10.1. GPU support | TensorFlow

Préparation des données

Il existe un format de données unique (TFRecord) qui permet à TensorFlow de calculer efficacement. Créons un TFRecord à partir de données existantes à l'aide de l'API DataSet.

data2tfrecord.py


#!/usr/bin/env python3

import numpy as np
import tensorflow as tf
from tensorflow.keras.datasets import mnist

def feature_float_list(l):
    return tf.train.Feature(float_list=tf.train.FloatList(value=l))

def record2example(r):
    return tf.train.Example(features=tf.train.Features(feature={
        "x": feature_float_list(r[0:-1]),
        "y": feature_float_list([r[-1]])
    }))

filename_train = "train.tfrecords"
filename_test  = "test.tfrecords"

# ===Lire les données MNIST===
#Par souci de simplicité, supposons que les mêmes données de vérification que les données d'évaluation sont utilisées pour les données de vérification pendant l'entraînement.
(x_train, y_train), (x_test, y_test) = mnist.load_data()
print("x_train   : ", x_train.shape) # x_train   :  (60000, 28, 28)
print("y_train   : ", y_train.shape) # y_train   :  (60000,)
print("x_test    : ", x_test.shape)  # x_test    :  (10000, 28, 28)
print("y_test    : ", y_test.shape)  # y_test    :  (10000,)

#Pré-traitement
#Pixel[0, 1]Convertir en type float32
#De plus, pour l'enregistrement TFR, rendez le montant de la caractéristique unidimensionnel (la ligne correspond à l'enregistrement)
x_train = x_train.reshape((-1, 28*28)).astype("float32") / 255.0
x_test  = x_test.reshape((-1, 28*28)).astype("float32") / 255.0
#L'étiquette est également de type float32
y_train = y_train.reshape((-1, 1)).astype("float32")
y_test  = y_test.reshape((-1, 1)).astype("float32")
#Combinez des fonctionnalités et des étiquettes pour l'enregistrement TFR
data_train = np.c_[x_train, y_train]
data_test = np.c_[x_test,  y_test]

#En fait, les données que vous souhaitez apprendre sont converties au même format et créées.
#Si toutes les données ne tiennent pas dans la mémoire, dans la phase d'écriture suivante
#Vous pouvez le faire petit à petit et répéter l'écriture.

#Écrire les données d'entraînement dans TFRecord
with tf.io.TFRecordWriter(filename_train) as writer:
    for r in data_train:
        ex = record2example(r)
        writer.write(ex.SerializeToString())

#Écrire les données d'évaluation dans TFRecord
with tf.io.TFRecordWriter(filename_test) as writer:
    for r in data_test:
        ex = record2example(r)
        writer.write(ex.SerializeToString())

C'est presque le même que la dernière fois, mais avec la mise à jour de la version de TensorFlow, le paquet tensorflow.python_io a disparu, et les fonctions liées à TFRecord ont été ajoutées à tensorflow.io. De plus, depuis que j'ai changé pour utiliser Keras inclus dans TensorFlow, «import» a changé, mais la méthode de lecture du jeu de données MNIST lui-même n'a pas changé.

Si vous n'avez pas de bibliothèque pour le calcul GPU, vous obtiendrez un AVERTISSEMENT lié à CUDA (les libcublas sont introuvables, etc.), mais si vous voulez juste l'essayer légèrement sur le CPU, vous n'avez pas à vous en soucier.

Apprentissage

Cela a un peu changé depuis la dernière fois. Commençons par le code, puis expliquons les différences.

train.py


#!/usr/bin/env python3

import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Dense, Input
from tensorflow.keras.optimizers import RMSprop
from tensorflow.keras.callbacks import ModelCheckpoint
from tensorflow.keras.models import Model

#Paramètres d'apprentissage
batch_size = 32
epochs = 10
#Paramètre de fonctionnalité
num_classes = 10    #Type d'étiquette. 0-10 types de 9
feature_dim = 28*28 #La dimension de la quantité d'entités. Manipuler comme 1D pour plus de simplicité
#Nombre de données d'apprentissage / d'évaluation. Vérifiez à l'avance.
#Notez que lorsque vous utilisez plusieurs TFRecords, le nombre ci-dessous est la somme de tous les fichiers.
num_records_train = 60000
num_records_test  = 10000
#Nombre de mini-lots par époque. Utilisé lors de l'apprentissage.
steps_per_epoch_train = (num_records_train-1) // batch_size + 1
steps_per_epoch_test  = (num_records_test-1) // batch_size + 1

#Décoder 1 TFRecord
def parse_example(example):
    features = tf.io.parse_single_example(
        example,
        features={
            #Spécifiez le nombre de dimensions lors de la lecture de la liste
            "x": tf.io.FixedLenFeature([feature_dim], dtype=tf.float32),
            "y": tf.io.FixedLenFeature([], dtype=tf.float32)
        })
    x = features["x"]
    y = features["y"]
    return x, y

# ===Préparer les données du fichier TFRecord pour l'apprentissage et l'évaluation===

dataset_train = tf.data.TFRecordDataset(["train.tfrecords"]) \
    .map(parse_example) \
    .shuffle(batch_size * 100) \
    .batch(batch_size).repeat(-1)
#Lorsque vous utilisez plusieurs fichiers TFRecord ci-dessus, spécifiez une liste de noms de fichiers.
# dataset_train = tf.data.TFRecordDataset(["train.tfrecords.{}".format(i) for i in range(10)]) \

dataset_test = tf.data.TFRecordDataset(["test.tfrecords"]) \
    .map(parse_example) \
    .batch(batch_size)

# ===Définition du modèle===
#Cette fois, une seule couche intermédiaire de 512 dimensions est spécifiée.
layer_input = Input(shape=(feature_dim,))
fc1 = Dense(512, activation="relu")(layer_input)
layer_output = Dense(num_classes, activation="softmax")(fc1)
model = Model(layer_input, layer_output)
model.summary()

#Perte même si l'étiquette est une variable catégorielle="sparse_categorical_crossentropy"Peut apprendre avec
#Étiqueter un-Si chaud vectorisé, perte="categorical_crossentropy"devenir
model.compile(
    loss="sparse_categorical_crossentropy",
    optimizer=RMSprop(),
    metrics=["accuracy"])

# ===Apprentissage===

#Enregistrez le modèle au milieu
cp_cb = ModelCheckpoint(
    filepath="weights.{epoch:02d}-{loss:.4f}-{val_loss:.4f}.hdf5",
    monitor="val_loss",
    verbose=1,
    save_best_only=True,
    mode="auto")
model.fit(
    x=dataset_train,
    epochs=epochs,
    verbose=1,
    steps_per_epoch=steps_per_epoch_train,
    validation_data=dataset_test,
    validation_steps=steps_per_epoch_test,
    callbacks=[cp_cb])

Différence par rapport à la fois précédente

`` tensorflow.keras.Model.fit () '' a changé pour pouvoir prendre un DataSet pour les données d'entraînement. tf.keras.Model | TensorFlow Core v2.1.0

x: Input data. It could be: (Omis) A tf.data dataset. Should return a tuple of either (inputs, targets) or (inputs, targets, sample_weights).

Auparavant, lors de l'apprentissage à partir d'un DataSet, vous deviez brancher des données dans la couche `ʻInput, il y avait donc une procédure fastidieuse de création de deux modèles avec des poids partagés, un pour la formation et un pour l'évaluation. Dans TensorFlow 2.x (Keras inclus dans), vous pouvez donner un DataSet à Model.fit () '', vous n'avez donc besoin que d'un seul modèle. Vous n'avez plus besoin de créer votre propre itérateur avec `` make_one_shot_iterator () ''. Tu l'as fait!

De plus, il était désormais possible de donner un DataSet pour évaluation à l'argument validation_data '' de tensorflow.keras.Model.fit () ''. Par conséquent, il n'est plus nécessaire de créer un callback pour l'évaluation par vous-même (bien que la barre de progression au moment de l'évaluation n'apparaisse pas ... C'est une histoire pour écrire une boucle d'apprentissage par vous-même).

Amélioration des performances avec plusieurs TFRecords

En chargeant plusieurs fichiers en parallèle, vous pourrez peut-être augmenter le taux d'utilisation du GPU (= accélérer l'apprentissage).

Divisez et écrivez les données d'entraînement de la même manière que la dernière fois. La seule différence par rapport à la dernière fois est que tf.python_io a changé en tf.io.

data2tfrecord.py (partie)


for i in range(10):
    with tf.io.TFRecordWriter(filename_train + "." + str(i)) as writer:
        for r in data_train[i::10]:
            ex = record2example(r)
            writer.write(ex.SerializeToString())

Pendant l'apprentissage, la création de `` dataset_train '' change comme suit.

train.py (partie)


dataset_train = tf.data.Dataset.from_tensor_slices(["train.tfrecords.{}".format(i) for i in range(10)]) \
    .interleave(
        lambda filename: tf.data.TFRecordDataset(filename).map(parse_example, num_parallel_calls=1),
        cycle_length=10) \
    .shuffle(batch_size * 100) \
    .batch(batch_size) \
    .prefetch(1) \
    .repeat(-1)

La fonction équivalente à tf.contrib.data.parallel_interleave () '' (plus tard tf.data.experimental.parallel_interleave () '') dans l'article précédent a été officiellement incorporée en tant que méthode de DataSet. C'est donc un peu plus facile à écrire. Cependant, il se comporte comme sloppy = False, il semble donc que vous deviez spécifier des options avec with_options () '' pour que cela fonctionne comme sloppy = True``. tf.data.experimental.parallel_interleave | TensorFlow Core v2.1.0

Passons à TensorFlow 2

Il y a des changements, mais c'est généralement plus facile à écrire, donc je sentais que je n'avais pas à avoir peur. Vous pouvez vous attendre à ce que les performances de base s'améliorent (est-ce vrai?), Et explorons beaucoup de données avec TensorFlow 2!

Recommended Posts

[Version compatible TensorFlow 2.x] Comment entraîner une grande quantité de données à l'aide de TFRecord et DataSet dans TensorFlow (Keras)
Comment créer une grande quantité de données de test dans MySQL? ??
Exemple d'agrégation d'une grande quantité de données de séries temporelles à l'aide de Python dans un petit environnement de mémoire à une vitesse raisonnable
Comment tester chaque version d'IE en utilisant Selenium avec modan.IE (VM)
Comment envoyer une image visualisée des données créées en Python à Typetalk
[Circuit x Python] Comment trouver la fonction de transfert d'un circuit en utilisant Lcapy
Un mémorandum sur l'utilisation de keras.preprocessing.image de Keras
Lire un grand nombre de rapports sur les titres en utilisant COTOHA
Comment exécuter une commande à l'aide d'un sous-processus en Python
Comment créer une instance d'une classe particulière à partir de dict en utilisant __new__ () en python
[Question] Comment obtenir les données des données textarea en temps réel à l'aide du flacon du framework Web Python
Comment représenter la distribution de la composition bactérienne à partir des données d'analyse Qiime2 dans un diagramme de moustaches
Comment passer le résultat de l'exécution d'une commande shell dans une liste en Python (version non bloquante)
[TensorFlow 2 / Keras] Comment exécuter l'apprentissage avec CTC Loss dans Keras
Comment développer dans un environnement virtuel Python [Memo]
Comment générer une requête à l'aide de l'opérateur IN dans Django
Comment obtenir une liste d'exceptions intégrées pour python
Comment obtenir un aperçu de vos données dans Pandas
Comment déterminer l'existence d'un élément sélénium en Python
J'ai essayé de créer une expression régulière de "montant" en utilisant Python
Comment vérifier la taille de la mémoire d'une variable en Python
TensorFlow Pour apprendre d'un grand nombre d'images ... ~ (presque) solution ~
Comment vérifier la taille de la mémoire d'un dictionnaire en Python
[TensorFlow 2] Comment vérifier le contenu de Tensor en mode graphique
Convertissez un grand nombre de fichiers PDF en fichiers texte à l'aide de pdfminer
<Pandas> Comment gérer les données de séries chronologiques dans le tableau croisé dynamique
Comment enregistrer une partie d'une longue vidéo en utilisant OpenCV
Comment obtenir les coordonnées de sommet d'une entité dans ArcPy
Explique comment utiliser TensorFlow 2.X avec l'implémentation de VGG16 / ResNet50
La première intelligence artificielle. Comment vérifier la version de Tensorflow installée.
Comment mettre à jour une source de données de classeur packagée Tableau à l'aide de Python
Comment copier et coller le contenu d'une feuille au format JSON avec une feuille de calcul Google (en utilisant Google Colab)
Comment exécuter du code TensorFlow 1.0 en 2.0
Comment diviser et traiter une trame de données à l'aide de la fonction groupby
Comment faire un modèle pour la détection d'objets avec YOLO en 3 heures
[Python] Comment mettre n'importe quel nombre d'entrées standard dans la liste
Comment obtenir la valeur du magasin de paramètres dans lambda (en utilisant python)
Comment tracer les données de lumière visible d'une galaxie à l'aide de la base de données OpenNGC en python
Version de juin 2017 pour créer un environnement Tensorflow / Keras sur une instance GPU d'AWS
Comment bien formater une liste de dictionnaires (ou d'instances) en Python
J'ai essayé d'effectuer une analyse de cluster de clients à l'aide des données d'achat
[Python] [Word] [python-docx] Essayez de créer un modèle de phrase de mot en Python en utilisant python-docx
TensorFlow Pour apprendre d'un grand nombre d'images ... (Problème non résolu) → 12/18 Résolu
Comment créer un ensemble de données d'image de visage utilisé dans l'apprentissage automatique (1: Acquérir des images de candidats à l'aide du service API Web)
J'ai créé un programme en Python qui lit les données FX CSV et crée un grand nombre d'images de graphiques