एक सवाल है? TensorFlow फ़ोरम विज़िट फ़ोरम पर समुदाय से जुड़ें

सीएसवी डेटा लोड करें

TensorFlow.org पर देखें Google Colab में चलाएं GitHub पर स्रोत देखेंनोटबुक डाउनलोड करें

यह ट्यूटोरियल TensorFlow के साथ CSV डेटा का उपयोग करने के उदाहरण प्रदान करता है।

इसके दो मुख्य भाग हैं:

  1. डिस्क से डेटा लोड हो रहा है
  2. प्रशिक्षण के लिए उपयुक्त रूप में इसे पूर्व-संसाधित करना।

यह ट्यूटोरियल लोडिंग पर केंद्रित है, और प्रीप्रोसेसिंग के कुछ त्वरित उदाहरण देता है। प्रीप्रोसेसिंग पहलू पर ध्यान केंद्रित करने वाले ट्यूटोरियल के लिए प्रीप्रोसेसिंग लेयर्स गाइड और ट्यूटोरियल देखें

सेट अप

import pandas as pd
import numpy as np

# Make numpy values easier to read.
np.set_printoptions(precision=3, suppress=True)

import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras.layers.experimental import preprocessing

मेमोरी डेटा में

किसी भी छोटे CSV डेटासेट के लिए उस पर TensorFlow मॉडल को प्रशिक्षित करने का सबसे सरल तरीका है कि इसे मेमोरी में पांडा डेटाफ़्रेम या NumPy सरणी के रूप में लोड किया जाए।

एक अपेक्षाकृत सरल उदाहरण अबालोन डेटासेट है

  • डेटासेट छोटा है।
  • सभी इनपुट सुविधाएँ सभी सीमित-श्रेणी के फ़्लोटिंग पॉइंट मान हैं।

DataFrame में डेटा डाउनलोड करने का तरीका यहां दिया गया है:

abalone_train = pd.read_csv(
    "https://storage.googleapis.com/download.tensorflow.org/data/abalone_train.csv",
    names=["Length", "Diameter", "Height", "Whole weight", "Shucked weight",
           "Viscera weight", "Shell weight", "Age"])

abalone_train.head()

डेटासेट में समुद्री घोंघे का एक प्रकार, अबालोन के माप का एक सेट होता है।

एक अबालोन खोल

"एबालोन शेल" ( निकी दुगन पोग द्वारा, सीसी बाय-एसए 2.0)

इस डेटासेट के लिए नाममात्र का कार्य अन्य मापों से आयु की भविष्यवाणी करना है, इसलिए प्रशिक्षण के लिए सुविधाओं और लेबल को अलग करें:

02एईबी15630

इस डेटासेट के लिए आप सभी सुविधाओं को एक समान मानेंगे। सुविधाओं को एक एकल NumPy सरणी में पैक करें।

0621eea80
array([[0.435, 0.335, 0.11 , ..., 0.136, 0.077, 0.097],
       [0.585, 0.45 , 0.125, ..., 0.354, 0.207, 0.225],
       [0.655, 0.51 , 0.16 , ..., 0.396, 0.282, 0.37 ],
       ...,
       [0.53 , 0.42 , 0.13 , ..., 0.374, 0.167, 0.249],
       [0.395, 0.315, 0.105, ..., 0.118, 0.091, 0.119],
       [0.45 , 0.355, 0.12 , ..., 0.115, 0.067, 0.16 ]])

अगला एक प्रतिगमन मॉडल बनाएं जो उम्र की भविष्यवाणी करता है। चूंकि केवल एक इनपुट टेंसर है, एक keras.Sequentialkeras.Sequential मॉडल यहां पर्याप्त है।

abalone_model = tf.keras.Sequential([
  layers.Dense(64),
  layers.Dense(1)
])

abalone_model.compile(loss = tf.losses.MeanSquaredError(),
                      optimizer = tf.optimizers.Adam())

उस मॉडल को प्रशिक्षित करने के लिए, सुविधाओं और लेबल को Model.fit :

abalone_model.fit(abalone_features, abalone_labels, epochs=10)
Epoch 1/10
104/104 [==============================] - 1s 2ms/step - loss: 68.1297
Epoch 2/10
104/104 [==============================] - 0s 2ms/step - loss: 13.3981
Epoch 3/10
104/104 [==============================] - 0s 1ms/step - loss: 8.9458
Epoch 4/10
104/104 [==============================] - 0s 1ms/step - loss: 8.3894
Epoch 5/10
104/104 [==============================] - 0s 1ms/step - loss: 7.8835
Epoch 6/10
104/104 [==============================] - 0s 1ms/step - loss: 7.4897
Epoch 7/10
104/104 [==============================] - 0s 1ms/step - loss: 7.1716
Epoch 8/10
104/104 [==============================] - 0s 1ms/step - loss: 6.9468
Epoch 9/10
104/104 [==============================] - 0s 1ms/step - loss: 6.7714
Epoch 10/10
104/104 [==============================] - 0s 1ms/step - loss: 6.6458
<tensorflow.python.keras.callbacks.History at 0x7f7bf0178110>

आपने अभी-अभी CSV डेटा का उपयोग करके किसी मॉडल को प्रशिक्षित करने का सबसे बुनियादी तरीका देखा है। इसके बाद, आप सीखेंगे कि संख्यात्मक कॉलम को सामान्य करने के लिए प्रीप्रोसेसिंग कैसे लागू करें।

बेसिक प्रीप्रोसेसिंग

अपने मॉडल के इनपुट को सामान्य करना एक अच्छा अभ्यास है। आपके मॉडल में इस सामान्यीकरण को बनाने के लिए experimental.preprocessing परतें एक सुविधाजनक तरीका प्रदान करती हैं।

परत प्रत्येक कॉलम के माध्य और विचरण को पूर्व-गणना करेगी, और डेटा को सामान्य करने के लिए इनका उपयोग करेगी।

सबसे पहले आप परत बनाएं:

normalize = preprocessing.Normalization()

फिर आप अपने डेटा के लिए सामान्यीकरण परत को अनुकूलित करने के लिए Normalization.adapt() विधि का उपयोग करते हैं।

