Ich bin relativ neu in der Welt von TensorFlow und ziemlich ratlos darüber, wie Sie CSV-Daten tatsächlich in TensorFlow in verwendbare Beispiel- / Etikettentensoren einlesen würden. Das Beispiel aus dem TensorFlow-Tutorial zum Lesen von CSV-Daten ist ziemlich fragmentiert und gibt Ihnen nur einen Teil des Weges zum Trainieren von CSV-Daten.
Hier ist mein Code, den ich basierend auf diesem CSV-Tutorial zusammengestellt habe:
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")
Und hier ist ein kurzes Beispiel aus der CSV-Datei, die ich lade - ziemlich grundlegende Daten - 4 Feature-Spalten und 1 Beschriftungsspalte:
0,0,0,0,0
0,15,0,0,0
0,30,0,0,0
0,45,0,0,0
Der obige Code druckt lediglich jedes Beispiel einzeln aus der CSV-Datei , was zwar nett, aber für das Training verdammt nutzlos ist.
Ich habe hier Probleme damit, wie Sie diese einzelnen Beispiele, die einzeln geladen werden, tatsächlich in einen Trainingsdatensatz umwandeln. Hier ist zum Beispiel ein Notizbuch, an dem ich im Udacity Deep Learning-Kurs gearbeitet habe. Grundsätzlich möchte ich die CSV-Daten, die ich lade, in etwas wie train_dataset und train_labels kopieren :
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)
Ich habe versucht tf.train.shuffle_batch
, so etwas zu verwenden, aber es hängt unerklärlicherweise:
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)
Zusammenfassend sind hier meine Fragen:
- Was fehlt mir an diesem Prozess?
- Es scheint, als ob mir eine wichtige Intuition fehlt, wie man eine Eingabepipeline richtig erstellt.
- Gibt es eine Möglichkeit, die Länge der CSV-Datei nicht zu kennen?
- Es fühlt sich ziemlich unelegant an, die Anzahl der zu verarbeitenden Zeilen kennen zu müssen (die
for i in range(file_length)
Codezeile oben).
- Es fühlt sich ziemlich unelegant an, die Anzahl der zu verarbeitenden Zeilen kennen zu müssen (die
Bearbeiten: Sobald Jaroslaw darauf hinwies, dass ich hier wahrscheinlich imperative und grafische Konstruktionsteile verwechseln würde, wurde es klarer. Ich konnte den folgenden Code zusammenstellen, der meiner Meinung nach näher an dem liegt, was normalerweise beim Trainieren eines Modells aus CSV (ohne Modell-Trainingscode) gemacht wird:
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)
quelle
Antworten:
Ich denke, Sie verwechseln hier imperative und grafische Konstruktionsteile. Die Operation
tf.train.shuffle_batch
erstellt einen neuen Warteschlangenknoten, und ein einzelner Knoten kann zum Verarbeiten des gesamten Datensatzes verwendet werden. Ich denke, Sie hängen, weil Sie eine Reihe vonshuffle_batch
Warteschlangen in Ihrer for-Schleife erstellt und keine Warteschlangenläufer für sie gestartet haben.Die normale Verwendung der Eingabepipeline sieht folgendermaßen aus:
shuffle_batch
, die eine Pipeline eingeben möchten--- Ende der Graphkonstruktion, Beginn der imperativen Programmierung -
tf.start_queue_runners
while(True): session.run()
Um skalierbarer zu sein (um Python GIL zu vermeiden), können Sie alle Ihre Daten mithilfe der TensorFlow-Pipeline generieren. Wenn die Leistung jedoch nicht kritisch ist, können Sie ein Numpy-Array an eine Eingabepipeline anschließen. Verwenden Sie
slice_input_producer.
hier ein Beispiel mit einigenPrint
Knoten, um zu sehen, was los ist (Nachrichten inPrint
gehen an stdout, wenn der Knoten ausgeführt wird).Sie sollten so etwas sehen
Die "8, 9" -Nummern füllten nicht die gesamte Charge aus, sodass sie nicht produziert wurden. Sie
tf.Print
werden auch in sys.stdout gedruckt, sodass sie für mich separat im Terminal angezeigt werden.PS: Eine minimale Anzahl von Verbindungen
batch
zu einer manuell initialisierten Warteschlange befindet sich in Github-Ausgabe 2193Zu Debugging-Zwecken möchten Sie möglicherweise
timeout
eine Sitzung festlegen, damit Ihr IPython-Notizbuch nicht an leeren Warteschlangenwarteschlangen hängt. Ich benutze diese Hilfsfunktion für meine SitzungenHinweise zur Skalierbarkeit:
tf.constant
Inline-Kopie Ihrer Daten in das Diagramm. Es gibt eine grundlegende Grenze von 2 GB für die Größe der Diagrammdefinition, sodass dies eine Obergrenze für die Datengröße istv=tf.Variable
die Daten verwenden und dort speichern, indem Siev.assign_op
mit einemtf.placeholder
auf der rechten Seite ausführen und dem Platzhalter ein numpy-Array zuweisen (feed_dict
).slice_input_producer
erstellen, die auf Numpy-Arrays ausgeführt wird, und Zeilen einzeln mit hochladenfeed_dict
quelle
tf.slice_input_producer()
durchtf.train.slice_input_producer()
(und ähnlich für mehrere andere Funktionen). Und auchsess.run(tf.initialize_local_variables())
nachher hinzufügensess.run(tf.initialize_all_variables())
.pack()
ist jetztstack()
undinitialize_all_variables()
sollte durchglobal_variables_initializer()
und ersetzt werdenlocal_variables_initializer()
.tf.group(tf.global_variables_initializer(), tf.local_variables_initializer()).run()
. Sie müssen lokale Variablen initialisieren, da Sie num_epochs verwenden und gemäß Dokumentation "Hinweis: Wenn diesnum_epochs
nicht derNone
epochs
Oder Sie könnten dies versuchen, der Code lädt den Iris-Datensatz mithilfe von Pandas und Numpy in den Tensorflow und eine einfache Ausgabe mit einem Neuron wird in der Sitzung gedruckt. Hoffe, es hilft für ein grundlegendes Verständnis .... [Ich habe nicht den Weg eines heißen Dekodierungsetiketts hinzugefügt].
quelle
Sie können die neueste tf.data-API verwenden:
quelle
Wenn jemand hierher gekommen ist, um nach einer einfachen Möglichkeit zu suchen, absolut große und gesplittete CSV-Dateien in der tf.estimator-API zu lesen, siehe unten meinen Code
Beispiel für die Verwendung in TF.estimator:
quelle
2.0-kompatible Lösung : Diese Antwort wird möglicherweise von anderen im obigen Thread bereitgestellt, aber ich werde zusätzliche Links bereitstellen, die der Community helfen.
Weitere Informationen finden Sie in diesem Tensorflow-Tutorial .
quelle