TensorFlow में CSV डेटा को * वास्तव में * कैसे पढ़ा जाए?


84

मैं TensorFlow की दुनिया के लिए अपेक्षाकृत नया हूँ, और आप वास्तव में CSV डेटा को TensorFlow में प्रयोग करने योग्य उदाहरण / लेबल टेनर्स में कैसे पढ़ेंगे, इस बात से बहुत हैरान हैं । CSV डेटा पढ़ने पर TensorFlow ट्यूटोरियल से उदाहरण बहुत ही खंडित है और केवल आपको CSV डेटा पर प्रशिक्षण देने में सक्षम होने के तरीके का हिस्सा है।

यहाँ मेरा कोड है जो मैंने एक साथ pieced है, उस 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")

और यहाँ CSV फ़ाइल से मैं एक संक्षिप्त उदाहरण लोड कर रहा हूँ - बहुत आधारभूत डेटा - 4 फ़ीचर कॉलम और 1 लेबल कॉलम:

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

उपरोक्त सभी कोड CSV फ़ाइल से एक-एक करके प्रत्येक उदाहरण को प्रिंट करता है , जो कि, जबकि अच्छा है, प्रशिक्षण के लिए बहुत बेकार है।

यहां मैं जो संघर्ष कर रहा हूं वह यह है कि आप वास्तव में उन व्यक्तिगत उदाहरणों को कैसे बदल देंगे, एक-एक करके, एक प्रशिक्षण डाटासेट में लोड किया जाता है। उदाहरण के लिए, यहाँ एक नोटबुक है जो मैं उडनेस डीप लर्निंग कोर्स में काम कर रहा था। मैं मूल रूप से CSV डेटा लेना चाहता हूं, जिसे मैं लोड कर रहा हूं, और उसे ट्रेन_डैटसेट और 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)

मैं tf.train.shuffle_batchइस तरह का उपयोग करने की कोशिश की है , लेकिन यह सिर्फ बेवजह लटका हुआ है:

  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)

तो संक्षेप में, यहाँ मेरे प्रश्न हैं:

  • इस प्रक्रिया के बारे में मुझे क्या याद आ रही है?
    • ऐसा लगता है कि कुछ महत्वपूर्ण अंतर्ज्ञान है जो मुझे याद आ रहा है कि इनपुट पाइपलाइन को ठीक से कैसे बनाया जाए।
  • क्या CSV फ़ाइल की लंबाई जानने से बचने का कोई तरीका है?
    • आपके द्वारा प्रोसेस की जाने वाली लाइनों की संख्या ( for i in range(file_length)ऊपर दी गई कोड की लाइन) जानना बहुत ही अशुभ लगता है

संपादित करें: जैसे ही यारोस्लाव ने बताया कि मैं यहाँ अनिवार्य और ग्राफ-निर्माण भागों को मिला रहा था, यह स्पष्ट होने लगा। मैं निम्नलिखित कोड को एक साथ खींचने में सक्षम था, जो मुझे लगता है कि CSV से किसी मॉडल को प्रशिक्षित करते समय (आमतौर पर किसी भी मॉडल प्रशिक्षण कोड को छोड़कर) किया जाता है:

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) 

मैं आपके कोड की कोशिश कर रहा हूं, लेकिन यह काम नहीं कर सकता। क्या कुछ ऐसा है जो मुझे याद है जो आपने निर्धारित किया है? धन्यवाद। मैंने एक धागा यहाँ पोस्ट किया है ताकि आप अधिक जानकारी प्राप्त कर सकें: stackoverflow.com/questions/40143019/…
लिंक

जवाबों:


24

मुझे लगता है कि आप यहाँ अनिवार्य और ग्राफ-निर्माण भागों का मिश्रण कर रहे हैं। ऑपरेशन tf.train.shuffle_batchएक नया कतार नोड बनाता है, और पूरे डेटासेट को संसाधित करने के लिए एक एकल नोड का उपयोग किया जा सकता है। इसलिए मुझे लगता है कि आप लटके हुए हैं क्योंकि आपने shuffle_batchअपने लूप के लिए कतारों का एक गुच्छा बनाया है और उनके लिए कतार धावक शुरू नहीं किया है।