normalize.adapt(abalone_features)

फिर अपने मॉडल में सामान्यीकरण परत का उपयोग करें:

norm_abalone_model = tf.keras.Sequential([
  normalize,
  layers.Dense(64),
  layers.Dense(1)
])

norm_abalone_model.compile(loss = tf.losses.MeanSquaredError(),
                           optimizer = tf.optimizers.Adam())

norm_abalone_model.fit(abalone_features, abalone_labels, epochs=10)
Epoch 1/10
104/104 [==============================] - 0s 2ms/step - loss: 91.9882
Epoch 2/10
104/104 [==============================] - 0s 2ms/step - loss: 52.3517
Epoch 3/10
104/104 [==============================] - 0s 1ms/step - loss: 16.0901
Epoch 4/10
104/104 [==============================] - 0s 1ms/step - loss: 5.8372
Epoch 5/10
104/104 [==============================] - 0s 1ms/step - loss: 5.0929
Epoch 6/10
104/104 [==============================] - 0s 2ms/step - loss: 5.0442
Epoch 7/10
104/104 [==============================] - 0s 1ms/step - loss: 5.0062
Epoch 8/10
104/104 [==============================] - 0s 1ms/step - loss: 4.9882
Epoch 9/10
104/104 [==============================] - 0s 2ms/step - loss: 4.9629
Epoch 10/10
104/104 [==============================] - 0s 2ms/step - loss: 4.9666
<tensorflow.python.keras.callbacks.History at 0x7f7be008f910>

मिश्रित डेटा प्रकार

"टाइटैनिक" डेटासेट में टाइटैनिक के यात्रियों के बारे में जानकारी होती है। इस डेटासेट पर नाममात्र का कार्य यह भविष्यवाणी करना है कि कौन बच गया।

भीमकाय

विकिमीडिया से छवि

कच्चे डेटा को आसानी से पंडों के DataFrame रूप में लोड किया जा सकता है, लेकिन तुरंत TensorFlow मॉडल में इनपुट के रूप में उपयोग करने योग्य नहीं है।

titanic = pd.read_csv("https://storage.googleapis.com/tf-datasets/titanic/train.csv")
titanic.head()
titanic_features = titanic.copy()
titanic_labels = titanic_features.pop('survived')

विभिन्न डेटा प्रकारों और श्रेणियों के कारण आप केवल सुविधाओं को NumPy सरणी में स्टैक नहीं कर सकते हैं और इसे keras.Sequential मॉडल में पास कर सकते हैं। प्रत्येक कॉलम को व्यक्तिगत रूप से संभाला जाना चाहिए।

एक विकल्प के रूप में, आप श्रेणीबद्ध स्तंभों को संख्यात्मक स्तंभों में बदलने के लिए अपने डेटा को ऑफ़लाइन (किसी भी उपकरण का उपयोग करके) प्रीप्रोसेस कर सकते हैं, फिर संसाधित आउटपुट को अपने TensorFlow मॉडल में पास कर सकते हैं। उस दृष्टिकोण का नुकसान यह है कि यदि आप अपने मॉडल को सहेजते और निर्यात करते हैं तो इसके साथ प्रीप्रोसेसिंग सहेजा नहीं जाता है। experimental.preprocessing परतें इस समस्या से बचती हैं क्योंकि वे मॉडल का हिस्सा हैं।

इस उदाहरण में, आप एक मॉडल का निर्माण करेंगे जो केरस फंक्शनल एपीआई का उपयोग करके प्रीप्रोसेसिंग लॉजिक को लागू करता है । आप इसे सबक्लासिंग करके भी कर सकते हैं।

कार्यात्मक एपीआई "प्रतीकात्मक" टेंसर पर काम करता है। सामान्य "उत्सुक" टेंसर का एक मूल्य होता है। इसके विपरीत ये "प्रतीकात्मक" टेंसर नहीं करते हैं। इसके बजाय वे ट्रैक करते हैं कि उन पर कौन से ऑपरेशन चल रहे हैं, और गणना का प्रतिनिधित्व करते हैं, जिसे आप बाद में चला सकते हैं। यहाँ एक त्वरित उदाहरण है:

# Create a symbolic input
input = tf.keras.Input(shape=(), dtype=tf.float32)

# Do a calculation using is
result = 2*input + 1

# the result doesn't have a value
result
<KerasTensor: shape=(None,) dtype=float32 (created by layer 'tf.__operators__.add')>
calc = tf.keras.Model(inputs=input, outputs=result)
print(calc(1).numpy())
print(calc(2).numpy())
3.0
5.0

प्रीप्रोसेसिंग मॉडल बनाने के लिए, प्रतीकात्मक keras.Input का एक सेट बनाकर शुरू करें। keras.Input ऑब्जेक्ट्स, सीएसवी कॉलम के नाम और डेटा-प्रकार से मेल खाते हैं।

inputs = {}

for name, column in titanic_features.items():
  dtype = column.dtype
  if dtype == object:
    dtype = tf.string
  else:
    dtype = tf.float32

  inputs[name] = tf.keras.Input(shape=(1,), name=name, dtype=dtype)

inputs
{'sex': <KerasTensor: shape=(None, 1) dtype=string (created by layer 'sex')>,
 'age': <KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'age')>,
 'n_siblings_spouses': <KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'n_siblings_spouses')>,
 'parch': <KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'parch')>,
 'fare': <KerasTensor: shape=(None, 1) dtype=float32 (created by layer 'fare')>,
 'class': <KerasTensor: shape=(None, 1) dtype=string (created by layer 'class')>,
 'deck': <KerasTensor: shape=(None, 1) dtype=string (created by layer 'deck')>,
 'embark_town': <KerasTensor: shape=(None, 1) dtype=string (created by layer 'embark_town')>,
 'alone': <KerasTensor: shape=(None, 1) dtype=string (created by layer 'alone')>}

आपके प्रीप्रोसेसिंग तर्क में पहला कदम संख्यात्मक इनपुट को एक साथ जोड़ना है, और उन्हें सामान्यीकरण परत के माध्यम से चलाना है:

numeric_inputs = {name:input for name,input in inputs.items()
                  if input.dtype==tf.float32}

x = layers.Concatenate()(list(numeric_inputs.values()))
norm = preprocessing.Normalization()
norm.adapt(np.array(titanic[numeric_inputs.keys()]))
all_numeric_inputs = norm(x)

all_numeric_inputs
<KerasTensor: shape=(None, 4) dtype=float32 (created by layer 'normalization_1')>

सभी प्रतीकात्मक प्रीप्रोसेसिंग परिणामों को बाद में संयोजित करने के लिए एकत्र करें।

preprocessed_inputs = [all_numeric_inputs]

स्ट्रिंग इनपुट के लिए preprocessing.StringLookup उपयोग करें। एक शब्दावली में स्ट्रिंग्स से पूर्णांक इंडेक्स तक मैप करने के लिए स्ट्रिंग preprocessing.StringLookup फ़ंक्शन। इसके बाद, preprocessing.CategoryEncoding का उपयोग करें। मॉडल के लिए उपयुक्त float32 डेटा में इंडेक्स को बदलने के लिए float32

preprocessing.CategoryEncoding लिए डिफ़ॉल्ट सेटिंग्स। श्रेणी preprocessing.CategoryEncoding परत प्रत्येक इनपुट के लिए एक-हॉट वेक्टर बनाती है। एक layers.Embeddinglayers.Embedding भी काम करेगी। इस विषय पर अधिक जानकारी के लिए प्रीप्रोसेसिंग लेयर गाइड और ट्यूटोरियल देखें।

for name, input in inputs.items():
  if input.dtype == tf.float32:
    continue

  lookup = preprocessing.StringLookup(vocabulary=np.unique(titanic_features[name]))
  one_hot = preprocessing.CategoryEncoding(max_tokens=lookup.vocab_size())

  x = lookup(input)
  x = one_hot(x)
  preprocessed_inputs.append(x)
WARNING:tensorflow:vocab_size is deprecated, please use vocabulary_size.
WARNING:tensorflow:max_tokens is deprecated, please use num_tokens instead.
WARNING:tensorflow:vocab_size is deprecated, please use vocabulary_size.
WARNING:tensorflow:max_tokens is deprecated, please use num_tokens instead.
WARNING:tensorflow:vocab_size is deprecated, please use vocabulary_size.
WARNING:tensorflow:max_tokens is deprecated, please use num_tokens instead.
WARNING:tensorflow:vocab_size is deprecated, please use vocabulary_size.
WARNING:tensorflow:max_tokens is deprecated, please use num_tokens instead.
WARNING:tensorflow:vocab_size is deprecated, please use vocabulary_size.
WARNING:tensorflow:max_tokens is deprecated, please use num_tokens instead.

inputs और processed_inputs के संग्रह के साथ, आप सभी प्रीप्रोसेस्ड इनपुट को एक साथ जोड़ सकते हैं, और एक मॉडल बना सकते हैं जो प्रीप्रोसेसिंग को संभालता है:

preprocessed_inputs_cat = layers.Concatenate()(preprocessed_inputs)

titanic_preprocessing = tf.keras.Model(inputs, preprocessed_inputs_cat)

tf.keras.utils.plot_model(model = titanic_preprocessing , rankdir="LR", dpi=72, show_shapes=True)

पीएनजी

इस model सिर्फ इनपुट प्रीप्रोसेसिंग शामिल है। आप इसे यह देखने के लिए चला सकते हैं कि यह आपके डेटा के साथ क्या करता है। केरस मॉडल स्वचालित रूप से पंडों के DataFrames परिवर्तित नहीं करते हैं क्योंकि यह स्पष्ट नहीं है कि इसे एक टेंसर में या टेंसर के शब्दकोश में परिवर्तित किया जाना चाहिए। तो इसे टेंसर के शब्दकोश में परिवर्तित करें:

titanic_features_dict = {name: np.array(value) 
                         for name, value in titanic_features.items()}

पहले प्रशिक्षण उदाहरण को स्लाइस करें और इसे इस प्रीप्रोसेसिंग मॉडल में पास करें, आप संख्यात्मक विशेषताओं और स्ट्रिंग वन-हॉट्स को एक साथ जोड़कर देखते हैं:

features_dict = {name:values[:1] for name, values in titanic_features_dict.items()}
titanic_preprocessing(features_dict)
<tf.Tensor: shape=(1, 33), dtype=float32, numpy=
array([[-0.61 ,  0.395, -0.479, -0.497,  0.   ,  0.   ,  0.   ,  1.   ,

         0.   ,  0.   ,  0.   ,  0.   ,  1.   ,  0.   ,  0.   ,  0.   ,
         0.   ,  0.   ,  0.   ,  0.   ,  0.   ,  0.   ,  1.   ,  0.   ,
         0.   ,  0.   ,  0.   ,  1.   ,  0.   ,  0.   ,  0.   ,  1.   ,
         0.   ]], dtype=float32)>

अब इसके ऊपर मॉडल बनाएं:

def titanic_model(preprocessing_head, inputs):
  body = tf.keras.Sequential([
    layers.Dense(64),
    layers.Dense(1)
  ])

  preprocessed_inputs = preprocessing_head(inputs)
  result = body(preprocessed_inputs)
  model = tf.keras.Model(inputs, result)

  model.compile(loss=tf.losses.BinaryCrossentropy(from_logits=True),
                optimizer=tf.optimizers.Adam())
  return model

titanic_model = titanic_model(titanic_preprocessing, inputs)

जब आप मॉडल को प्रशिक्षित करते हैं, तो सुविधाओं के शब्दकोश को x और लेबल को y रूप में पास करें।

