Comment faire pour extraire des données à l'aide d'un custom python fonction dans tensorflow
Je suis en train de prélecture de données de formation pour masquer la latence d'e/S. Je voudrais écrire personnalisé de code Python qui charge les données à partir du disque et prétraite les données (par exemple, par l'ajout d'une fenêtre contextuelle). En d'autres termes, un thread ne pré-traitement de données et l'autre de la formation. Est-ce possible dans TensorFlow?
Mise à jour: j'ai un exemple de travail basé sur @mrry l'exemple.
import numpy as np
import tensorflow as tf
import threading
BATCH_SIZE = 5
TRAINING_ITERS = 4100
feature_input = tf.placeholder(tf.float32, shape=[128])
label_input = tf.placeholder(tf.float32, shape=[128])
q = tf.FIFOQueue(200, [tf.float32, tf.float32], shapes=[[128], [128]])
enqueue_op = q.enqueue([label_input, feature_input])
label_batch, feature_batch = q.dequeue_many(BATCH_SIZE)
c = tf.reshape(feature_batch, [BATCH_SIZE, 128]) + tf.reshape(label_batch, [BATCH_SIZE, 128])
sess = tf.Session()
def load_and_enqueue(sess, enqueue_op, coord):
with open('dummy_data/features.bin') as feature_file, open('dummy_data/labels.bin') as label_file:
while not coord.should_stop():
feature_array = np.fromfile(feature_file, np.float32, 128)
if feature_array.shape[0] == 0:
print('reach end of file, reset using seek(0,0)')
feature_file.seek(0,0)
label_file.seek(0,0)
continue
label_value = np.fromfile(label_file, np.float32, 128)
sess.run(enqueue_op, feed_dict={feature_input: feature_array,
label_input: label_value})
coord = tf.train.Coordinator()
t = threading.Thread(target=load_and_enqueue, args=(sess,enqueue_op, coord))
t.start()
for i in range(TRAINING_ITERS):
sum = sess.run(c)
print('train_iter='+str(i))
print(sum)
coord.request_stop()
coord.join([t])
- Je viens de faire un carnet de notes sur les files d'attente qui explique aussi l'utilisation du même cas, j'espère que cela peut être utile à d'autres: gist.github.com/akiross/23b6ae42812841bb79af4976a2525cf9
- ce site web ne peut pas être consulté...
Vous devez vous connecter pour publier un commentaire.
Il s'agit d'un cas d'utilisation, et la plupart des implémentations utilisent TensorFlow de files d'attente pour découpler le prétraitement code de la formation code. Il est un tutoriel sur la façon d'utiliser les files d'attente, mais les principales étapes sont comme suit:
Définir une file d'attente,
q
, qui va tampon de la séquence de données. TensorFlow prend en charge le simpletf.FIFOQueue
qui produit les éléments dans l'ordre où ils ont été mis en file d'attente, et les plus avancéstf.RandomShuffleQueue
qui produit des éléments dans un ordre aléatoire. Un élément de la file d'attente est un n-uplet d'un ou de plusieurs tenseurs (qui peut avoir différents types et formes). Toutes les files d'attente de support de l'élément unique (enqueue
,dequeue
) et le lot (enqueue_many
,dequeue_many
) de l'exploitation, mais d'utiliser les opérations de traitement par lots, vous devez spécifier les formes de chaque tenseur dans une file d'attente de l'élément lors de la construction de la file d'attente.Construire un sous-graphe qui enqueues séquence d'éléments dans la file d'attente. Une façon de le faire serait de définir certains
tf.espace réservé()
de la fpo pour les tenseurs correspondant à une seule entrée exemple, puis de les transmettre àq.enqueue()
. (Si votre prétraitement produit d'un lot à la fois, vous devez utiliserq.enqueue_many()
à la place.) Vous pouvez également inclure TensorFlow ops dans ce sous-graphe.Construire un sous-graphe qui effectue la formation. Cela va ressembler à un régulière TensorFlow graphique, mais obtiendra son entrée en appelant
q.dequeue_many(BATCH_SIZE)
.Commencer votre session.
Créer un ou plusieurs threads qui exécutent votre prétraitement de la logique, puis exécutez la mise en file d'op, de l'alimentation dans la séquence de données. Vous pouvez trouver la
tf.le train.Coordonnateur
ettf.le train.QueueRunner
classes utilitaires utiles pour cela.Exécuter votre formation graphique (optimiseur, etc.) comme d'habitude.
EDIT: Ici est un simple
load_and_enqueue()
fonction et le fragment de code pour vous aider à démarrer:read()
de la fpo et leenqueue()
op dans le même appel àSession.run()
, et il n'y a qu'un seul fil conducteur qui sous-graphe à la fois, la cartographie sera préservée. (Notez que vous trouverez peut-être plus facile à mettre en œuvre tous de la lecture de la logique en Python, en utilisant par exemplenumpy.fromfile()
de lire un lot à partir de chaque fichier, et ensuite mettre en file d'attente d'un lot d'enregistrements à la fois. Cette approche pourrait aussi être plus efficace si vous avez un grand nombre de petits enregistrements).sess.run()
de deux threads différents, elles s'exécutent en parallèle.sess.run()
, la file d'attente à conserver cette cartographie. (Notez que si votre distorsion peut être mis en œuvre dans TensorFlow, vous pourriez être mieux d'avoir un thread en cours d'exécutionload_and_enqueue()
, et un ensemble de threads que de retirer des éléments de la file d'attente d'entrée, d'appliquer la distorsion, et de mettre en file d'attente de la déformée de données à une autre file d'attente,q2
. La formation de cette étape de l'utilisationq2
comme entrée. Le HOWTO explique cette.seek()
pour déplacer chaque thread à une position différente.)load_and_enqueue
fonction? désolé, peut-être que c'est évident, mais je suis nouveau sur le python...args=(sess,enqueue_op, coord)
comme il a été à la question de l'auteur?load_and_enqueue()
ne devriez pas avoir besoin de tous les arguments, parce que la fonction imbriquée peut capturer les variables ci-dessus. Vous avez raison que l'ajout deargs=(...)
à laThread
constructeur est une autre façon de passer des arguments si vous en avez besoin.TRAINING_EPOCHS
est, disons, 2,load_and_enqueue
sera exécuté par le biais de la fonctionnalité / les fichiers d'étiquettes à la fois et puis le retour, provoquant le fil à la sortie. TensorFlow a pas la possibilité d'invoquer cette fonction, et donc il va être d'essayer d'obtenir des données qui n'est pas là et va s'accrocher indéfiniment.Oui, il est. mrry la solution fonctionne, mais en plus simple existe.
De l'extraction de données
tf.py_func
enroule une fonction python et l'utilise comme un TensorFlow de l'opérateur. Donc on peut charger les données àsess.run()
à chaque fois. Le problème avec cette approche est que les données sont chargées pendantsess.run()
par le thread principal.Un exemple minimal:
Un exemple plus complexe:
Le pré-chargement de données dans un autre thread
À la file d'attente de nos données dans un autre thread (de sorte que
sess.run()
n'aurez pas à attendre pour les données), on peut utilisertf.le train.lot()
sur nos opérateurs detf.py_func()
.Un exemple minimal:
Nous pouvons omettre l'argument
shapes
sitensorflow_tensor
a sa forme spécifiée:Un exemple plus complexe:
En cas
get_numpy_tensor()
retourne un lot de tenseurs, puistf.train.batch(..., enqueue_many=True)
aidera.