सामान्य इनपुट पाइपलाइन उपयोग इस तरह दिखता है:

  1. shuffle_batchइनपुट पाइपलाइन की तरह नोड्स जोड़ें
  2. (वैकल्पिक, अनजाने ग्राफ संशोधन को रोकने के लिए) ग्राफ को अंतिम रूप दें

--- ग्राफ निर्माण का अंत, अनिवार्य प्रोग्रामिंग की शुरुआत -

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

अधिक स्केलेबल होने के लिए (पायथन जीआईएल से बचने के लिए), आप अपने सभी डेटा को TensorFlow पाइपलाइन का उपयोग करके उत्पन्न कर सकते हैं। हालाँकि, यदि प्रदर्शन महत्वपूर्ण नहीं है, तो आप इनपुट पाइपलाइन के लिए एक सुव्यवस्थित सारणी को हुक कर सकते हैं, slice_input_producer.यहां कुछ Printनोड्स के साथ एक उदाहरण देखें कि क्या चल रहा है ( Printनोड के चलने पर संदेश में जाने के लिए)

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

आपको कुछ इस तरह से देखना चाहिए

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

"8, 9" संख्याओं ने पूर्ण बैच नहीं भरा, इसलिए वे उत्पादित नहीं हुए। इसके अलावा tf.Printsys.stdout पर मुद्रित होते हैं, इसलिए वे मेरे लिए अलग से टर्मिनल में दिखाते हैं।

पुनश्च: batchमैन्युअल रूप से आरंभिक कतार से कनेक्ट करने का न्यूनतम तरीका है 2193 github

इसके अलावा, डिबगिंग के उद्देश्यों के लिए आप timeoutअपने सत्र को सेट करना चाह सकते हैं ताकि आपका IPython नोटबुक खाली कतार में नहीं लटका रहे। मैं अपने सत्र के लिए इस सहायक समारोह का उपयोग करता हूं

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

स्केलेबिलिटी नोट्स:

  1. tf.constantग्राफ़ में अपने डेटा की इनलाइन कॉपी। ग्राफ़ परिभाषा के आकार पर 2GB की मूलभूत सीमा है ताकि डेटा के आकार पर ऊपरी सीमा हो
  2. आप का उपयोग करके उस सीमा के आसपास मिल सकता है v=tf.Variableचलाकर और वहाँ में डेटा की बचत v.assign_opएक साथ tf.placeholderदाएँ हाथ की ओर पर और प्लेसहोल्डर को numpy सरणी खिला ( feed_dict)
  3. यह अभी भी डेटा की दो प्रतियाँ बनाता है, इसलिए मेमोरी को बचाने के लिए आप अपना स्वयं का संस्करण बना सकते हैं, slice_input_producerजो सुन्न सरणियों पर काम करता है, और एक समय में पंक्तियों को अपलोड करता हैfeed_dict

2
आह, हाँ! आप पूरी तरह से सही हैं - जैसे ही आपने कहा: "मुझे लगता है कि आप यहाँ अनिवार्य और ग्राफ-निर्माण भागों को मिला रहे हैं", मैंने देखना शुरू कर दिया कि मैं कहाँ गलत हो रहा था। मैंने अपने प्रश्न का एक संपादन पोस्ट किया है जिसमें नवीनतम कोड जो मैंने एक साथ रखा है, जो वास्तव में मुझे जो भी चाहिए, उसके करीब पहुंचता है - मैं सीएसवी डेटा में सफलतापूर्वक पढ़ने में सक्षम हूं और इसे इस तरह से बैच सकता हूं कि मैं एक ट्रेन कर सकता हूं नमूना।
रोब

2
मैं इस उत्तर को अपडेट करने का सुझाव देता हूं इसलिए यह TensorFlow के हाल के संस्करणों के साथ काम करता है: (और इसी तरह कई अन्य कार्यों के लिए) के tf.slice_input_producer()साथ बदलें tf.train.slice_input_producer()। और sess.run(tf.initialize_local_variables())बाद में भी जोड़ें sess.run(tf.initialize_all_variables())
मिनीक्वायर्क

बनाने के लिए कुछ और अधिक परिवर्तन: pack()अब है stack(), और initialize_all_variables()साथ प्रतिस्थापित किया जाना चाहिए global_variables_initializer()और local_variables_initializer()
मिनीक्वायर्क