titanic_model.fit(x=titanic_features_dict, y=titanic_labels, epochs=10)
Epoch 1/10
20/20 [==============================] - 1s 3ms/step - loss: 0.5665
Epoch 2/10
20/20 [==============================] - 0s 3ms/step - loss: 0.4980
Epoch 3/10
20/20 [==============================] - 0s 3ms/step - loss: 0.4643
Epoch 4/10
20/20 [==============================] - 0s 3ms/step - loss: 0.4463
Epoch 5/10
20/20 [==============================] - 0s 3ms/step - loss: 0.4333
Epoch 6/10
20/20 [==============================] - 0s 3ms/step - loss: 0.4297
Epoch 7/10
20/20 [==============================] - 0s 3ms/step - loss: 0.4252
Epoch 8/10
20/20 [==============================] - 0s 4ms/step - loss: 0.4234
Epoch 9/10
20/20 [==============================] - 0s 4ms/step - loss: 0.4213
Epoch 10/10
20/20 [==============================] - 0s 4ms/step - loss: 0.4202
<tensorflow.python.keras.callbacks.History at 0x7f7c8ff43510>

चूंकि प्रीप्रोसेसिंग मॉडल का हिस्सा है, आप मॉडल को सहेज सकते हैं और इसे कहीं और पुनः लोड कर सकते हैं और समान परिणाम प्राप्त कर सकते हैं:

titanic_model.save('test')
reloaded = tf.keras.models.load_model('test')
INFO:tensorflow:Assets written to: test/assets
features_dict = {name:values[:1] for name, values in titanic_features_dict.items()}

before = titanic_model(features_dict)
after = reloaded(features_dict)
assert (before-after)<1e-3
print(before)
print(after)
tf.Tensor([[-1.843]], shape=(1, 1), dtype=float32)
tf.Tensor([[-1.843]], shape=(1, 1), dtype=float32)

tf.डेटा का उपयोग करना

पिछले अनुभाग में आपने मॉडल को प्रशिक्षित करते समय मॉडल के अंतर्निहित डेटा फेरबदल और बैचिंग पर भरोसा किया था।

यदि आपको इनपुट डेटा पाइपलाइन पर अधिक नियंत्रण की आवश्यकता है या डेटा का उपयोग करने की आवश्यकता है जो आसानी से मेमोरी में फिट नहीं होता है: tf.data उपयोग tf.data

अधिक उदाहरणों के लिए tf.data गाइड देखें।

मेमोरी डेटा में चालू है

CSV डेटा में tf.data लागू करने के पहले उदाहरण के रूप में, पिछले अनुभाग से सुविधाओं के शब्दकोश को मैन्युअल रूप से अलग करने के लिए निम्नलिखित कोड पर विचार करें। प्रत्येक सूचकांक के लिए, यह प्रत्येक सुविधा के लिए उस सूचकांक को लेता है:

import itertools

def slices(features):
  for i in itertools.count():
    # For each feature take index `i`
    example = {name:values[i] for name, values in features.items()}
    yield example

इसे चलाएँ और पहला उदाहरण प्रिंट करें:

for example in slices(titanic_features_dict):
  for name, value in example.items():
    print(f"{name:19s}: {value}")
  break
sex                : male
age                : 22.0
n_siblings_spouses : 1
parch              : 0
fare               : 7.25
class              : Third
deck               : unknown
embark_town        : Southampton
alone              : n

मेमोरी डेटा लोडर में सबसे बुनियादीtf.data.Dataset Dataset.from_tensor_slices कंस्ट्रक्टर है। यह एकtf.data.Dataset देता है जोtf.data.Dataset में उपरोक्त slices फ़ंक्शन के सामान्यीकृत संस्करण को लागू करता है।

features_ds = tf.data.Dataset.from_tensor_slices(titanic_features_dict)

आप एकtf.data.Dataset पर पुनरावृति कर सकते हैं जैसे कि कोई अन्य अजगरtf.data.Dataset योग्य:

for example in features_ds:
  for name, value in example.items():
    print(f"{name:19s}: {value}")
  break
sex                : b'male'
age                : 22.0
n_siblings_spouses : 1
parch              : 0
fare               : 7.25
class              : b'Third'
deck               : b'unknown'
embark_town        : b'Southampton'
alone              : b'n'

from_tensor_slices फ़ंक्शन नेस्टेड शब्दकोशों या from_tensor_slices किसी भी संरचना को संभाल सकता है। निम्नलिखित कोड (features_dict, labels) जोड़े का एक डेटासेट बनाता है:

titanic_ds = tf.data.Dataset.from_tensor_slices((titanic_features_dict, titanic_labels))

इस Dataset का उपयोग करके किसी मॉडल को प्रशिक्षित करने के लिए, आपको कम से कम डेटा को shuffle और batch करना होगा।

titanic_batches = titanic_ds.shuffle(len(titanic_labels)).batch(32)

Model.fit को features और labels करने के Model.fit , आप डेटासेट पास करते हैं:

titanic_model.fit(titanic_batches, epochs=5)
Epoch 1/5
20/20 [==============================] - 0s 4ms/step - loss: 0.4199
Epoch 2/5
20/20 [==============================] - 0s 4ms/step - loss: 0.4199
Epoch 3/5
20/20 [==============================] - 0s 4ms/step - loss: 0.4192
Epoch 4/5
20/20 [==============================] - 0s 4ms/step - loss: 0.4189
Epoch 5/5
20/20 [==============================] - 0s 4ms/step - loss: 0.4185
<tensorflow.python.keras.callbacks.History at 0x7f7c8e8ee810>

एक ही फाइल से

अब तक इस ट्यूटोरियल ने इन-मेमोरी डेटा के साथ काम किया है। tf.data डेटा पाइपलाइन बनाने के लिए एक उच्च स्केलेबल टूलकिट है, और CSV फ़ाइलों को लोड करने से निपटने के लिए कुछ कार्य प्रदान करता है।

titanic_file_path = tf.keras.utils.get_file("train.csv", "https://storage.googleapis.com/tf-datasets/titanic/train.csv")
Downloading data from https://storage.googleapis.com/tf-datasets/titanic/train.csv
32768/30874 [===============================] - 0s 0us/step

अब फ़ाइल से CSV डेटा पढ़ें और एकtf.data.Dataset

(पूर्ण दस्तावेज़ीकरण के लिए, tf.data.experimental.make_csv_dataset देखें)

