2016-05-07 22 views
62

Jestem stosunkowo nowy w świecie TensorFlow, i bardzo zakłopotany tym, jak można odczytać dane CSV w użytecznym tensorze przykładów/etykiet w TensorFlow. Przykład z TensorFlow tutorial on reading CSV data jest dość fragmentaryczny i zapewnia tylko część możliwości uczenia się na danych CSV.Jak * faktycznie * odczytać dane CSV w TensorFlow?

Oto mój kod, który mam poskładane, że opiera się poradnik 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") 

I tu jest krótki przykład z pliku CSV Jestem ładowania - dość podstawowe dane - 4 kolumny funkcji, kolumna 1 i etykieta:

0,0,0,0,0 
0,15,0,0,0 
0,30,0,0,0 
0,45,0,0,0 

przede wszystkim kod robi to druku każdy przykład z pliku CSV, jeden po drugim, które, choć ładne, jest cholernie bezużyteczny dla treningu.

To, z czym się zmagam, to jak poszczególne przykłady, ładowane jeden po drugim, można wykorzystać w zbiorze danych treningowych. Na przykład here's a notebook Pracowałem nad kursami Udacity Deep Learning. Zasadniczo chcę, aby podjąć danych CSV Mam załadunku i rzuć go w coś jak train_dataset i 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) 

Próbowałem za pomocą tf.train.shuffle_batch, tak, ale tylko w niewytłumaczalny sposób rozłącza:

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) 

Więc Podsumowując, oto moje pytania:

  • Czego mi brakuje w tym procesie?
    • Czuję, że brakuje mi jakiejś kluczowej intuicji na temat prawidłowego budowania rurociągu wejściowego.
  • Czy istnieje sposób na uniknięcie konieczności sprawdzania długości pliku CSV?
    • Czuje się bardzo nieeleganckie musiał znać liczbę wierszy, które chcesz przetwarzać (linia for i in range(file_length) kodu powyżej)

Edit: Jak tylko Jarosław zauważył, że prawdopodobnie wymieszałem tutaj elementy imperatywne i graficzne, zaczęło być wyraźniejsze. Udało mi się wyciągnąć razem następujący kod, który moim zdaniem jest bliżej do tego, co zazwyczaj odbywa się podczas treningu model z CSV (z wyłączeniem dowolnego kodu modelu szkolenia):

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) 
+0

Próbowałem twój kod, ale nie mogę go uruchomić. Czy jest coś czego mi brakuje? Dzięki. Wysłałem tu wątek, aby uzyskać więcej informacji: http://stackoverflow.com/questions/40143019/how-to-correctly-read-data-from-csvs-into-tensorflow – Link

Odpowiedz

18

Myślę, że mieszanie się imperatywem i wykres -konstrukcje tutaj. Operacja tf.train.shuffle_batch tworzy nowy węzeł kolejki, a pojedynczy węzeł może być używany do przetwarzania całego zestawu danych.Więc myślę, że wiesz, ponieważ stworzyłeś kilka kolejek w pętli for i nie uruchomiłeś dla nich kolejki.

Normalne użytkowanie gazociągu wejściowe wygląda następująco:

  1. Dodaj węzły jak shuffle_batch do rurociągu wejściowym
  2. (opcja, aby zapobiec przypadkowemu modyfikację wykres) sfinalizować wykres

--- Koniec konstrukcja wykresu, początek bezwzględnej programowania -

  1. tf.start_queue_runners
  2. while(True): session.run()

Aby być bardziej skalowalne (aby uniknąć Python GIL), można generować wszystkie dane za pomocą TensorFlow rurociągu. Jednakże, jeśli wydajność nie jest krytyczna, można podłączyć do numpy tablicę do rurociągu wejściowego za pomocą slice_input_producer. Oto przykład z niektórych Print węzłów, aby zobaczyć, co się dzieje (komunikaty w Print iść do stdout, gdy węzeł jest prowadzony)

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." 

Powinieneś zobaczyć coś takiego

[[0 1] 
[2 3] 
[4 5] 
[6 7] 
[8 9]] 
[[0 1] 
[2 3]] 
[[4 5] 
[6 7]] 
No more inputs. 

w „8, 9” liczby nie zapełnić całą partię, więc nie dostali produkowane. Również tf.Print są drukowane na sys.stdout, więc pojawiają się osobno w Terminalu dla mnie.

PS: minimalna podłączenia batch do ręcznie zainicjowany kolejce jest github issue 2193

Również dla celów debugowania może chcesz ustawić timeout na sesji, dzięki czemu notebook ipython nie powiesić na pustych dequeues kolejki . Używam tej funkcji pomocnika dla moich sesjach

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 

Skalowalność Uwagi:

  1. tf.constant inlines kopii danych na wykresie. Jest podstawowym limit 2GB na wielkość definicji Graph więc to górny limit rozmiaru danych
  2. Można ominąć ten limit za pomocą v=tf.Variable i zapisywania danych do nie uruchamiając v.assign_op z tf.placeholder na prawej stronie i karmienie numpy tablicy do zastępczego (feed_dict)
  3. To nadal tworzy dwie kopie danych, tak aby zaoszczędzić pamięć można zrobić własną wersję slice_input_producer która działa na numPy tablic, i przesyła wierszy jednej naraz używając feed_dict
+2

Ahh, tak! Masz całkowitą rację - tak szybko, jak powiedziałeś: "Myślę, że mieszasz tutaj elementy imperatywne i graficzne", zacząłem dostrzegać, gdzie się nie myliłem. Opublikowalem poprawke do mojego pytania, które zawiera najnowszy napisany przeze mnie kod, który faktycznie przybliża mnie do tego, co chcę - jestem w stanie z powodzeniem odczytać dane w CSV i wsypać je w taki sposób, żebym mógł wyszkolić Model. –

+2

Sugeruję aktualizację tej odpowiedzi, aby działała z ostatnimi wersjami TensorFlow: zamień 'tf.slice_input_producer()' z 'tf.train.slice_input_producer()' (i podobnie dla kilku innych funkcji). A także dodaj 'sess.run (tf.initialize_local_variables())' po 'sess.run (tf.initialize_all_variables())'. – MiniQuark

+0

Kilka dodatkowych zmian: 'pack()' jest teraz 'stack()', a 'initialize_all_variables()' powinno zostać zamienione na 'global_variables_initializer()' i 'local_variables_initializer()'. – MiniQuark

11

Albo możesz spróbować tego, kod ładuje zbiór danych Iris do tensora przepływ przy użyciu pand i numpy oraz proste jedno wyjście neuronu jest drukowane w sesji. Mam nadzieję, że pomoże to w podstawowym zrozumieniu ... [Nie dodałem jeszcze sposobu na jedną z gorących etykiet dekodowania].

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) 
+0

To było bardzo pouczające, ale jeśli rozumiem poprawnie, to nie pokazuje, jak używać danych do treningu ... – dividebyzero

+0

tak, dodam wkrótce ... Powinno być trywialne, czy nie ... obliczyć stratę, uruchomić optymalizator anaway I'll add them soon –

+2

Cześć dividebyzero, przepraszam za spóźnienie! Znalazłem inny link, który jest interesujący i naprawdę ułatwia problem https: //www.tensorflow.org/tutorials/tflearn/.... Tutaj możesz załadować pliki CSV, szkolić je, wykonywać klasyfikację ... –