टेंसोफ़्लो 1.0.1 के साथ आपको स्थानीय और वैश्विक चर को शुरू करने की आवश्यकता है tf.group(tf.global_variables_initializer(), tf.local_variables_initializer()).run()। जब से आप num_epochs और प्रलेखन के अनुसार उपयोग कर रहे हैं, तब आपको स्थानीय चर को इनिशियलाइज़ करना होगा "नोट: यदि num_epochsऐसा नहीं है None, तो यह फ़ंक्शन स्थानीय काउंटर बनाता है epochs।"
ब्रूनो आर। कार्डसो

13

या आप यह कोशिश कर सकते हैं, कोड पंडों और सुन्न का उपयोग करके आईरिस डेटासेट को टेंसोफ़्लो में लोड करता है और एक साधारण एक न्यूरॉन आउटपुट सत्र में मुद्रित होता है। आशा है कि यह एक बुनियादी समझ के लिए मदद करता है .... [मैं एक गर्म डिकोडिंग लेबल का तरीका जोड़ा]।

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)

यह बहुत शिक्षाप्रद था, लेकिन अगर मैं सही ढंग से
समझूं

हाँ, मैं उन्हें जल्द ही जोड़ दूंगा ... यह तुच्छ होना चाहिए ... यह नुकसान की गणना करें, आशावादी आगम चलाएं मैं उन्हें जल्द ही जोड़ दूंगा
नागार्जुन गुरुराज

2
हाय dividebyzero, मैं देर से माफी चाहता हूँ! मैं एक और लिंक जो दिलचस्प है और वास्तव में समस्या को आसान बनाता है पाया tensorflow.org/tutorials/tflearn .... यहाँ आप csv फ़ाइलें लोड कर सकते हैं, उन्हें प्रशिक्षित, वर्गीकरण प्रदर्शन ...
नागार्जुन गुरूराज

@NagarjunGururaj क्या मैं सामान्य टेंसोफ़्लो दिनचर्या में कॉन्ट्रिब_लर्न द्वारा निर्मित डेटासेट का उपयोग कर सकता हूं?
जे वोंग

कौन सा डेटासेट? आपका मतलब है आइरिस या कोई और?
नागार्जुन गुरुराज

2

आप नवीनतम tf.data API का उपयोग कर सकते हैं:

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])

2

अगर किसी को भी tf.estimator API में बिल्कुल बड़ी और शार्प की गई CSV फ़ाइलों को पढ़ने का एक सरल तरीका खोजना है, तो कृपया मेरे कोड के नीचे

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

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)

0

2.0 संगत समाधान : यह उत्तर दूसरों द्वारा उपरोक्त धागे में प्रदान किया जा सकता है लेकिन मैं अतिरिक्त लिंक प्रदान करूंगा जो समुदाय की मदद करेगा।

dataset = tf.data.experimental.make_csv_dataset(
      file_path,
      batch_size=5, # Artificially small to make examples easier to show.
      label_name=LABEL_COLUMN,
      na_value="?",
      num_epochs=1,
      ignore_errors=True, 
      **kwargs)

अधिक जानकारी के लिए, कृपया इस Tensorflow Tutorial को देखें ।


1
मुझे यह उत्तर (और ट्यूटोरियल और प्रलेखन) पूरी तरह से निराशाजनक लगता है। यह अभी भी ओपी के शब्दों में "सीएसवी डेटा पर प्रशिक्षित करने में सक्षम होने के तरीके का हिस्सा" हो जाता है। यह एक "डेटासेट" बनाता है (लेकिन यह किस प्रकार का है - यह एक tf.data.Dataset है; प्रलेखन अस्पष्ट) और ऐसा लगता है कि डेटासेट स्तंभ-उन्मुख है, न कि पंक्ति-उन्मुख। अधिकांश मॉडलों को प्रशिक्षण के लिए उन्हें पास की गई पंक्तियों के बैचों की आवश्यकता होती है - इस चरण को कैसे प्राप्त करें? मैंने इस सवाल को एंड-टू-एंड उदाहरण के लिए पूछा ।
ओमाताई

कृपया अमूर्त स्तर के दस्तावेज लगाने के बजाय make_csv_dataset का अंतिम उदाहरण प्रदान करें!
DevLoverUmar
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.