titanic_csv_ds = tf.data.experimental.make_csv_dataset(
    titanic_file_path,
    batch_size=5, # Artificially small to make examples easier to show.
    label_name='survived',
    num_epochs=1,
    ignore_errors=True,)

इस फ़ंक्शन में कई सुविधाजनक सुविधाएं शामिल हैं ताकि डेटा के साथ काम करना आसान हो। यह भी शामिल है:

  • कॉलम हेडर का उपयोग डिक्शनरी कीज़ के रूप में करना।
  • प्रत्येक कॉलम के प्रकार को स्वचालित रूप से निर्धारित करना।
for batch, label in titanic_csv_ds.take(1):
  for key, value in batch.items():
    print(f"{key:20s}: {value}")
  print()
  print(f"{'label':20s}: {label}")
sex                 : [b'male' b'female' b'male' b'male' b'male']
age                 : [28. 28. 70.  1. 28.]
n_siblings_spouses  : [1 0 1 5 1]
parch               : [0 0 1 2 0]
fare                : [82.171  7.225 71.    46.9   15.85 ]
class               : [b'First' b'Third' b'First' b'Third' b'Third']
deck                : [b'unknown' b'unknown' b'B' b'unknown' b'unknown']
embark_town         : [b'Cherbourg' b'Cherbourg' b'Southampton' b'Southampton' b'Southampton']
alone               : [b'n' b'y' b'n' b'n' b'n']

label               : [0 1 0 0 0]

यह मक्खी पर डेटा को डीकंप्रेस भी कर सकता है। मेट्रो अंतरराज्यीय ट्रैफ़िक डेटासेट वाली gzipped CSV फ़ाइल यहां दी गई है

ट्रैफ़िक जाम।

विकिमीडिया से छवि

traffic_volume_csv_gz = tf.keras.utils.get_file(
    'Metro_Interstate_Traffic_Volume.csv.gz', 
    "https://archive.ics.uci.edu/ml/machine-learning-databases/00492/Metro_Interstate_Traffic_Volume.csv.gz",
    cache_dir='.', cache_subdir='traffic')
Downloading data from https://archive.ics.uci.edu/ml/machine-learning-databases/00492/Metro_Interstate_Traffic_Volume.csv.gz
409600/405373 [==============================] - 1s 2us/step

संपीड़ित फ़ाइल से सीधे पढ़ने के लिए compression_type तर्क सेट करें:

traffic_volume_csv_gz_ds = tf.data.experimental.make_csv_dataset(
    traffic_volume_csv_gz,
    batch_size=256,
    label_name='traffic_volume',
    num_epochs=1,
    compression_type="GZIP")

for batch, label in traffic_volume_csv_gz_ds.take(1):
  for key, value in batch.items():
    print(f"{key:20s}: {value[:5]}")
  print()
  print(f"{'label':20s}: {label[:5]}")
holiday             : [b'None' b'None' b'None' b'None' b'None']
temp                : [275.36 264.13 265.53 278.63 289.91]
rain_1h             : [0.   0.   0.   0.   1.52]
snow_1h             : [0. 0. 0. 0. 0.]
clouds_all          : [90 90 75 90 80]
weather_main        : [b'Rain' b'Clouds' b'Clouds' b'Rain' b'Mist']
weather_description : [b'light rain' b'overcast clouds' b'broken clouds' b'light rain' b'mist']
date_time           : [b'2013-03-10 19:00:00' b'2013-01-02 19:00:00' b'2012-12-06 06:00:00'
 b'2013-04-25 18:00:00' b'2013-07-31 04:00:00']

label               : [2743 2687 5545 5020  822]

कैशिंग

सीएसवी डेटा को पार्स करने के लिए कुछ ओवरहेड है। छोटे मॉडलों के लिए यह प्रशिक्षण में अड़चन हो सकती है।

आपके उपयोग के मामले के आधार पर Dataset.cache या data.experimental.snapshot का उपयोग करना एक अच्छा विचार हो सकता है ताकि csv डेटा केवल पहले युग में ही पार्स किया जा सके।

cache और snapshot विधियों के बीच मुख्य अंतर यह है कि cache फ़ाइलों का उपयोग केवल TensorFlow प्रक्रिया द्वारा किया जा सकता है जिसने उन्हें बनाया है, लेकिन snapshot फ़ाइलों को अन्य प्रक्रियाओं द्वारा पढ़ा जा सकता है।

उदाहरण के लिए, traffic_volume_csv_gz_ds 20 बार पुनरावृति करने पर, कैशिंग के बिना ~15 सेकंड या कैशिंग के साथ ~2 सेकंड लगते हैं।

%%time
for i, (batch, label) in enumerate(traffic_volume_csv_gz_ds.repeat(20)):
  if i % 40 == 0:
    print('.', end='')
print()
...............................................................................................
CPU times: user 14.9 s, sys: 3.58 s, total: 18.5 s
Wall time: 11 s
%%time
caching = traffic_volume_csv_gz_ds.cache().shuffle(1000)

for i, (batch, label) in enumerate(caching.shuffle(1000).repeat(20)):
  if i % 40 == 0:
    print('.', end='')
print()
...............................................................................................
CPU times: user 1.42 s, sys: 115 ms, total: 1.53 s
Wall time: 1.22 s
%%time
snapshot = tf.data.experimental.snapshot('titanic.tfsnap')
snapshotting = traffic_volume_csv_gz_ds.apply(snapshot).shuffle(1000)

for i, (batch, label) in enumerate(snapshotting.shuffle(1000).repeat(20)):
  if i % 40 == 0:
    print('.', end='')
print()
...............................................................................................
CPU times: user 2.26 s, sys: 431 ms, total: 2.69 s
Wall time: 1.62 s

यदि सीएसवी फाइलों को लोड करने से आपका डेटा लोड धीमा हो जाता है, और cache और snapshot आपके उपयोग के मामले के लिए अपर्याप्त हैं, तो अपने डेटा को अधिक सुव्यवस्थित प्रारूप में फिर से एन्कोड करने पर विचार करें।

एकाधिक फ़ाइलें

