Je suis relativement nouveau dans le monde de TensorFlow et assez déconcerté par la manière dont vous avez réellement lire les données CSV dans un exemple de tenseurs/étiquettes utilisables dans TensorFlow. L'exemple tiré du didacticiel TensorFlow sur la lecture de données CSV est assez fragmenté et ne vous permet qu'une partie du processus de formation sur les données CSV.
Voici le code que j'ai reconstitué à partir de ce tutoriel CSV:
from __future__ import print_function
import tensorflow as tf
def file_len(fname):
with open(fname) as f:
for i, l in enumerate(f):
pass
return i + 1
filename = "csv_test_data.csv"
# setup text reader
file_length = file_len(filename)
filename_queue = tf.train.string_input_producer([filename])
reader = tf.TextLineReader(skip_header_lines=1)
_, csv_row = reader.read(filename_queue)
# setup CSV decoding
record_defaults = [[0],[0],[0],[0],[0]]
col1,col2,col3,col4,col5 = tf.decode_csv(csv_row, record_defaults=record_defaults)
# turn features back into a tensor
features = tf.stack([col1,col2,col3,col4])
print("loading, " + str(file_length) + " line(s)\n")
with tf.Session() as sess:
tf.initialize_all_variables().run()
# start populating filename queue
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
for i in range(file_length):
# retrieve a single instance
example, label = sess.run([features, col5])
print(example, label)
coord.request_stop()
coord.join(threads)
print("\ndone loading")
Et voici un bref exemple tiré du fichier CSV que je suis en train de charger - données plutôt basiques - 4 colonnes de fonction et une colonne d'étiquette:
0,0,0,0,0
0,15,0,0,0
0,30,0,0,0
0,45,0,0,0
Tout le code ci-dessus ne fait imprimer chaque exemple à partir du fichier CSV, un par un , ce qui, bien que Nice, est vachement inutile pour la formation.
Ce qui me pose problème ici, c'est comment transformer ces exemples individuels, chargés un par un, en un ensemble de données de formation. Par exemple, voici un cahier je travaillais sur le cours Udacity Deep Learning. Je veux fondamentalement prendre les données CSV que je charge et les insérer dans quelque chose comme train_dataset et train_labels :
def reformat(dataset, labels):
dataset = dataset.reshape((-1, image_size * image_size)).astype(np.float32)
# Map 2 to [0.0, 1.0, 0.0 ...], 3 to [0.0, 0.0, 1.0 ...]
labels = (np.arange(num_labels) == labels[:,None]).astype(np.float32)
return dataset, labels
train_dataset, train_labels = reformat(train_dataset, train_labels)
valid_dataset, valid_labels = reformat(valid_dataset, valid_labels)
test_dataset, test_labels = reformat(test_dataset, test_labels)
print('Training set', train_dataset.shape, train_labels.shape)
print('Validation set', valid_dataset.shape, valid_labels.shape)
print('Test set', test_dataset.shape, test_labels.shape)
J'ai essayé d'utiliser tf.train.shuffle_batch
, comme ceci, mais il se bloque inexplicablement:
for i in range(file_length):
# retrieve a single instance
example, label = sess.run([features, colRelevant])
example_batch, label_batch = tf.train.shuffle_batch([example, label], batch_size=file_length, capacity=file_length, min_after_dequeue=10000)
print(example, label)
Donc pour résumer, voici mes questions:
for i in range(file_length)
ci-dessus)Edit: Dès que Yaroslav a fait remarquer que j’étais probablement en train de mélanger des éléments de construction impérative et graphique, cela a commencé à devenir plus clair. J'ai pu rassembler le code suivant, ce qui, je pense, est plus proche de ce que ferait généralement la formation d'un modèle à partir d'un fichier CSV (à l'exclusion de tout code de formation de modèle):
from __future__ import print_function
import numpy as np
import tensorflow as tf
import math as math
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('dataset')
args = parser.parse_args()
def file_len(fname):
with open(fname) as f:
for i, l in enumerate(f):
pass
return i + 1
def read_from_csv(filename_queue):
reader = tf.TextLineReader(skip_header_lines=1)
_, csv_row = reader.read(filename_queue)
record_defaults = [[0],[0],[0],[0],[0]]
colHour,colQuarter,colAction,colUser,colLabel = tf.decode_csv(csv_row, record_defaults=record_defaults)
features = tf.stack([colHour,colQuarter,colAction,colUser])
label = tf.stack([colLabel])
return features, label
def input_pipeline(batch_size, num_epochs=None):
filename_queue = tf.train.string_input_producer([args.dataset], num_epochs=num_epochs, shuffle=True)
example, label = read_from_csv(filename_queue)
min_after_dequeue = 10000
capacity = min_after_dequeue + 3 * batch_size
example_batch, label_batch = tf.train.shuffle_batch(
[example, label], batch_size=batch_size, capacity=capacity,
min_after_dequeue=min_after_dequeue)
return example_batch, label_batch
file_length = file_len(args.dataset) - 1
examples, labels = input_pipeline(file_length, 1)
with tf.Session() as sess:
tf.initialize_all_variables().run()
# start populating filename queue
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
try:
while not coord.should_stop():
example_batch, label_batch = sess.run([examples, labels])
print(example_batch)
except tf.errors.OutOfRangeError:
print('Done training, Epoch reached')
finally:
coord.request_stop()
coord.join(threads)
Je pense que vous mélangez ici des éléments impératifs et graphiques. L'opération _tf.train.shuffle_batch
_ crée un nouveau nœud de file d'attente. Un seul nœud peut être utilisé pour traiter l'ensemble de données. Je pense donc que vous vous attardez parce que vous avez créé un groupe de files d'attente _shuffle_batch
_ dans votre boucle for et que vous n'avez pas démarré les coureurs de files d'attente pour elles.
L’utilisation normale du pipeline d’entrée ressemble à ceci:
shuffle_batch
_ au pipeline d'entrée--- fin de la construction du graphe, début de la programmation impérative -
tf.start_queue_runners
_while(True): session.run()
Pour être plus évolutif (pour éviter Python GIL), vous pouvez générer toutes vos données à l'aide du pipeline TensorFlow. Toutefois, si les performances ne sont pas critiques, vous pouvez connecter un tableau numpy à un pipeline d'entrée à l'aide de _slice_input_producer.
_ Voici un exemple avec quelques nœuds Print
pour voir ce qu'il se passe (messages dans Print
aller à la sortie standard lorsque le noeud est exécuté)
_tf.reset_default_graph()
num_examples = 5
num_features = 2
data = np.reshape(np.arange(num_examples*num_features), (num_examples, num_features))
print data
(data_node,) = tf.slice_input_producer([tf.constant(data)], num_epochs=1, shuffle=False)
data_node_debug = tf.Print(data_node, [data_node], "Dequeueing from data_node ")
data_batch = tf.batch([data_node_debug], batch_size=2)
data_batch_debug = tf.Print(data_batch, [data_batch], "Dequeueing from data_batch ")
sess = tf.InteractiveSession()
sess.run(tf.initialize_all_variables())
tf.get_default_graph().finalize()
tf.start_queue_runners()
try:
while True:
print sess.run(data_batch_debug)
except tf.errors.OutOfRangeError as e:
print "No more inputs."
_
Vous devriez voir quelque chose comme ça
_[[0 1]
[2 3]
[4 5]
[6 7]
[8 9]]
[[0 1]
[2 3]]
[[4 5]
[6 7]]
No more inputs.
_
Les numéros "8, 9" n'ont pas rempli le lot complet, ils n'ont donc pas été produits. De plus, _tf.Print
_ sont imprimés sur sys.stdout, ils apparaissent donc séparément dans Terminal pour moi.
PS: un minimum de connexion de batch
à une file d'attente initialisée manuellement est dans numéro 2193 de github
De plus, pour le débogage, vous pouvez définir timeout
sur votre session afin que votre bloc-notes IPython ne se bloque pas sur les files d'attente vides. J'utilise cette fonction d'assistance pour mes sessions
_def create_session():
config = tf.ConfigProto(log_device_placement=True)
config.gpu_options.per_process_gpu_memory_fraction=0.3 # don't hog all vRAM
config.operation_timeout_in_ms=60000 # terminate on long hangs
# create interactive session to register a default session
sess = tf.InteractiveSession("", config=config)
return sess
_
Notes d'évolutivité:
tf.constant
_ copie en ligne de vos données dans le graphique. Il y a une limite fondamentale de 2 Go sur la taille de la définition de graphique, donc c'est une limite supérieure sur la taille des donnéesv=tf.Variable
_ et en y enregistrant les données en exécutant _v.assign_op
_ avec un _tf.placeholder
_ à droite et en insérant un tableau numpy dans l'espace réservé (_feed_dict
_)slice_input_producer
_ qui fonctionne sur des tableaux numpy et télécharger des lignes une par une à l’aide de _feed_dict
_.Vous pouvez également essayer ceci: le code charge le jeu de données Iris dans tensorflow à l'aide de pandas et de numpy, et une sortie simple d'un neurone est imprimée dans la session. J'espère que cela vous aidera pour une compréhension de base .... [Je n'ai pas ajouté la méthode des étiquettes à décodage à chaud].
import tensorflow as tf
import numpy
import pandas as pd
df=pd.read_csv('/home/nagarjun/Desktop/Iris.csv',usecols = [0,1,2,3,4],skiprows = [0],header=None)
d = df.values
l = pd.read_csv('/home/nagarjun/Desktop/Iris.csv',usecols = [5] ,header=None)
labels = l.values
data = numpy.float32(d)
labels = numpy.array(l,'str')
#print data, labels
#tensorflow
x = tf.placeholder(tf.float32,shape=(150,5))
x = data
w = tf.random_normal([100,150],mean=0.0, stddev=1.0, dtype=tf.float32)
y = tf.nn.softmax(tf.matmul(w,x))
with tf.Session() as sess:
print sess.run(y)
Vous pouvez utiliser la dernière API tf.data:
dataset = tf.contrib.data.make_csv_dataset(filepath)
iterator = dataset.make_initializable_iterator()
columns = iterator.get_next()
with tf.Session() as sess:
sess.run([iteator.initializer])
Si quelqu'un est venu ici à la recherche d'un moyen simple de lire des fichiers CSV absolument volumineux et fragmentés dans l'API tf.estimator, veuillez voir ci-dessous mon code
CSV_COLUMNS = ['ID','text','class']
LABEL_COLUMN = 'class'
DEFAULTS = [['x'],['no'],[0]] #Default values
def read_dataset(filename, mode, batch_size = 512):
def _input_fn(v_test=False):
# def decode_csv(value_column):
# columns = tf.decode_csv(value_column, record_defaults = DEFAULTS)
# features = dict(Zip(CSV_COLUMNS, columns))
# label = features.pop(LABEL_COLUMN)
# return add_engineered(features), label
# Create list of files that match pattern
file_list = tf.gfile.Glob(filename)
# Create dataset from file list
#dataset = tf.data.TextLineDataset(file_list).map(decode_csv)
dataset = tf.contrib.data.make_csv_dataset(file_list,
batch_size=batch_size,
column_names=CSV_COLUMNS,
column_defaults=DEFAULTS,
label_name=LABEL_COLUMN)
if mode == tf.estimator.ModeKeys.TRAIN:
num_epochs = None # indefinitely
dataset = dataset.shuffle(buffer_size = 10 * batch_size)
else:
num_epochs = 1 # end-of-input after this
batch_features, batch_labels = dataset.make_one_shot_iterator().get_next()
#Begins - Uncomment for testing only -----------------------------------------------------<
if v_test == True:
with tf.Session() as sess:
print(sess.run(batch_features))
#End - Uncomment for testing only -----------------------------------------------------<
return add_engineered(batch_features), batch_labels
return _input_fn
Exemple d'utilisation dans TF.estimator:
train_spec = tf.estimator.TrainSpec(input_fn = read_dataset(
filename = train_file,
mode = tf.estimator.ModeKeys.TRAIN,
batch_size = 128),
max_steps = num_train_steps)