इस खंड में अब तक के सभी उदाहरण tf.data बिना आसानी से किए जा सकते हैं। फाइलों के संग्रह से निपटने के दौरान एक जगह जहां tf.data वास्तव में चीजों को सरल बना सकता है।

उदाहरण के लिए, वर्ण फ़ॉन्ट छवियों के डेटासेट को csv फ़ाइलों के संग्रह के रूप में वितरित किया जाता है, एक प्रति फ़ॉन्ट।

फोंट्स

द्वारा छवि विल्ली Heidelbach से Pixabay

डेटासेट डाउनलोड करें, और अंदर की फाइलों पर एक नज़र डालें:

fonts_zip = tf.keras.utils.get_file(
    'fonts.zip',  "https://archive.ics.uci.edu/ml/machine-learning-databases/00417/fonts.zip",
    cache_dir='.', cache_subdir='fonts',
    extract=True)
Downloading data from https://archive.ics.uci.edu/ml/machine-learning-databases/00417/fonts.zip
160317440/160313983 [==============================] - 8s 0us/step
import pathlib
font_csvs =  sorted(str(p) for p in pathlib.Path('fonts').glob("*.csv"))

font_csvs[:10]
['fonts/AGENCY.csv',
 'fonts/ARIAL.csv',
 'fonts/BAITI.csv',
 'fonts/BANKGOTHIC.csv',
 'fonts/BASKERVILLE.csv',
 'fonts/BAUHAUS.csv',
 'fonts/BELL.csv',
 'fonts/BERLIN.csv',
 'fonts/BERNARD.csv',
 'fonts/BITSTREAMVERA.csv']
len(font_csvs)
153

फ़ाइलों के एक समूह के साथ काम करते समय आप एक ग्लोब-शैली file_pattern को experimental.make_csv_dataset . file_pattern फ़ंक्शन में पास कर सकते हैं। फ़ाइलों का क्रम प्रत्येक पुनरावृत्ति में फेरबदल किया जाता है।

समानांतर में कितनी फाइलें पढ़ी जाती हैं और एक साथ इंटरलीव की जाती हैं, यह निर्धारित करने के लिए num_parallel_reads तर्क का उपयोग करें।

fonts_ds = tf.data.experimental.make_csv_dataset(
    file_pattern = "fonts/*.csv",
    batch_size=10, num_epochs=1,
    num_parallel_reads=20,
    shuffle_buffer_size=10000)

इन सीएसवी फाइलों में छवियों को एक ही पंक्ति में समतल कर दिया गया है। कॉलम नाम प्रारूपित हैं r{row}c{column} । यहाँ पहला बैच है:

for features in fonts_ds.take(1):
  for i, (name, value) in enumerate(features.items()):
    if i>15:
      break
    print(f"{name:20s}: {value}")
print('...')
print(f"[total: {len(features)} features]")
font                : [b'GLOUCESTER' b'REFERENCE' b'TREBUCHET' b'MONEY' b'GLOUCESTER' b'MONEY'
 b'GLOUCESTER' b'JUICE' b'CAMBRIA' b'BRUSH']
fontVariant         : [b'GLOUCESTER MT EXTRA CONDENSED' b'MS REFERENCE SANS SERIF'
 b'TREBUCHET MS' b'scanned' b'GLOUCESTER MT EXTRA CONDENSED' b'scanned'
 b'GLOUCESTER MT EXTRA CONDENSED' b'JUICE ITC' b'CAMBRIA'
 b'BRUSH SCRIPT MT']
m_label             : [  116 63521   507    53   402    54  8747   213 10766  8776]
strength            : [0.4 0.4 0.4 0.4 0.4 0.4 0.4 0.4 0.4 0.4]
italic              : [1 0 0 0 0 0 0 1 0 1]
orientation         : [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
m_top               : [41 21 23  0 31  0 22 20 25 44]
m_left              : [25 26 23  0 15  0 20 27 23 24]
originalH           : [42 68 64 32 63 27 68 61 73 25]
originalW           : [18 30 30 19 22 16 18 33 32 36]
h                   : [20 20 20 20 20 20 20 20 20 20]
w                   : [20 20 20 20 20 20 20 20 20 20]
r0c0                : [1 1 1 1 1 1 1 1 1 1]
r0c1                : [ 1  1  1 91  1  1  1  1  1  1]
r0c2                : [  1   1   1 239   1   1   1   1   1  40]
r0c3                : [  1   1   1 255   1   1   1   1   1  74]
...
[total: 412 features]

वैकल्पिक: पैकिंग फ़ील्ड

आप शायद इस तरह के अलग-अलग कॉलम में प्रत्येक पिक्सेल के साथ काम नहीं करना चाहते हैं। इस डेटासेट का उपयोग करने का प्रयास करने से पहले पिक्सेल को इमेज-टेंसर में पैक करना सुनिश्चित करें।

यहां कोड है जो प्रत्येक उदाहरण के लिए छवियों को बनाने के लिए कॉलम नामों को पार करता है:

०एबे९१८०डी०

डेटासेट में प्रत्येक बैच में उस फ़ंक्शन को लागू करें:

fonts_image_ds = fonts_ds.map(make_images)

for features in fonts_image_ds.take(1):
  break

परिणामी छवियों को प्लॉट करें:

from matplotlib import pyplot as plt

plt.figure(figsize=(6,6), dpi=120)

for n in range(9):
  plt.subplot(3,3,n+1)
  plt.imshow(features['image'][..., n])
  plt.title(chr(features['m_label'][n]))
  plt.axis('off')

पीएनजी

निचले स्तर के कार्य

अब तक इस ट्यूटोरियल ने csv डेटा पढ़ने के लिए उच्चतम स्तर की उपयोगिताओं पर ध्यान केंद्रित किया है। अन्य दो एपीआई हैं जो उन्नत उपयोगकर्ताओं के लिए सहायक हो सकती हैं यदि आपका उपयोग-मामला बुनियादी पैटर्न में फिट नहीं होता है।

  • tf.io.decode_csv - CSV कॉलम टेंसर की सूची में टेक्स्ट की पंक्तियों को पार्स करने के लिए एक फ़ंक्शन।
  • tf.data.experimental.CsvDataset - एक निचला स्तर csv डेटासेट कंस्ट्रक्टर।

यह खंड make_csv_dataset द्वारा प्रदान की गई कार्यक्षमता को फिर से प्रदर्शित करता है, यह प्रदर्शित करने के लिए कि इस निचले स्तर की कार्यक्षमता का उपयोग कैसे किया जा सकता है।

tf.io.decode_csv

यह फ़ंक्शन एक स्ट्रिंग, या स्ट्रिंग्स की सूची को कॉलम की सूची में डीकोड करता है।

make_csv_dataset विपरीत यह फ़ंक्शन कॉलम डेटा-प्रकारों का अनुमान लगाने का प्रयास नहीं करता है। आप प्रत्येक कॉलम के लिए सही प्रकार के मान वाले record_defaults सूची प्रदान करके कॉलम प्रकार निर्दिष्ट करते हैं।

टाइटैनिक डेटा को decode_csv का उपयोग करके स्ट्रिंग्स के रूप में पढ़ने के लिए आप कहेंगे:

text = pathlib.Path(titanic_file_path).read_text()
lines = text.split('\n')[1:-1]

all_strings = [str()]*10
all_strings
['', '', '', '', '', '', '', '', '', '']
features = tf.io.decode_csv(lines, record_defaults=all_strings) 

for f in features:
  print(f"type: {f.dtype.name}, shape: {f.shape}")
type: string, shape: (627,)
type: string, shape: (627,)
type: string, shape: (627,)
type: string, shape: (627,)
type: string, shape: (627,)
type: string, shape: (627,)
type: string, shape: (627,)
type: string, shape: (627,)
type: string, shape: (627,)
type: string, shape: (627,)

उन्हें उनके वास्तविक प्रकारों के साथ पार्स करने के लिए, संबंधित प्रकार के record_defaults की एक सूची बनाएं:

print(lines[0])
0,male,22.0,1,0,7.25,Third,unknown,Southampton,n
titanic_types = [int(), str(), float(), int(), int(), float(), str(), str(), str(), str()]
titanic_types
[0, '', 0.0, 0, 0, 0.0, '', '', '', '']
features = tf.io.decode_csv(lines, record_defaults=titanic_types) 

for f in features:
  print(f"type: {f.dtype.name}, shape: {f.shape}")
type: int32, shape: (627,)
type: string, shape: (627,)
type: float32, shape: (627,)
type: int32, shape: (627,)
type: int32, shape: (627,)
type: float32, shape: (627,)
type: string, shape: (627,)
type: string, shape: (627,)
type: string, shape: (627,)
type: string, shape: (627,)

tf.data.experimental.CsvDataset

tf.data.experimental.CsvDataset वर्ग make_csv_dataset फ़ंक्शन की सुविधा सुविधाओं के बिना एक न्यूनतम CSV Dataset इंटरफ़ेस प्रदान करता है: कॉलम हेडर पार्सिंग, कॉलम प्रकार-अनुमान, स्वचालित फेरबदल, फ़ाइल इंटरलीविंग।

यह निर्माता का उपयोग करता है इस प्रकार है record_defaults के रूप में एक ही तरह से io.parse_csv :

simple_titanic = tf.data.experimental.CsvDataset(titanic_file_path, record_defaults=titanic_types, header=True)

for example in simple_titanic.take(1):
  print([e.numpy() for e in example])
[0, b'male', 22.0, 1, 0, 7.25, b'Third', b'unknown', b'Southampton', b'n']

उपरोक्त कोड मूल रूप से इसके बराबर है:

def decode_titanic_line(line):
  return tf.io.decode_csv(line, titanic_types)

manual_titanic = (
    # Load the lines of text
    tf.data.TextLineDataset(titanic_file_path)
    # Skip the header row.
    .skip(1)
    # Decode the line.
    .map(decode_titanic_line)
)

for example in manual_titanic.take(1):
  print([e.numpy() for e in example])
[0, b'male', 22.0, 1, 0, 7.25, b'Third', b'unknown', b'Southampton', b'n']

एकाधिक फ़ाइलें

experimental.CsvDataset . record_defaults का उपयोग करके फ़ॉन्ट डेटासेट को पार्स करने के लिए, आपको पहले record_defaults लिए कॉलम प्रकार निर्धारित करने की आवश्यकता है। एक फ़ाइल की पहली पंक्ति का निरीक्षण करके प्रारंभ करें:

font_line = pathlib.Path(font_csvs[0]).read_text().splitlines()[1]
print(font_line)
AGENCY,AGENCY FB,64258,0.400000,0,0.000000,35,21,51,22,20,20,1,1,1,21,101,210,255,255,255,255,255,255,255,255,255,255,255,255,255,255,1,1,1,93,255,255,255,176,146,146,146,146,146,146,146,146,216,255,255,255,1,1,1,93,255,255,255,70,1,1,1,1,1,1,1,1,163,255,255,255,1,1,1,93,255,255,255,70,1,1,1,1,1,1,1,1,163,255,255,255,1,1,1,93,255,255,255,70,1,1,1,1,1,1,1,1,163,255,255,255,1,1,1,93,255,255,255,70,1,1,1,1,1,1,1,1,163,255,255,255,1,1,1,93,255,255,255,70,1,1,1,1,1,1,1,1,163,255,255,255,141,141,141,182,255,255,255,172,141,141,141,115,1,1,1,1,163,255,255,255,255,255,255,255,255,255,255,255,255,255,255,209,1,1,1,1,163,255,255,255,6,6,6,96,255,255,255,74,6,6,6,5,1,1,1,1,163,255,255,255,1,1,1,93,255,255,255,70,1,1,1,1,1,1,1,1,163,255,255,255,1,1,1,93,255,255,255,70,1,1,1,1,1,1,1,1,163,255,255,255,1,1,1,93,255,255,255,70,1,1,1,1,1,1,1,1,163,255,255,255,1,1,1,93,255,255,255,70,1,1,1,1,1,1,1,1,163,255,255,255,1,1,1,93,255,255,255,70,1,1,1,1,1,1,1,1,163,255,255,255,1,1,1,93,255,255,255,70,1,1,1,1,1,1,1,1,163,255,255,255,1,1,1,93,255,255,255,70,1,1,1,1,1,1,1,1,163,255,255,255,1,1,1,93,255,255,255,70,1,1,1,1,1,1,1,1,163,255,255,255,1,1,1,93,255,255,255,70,1,1,1,1,1,1,1,1,163,255,255,255,1,1,1,93,255,255,255,70,1,1,1,1,1,1,1,1,163,255,255,255

केवल पहले दो फ़ील्ड स्ट्रिंग हैं, बाकी इनट्स या फ़्लोट्स हैं, और आप कॉमा की गणना करके सुविधाओं की कुल संख्या प्राप्त कर सकते हैं:

०७४५२२९बी६०

CsvDatasaet कंस्ट्रक्टर इनपुट फ़ाइलों की एक सूची ले सकता है, लेकिन उन्हें क्रमिक रूप से पढ़ता है। CSV की सूची में पहली फ़ाइल AGENCY.csv :

font_csvs[0]
'fonts/AGENCY.csv'

तो जब आप करने के लिए फ़ाइलों की सूची पारित गुजरती CsvDataaset से रिकॉर्ड AGENCY.csv पहले पढ़ रहे हैं:

simple_font_ds = tf.data.experimental.CsvDataset(
    font_csvs, 
    record_defaults=font_column_types, 
    header=True)
for row in simple_font_ds.take(10):
  print(row[0].numpy())
b'AGENCY'
b'AGENCY'
b'AGENCY'
b'AGENCY'
b'AGENCY'
b'AGENCY'
b'AGENCY'
b'AGENCY'
b'AGENCY'
b'AGENCY'

एकाधिक फ़ाइलों को इंटरलीव करने के लिए, Dataset.interleave उपयोग Dataset.interleave

यहां एक प्रारंभिक डेटासेट है जिसमें csv फ़ाइल नाम हैं:

०बी२५०७डी०

यह फ़ाइल नामों को प्रत्येक युग में फेरबदल करता है:

print('Epoch 1:')
for f in list(font_files)[:5]:
  print("    ", f.numpy())
print('    ...')
print()

print('Epoch 2:')
for f in list(font_files)[:5]:
  print("    ", f.numpy())
print('    ...')
Epoch 1:
     b'fonts/BROADWAY.csv'
     b'fonts/COPPERPLATE.csv'
     b'fonts/STENCIL.csv'
     b'fonts/COOPER.csv'
     b'fonts/GABRIOLA.csv'
    ...

Epoch 2:
     b'fonts/MONOSPAC821.csv'
     b'fonts/ONYX.csv'
     b'fonts/HARLOW.csv'
     b'fonts/TIMES.csv'
     b'fonts/JOKERMAN.csv'
    ...

interleave विधि एक map_func लेती है जो माता-पिता के प्रत्येक तत्व के लिए एक map_func Dataset बनाता map_func Dataset

यहां, आप फ़ाइलों के डेटासेट के प्रत्येक तत्व से एक CsvDataset बनाना चाहते हैं:

def make_font_csv_ds(path):
  return tf.data.experimental.CsvDataset(
    path, 
    record_defaults=font_column_types, 
    header=True)

इंटरलीव द्वारा लौटाया गया Dataset कई बच्चे- Dataset s पर साइकिल चलाकर तत्वों को लौटाता है। ध्यान दें, नीचे, कैसे डेटासेट cycle_length)=3 पर cycle_length)=3 तीन फ़ॉन्ट फ़ाइलें:

font_rows = font_files.interleave(make_font_csv_ds,
                                  cycle_length=3)
fonts_dict = {'font_name':[], 'character':[]}

for row in font_rows.take(10):
  fonts_dict['font_name'].append(row[0].numpy().decode())
  fonts_dict['character'].append(chr(row[2].numpy()))

pd.DataFrame(fonts_dict)

प्रदर्शन

इससे पहले, यह नोट किया गया था कि स्ट्रिंग्स के बैच पर चलने पर io.decode_csv अधिक कुशल है।

सीएसवी लोडिंग प्रदर्शन में सुधार करने के लिए, बड़े बैच आकारों का उपयोग करते समय इस तथ्य का लाभ उठाना संभव है (लेकिन पहले कैशिंग का प्रयास करें)।

बिल्ट-इन लोडर 20 के साथ, 2048-उदाहरण बैचों में लगभग 17 सेकंड लगते हैं।

BATCH_SIZE=2048
fonts_ds = tf.data.experimental.make_csv_dataset(
    file_pattern = "fonts/*.csv",
    batch_size=BATCH_SIZE, num_epochs=1,
    num_parallel_reads=100)
%%time
for i,batch in enumerate(fonts_ds.take(20)):
  print('.',end='')

print()
....................
CPU times: user 26.8 s, sys: 1.75 s, total: 28.6 s
Wall time: 11.1 s

टेक्स्ट लाइनों के बैच को decode_csv में पास करना लगभग 5 decode_csv तेजी से चलता है:

fonts_files = tf.data.Dataset.list_files("fonts/*.csv")
fonts_lines = fonts_files.interleave(
    lambda fname:tf.data.TextLineDataset(fname).skip(1), 
    cycle_length=100).batch(BATCH_SIZE)

fonts_fast = fonts_lines.map(lambda x: tf.io.decode_csv(x, record_defaults=font_column_types))
%%time
for i,batch in enumerate(fonts_fast.take(20)):
  print('.',end='')

print()
....................
CPU times: user 9.29 s, sys: 0 ns, total: 9.29 s
Wall time: 1.48 s

बड़े बैचों का उपयोग करके सीएसवी प्रदर्शन बढ़ाने के एक अन्य उदाहरण के लिए ओवरफिट और अंडरफिट ट्यूटोरियल देखें

इस प्रकार का दृष्टिकोण काम कर सकता है, लेकिन cache और snapshot जैसे अन्य विकल्पों पर विचार करें, या अपने डेटा को अधिक सुव्यवस्थित प्रारूप में फिर से एन्कोड करें।