TensorFlow.org पर देखें | Google Colab में चलाएं | GitHub पर स्रोत देखें | नोटबुक डाउनलोड करें |
यह ट्यूटोरियल TensorFlow के साथ CSV डेटा का उपयोग करने के उदाहरण प्रदान करता है।
इसके दो मुख्य भाग हैं:
- डिस्क से डेटा लोड हो रहा है
- प्रशिक्षण के लिए उपयुक्त रूप में इसे पूर्व-संसाधित करना।
यह ट्यूटोरियल लोडिंग पर केंद्रित है, और प्रीप्रोसेसिंग के कुछ त्वरित उदाहरण देता है। प्रीप्रोसेसिंग पहलू पर ध्यान केंद्रित करने वाले ट्यूटोरियल के लिए प्रीप्रोसेसिंग लेयर्स गाइड और ट्यूटोरियल देखें।
सेट अप
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
मेमोरी डेटा में
किसी भी छोटे 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()
डेटासेट में अबालोन के माप का एक सेट होता है, जो एक प्रकार का समुद्री घोंघा होता है।
"अबालोन शेल" ( निकी दुगन पोग द्वारा, CC BY-SA 2.0)
इस डेटासेट के लिए नाममात्र का कार्य अन्य मापों से आयु की भविष्यवाणी करना है, इसलिए प्रशिक्षण के लिए सुविधाओं और लेबल को अलग करें:
abalone_features = abalone_train.copy()
abalone_labels = abalone_features.pop('Age')
इस डेटासेट के लिए आप सभी सुविधाओं को एक समान मानेंगे। सुविधाओं को एक एकल NumPy सरणी में पैक करें।
abalone_features = np.array(abalone_features)
abalone_features
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.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: 63.0446 Epoch 2/10 104/104 [==============================] - 0s 2ms/step - loss: 11.9429 Epoch 3/10 104/104 [==============================] - 0s 2ms/step - loss: 8.4836 Epoch 4/10 104/104 [==============================] - 0s 2ms/step - loss: 8.0052 Epoch 5/10 104/104 [==============================] - 0s 2ms/step - loss: 7.6073 Epoch 6/10 104/104 [==============================] - 0s 2ms/step - loss: 7.2485 Epoch 7/10 104/104 [==============================] - 0s 2ms/step - loss: 6.9883 Epoch 8/10 104/104 [==============================] - 0s 2ms/step - loss: 6.7977 Epoch 9/10 104/104 [==============================] - 0s 2ms/step - loss: 6.6477 Epoch 10/10 104/104 [==============================] - 0s 2ms/step - loss: 6.5359 <keras.callbacks.History at 0x7f70543c7350>
आपने अभी-अभी CSV डेटा का उपयोग करके किसी मॉडल को प्रशिक्षित करने का सबसे बुनियादी तरीका देखा है। इसके बाद, आप सीखेंगे कि संख्यात्मक कॉलम को सामान्य करने के लिए प्रीप्रोसेसिंग कैसे लागू करें।
बेसिक प्रीप्रोसेसिंग
अपने मॉडल के इनपुट को सामान्य करना एक अच्छा अभ्यास है। केरस प्रीप्रोसेसिंग परतें इस सामान्यीकरण को आपके मॉडल में बनाने का एक सुविधाजनक तरीका प्रदान करती हैं।
परत प्रत्येक कॉलम के माध्य और विचरण को पूर्व-गणना करेगी, और इनका उपयोग डेटा को सामान्य करने के लिए करेगी।
सबसे पहले आप परत बनाएं:
normalize = layers.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: 92.5851 Epoch 2/10 104/104 [==============================] - 0s 2ms/step - loss: 55.1199 Epoch 3/10 104/104 [==============================] - 0s 2ms/step - loss: 18.2937 Epoch 4/10 104/104 [==============================] - 0s 2ms/step - loss: 6.2633 Epoch 5/10 104/104 [==============================] - 0s 2ms/step - loss: 5.1257 Epoch 6/10 104/104 [==============================] - 0s 2ms/step - loss: 5.0217 Epoch 7/10 104/104 [==============================] - 0s 2ms/step - loss: 4.9775 Epoch 8/10 104/104 [==============================] - 0s 2ms/step - loss: 4.9730 Epoch 9/10 104/104 [==============================] - 0s 2ms/step - loss: 4.9348 Epoch 10/10 104/104 [==============================] - 0s 2ms/step - loss: 4.9416 <keras.callbacks.History at 0x7f70541b2a50>
मिश्रित डेटा प्रकार
"टाइटैनिक" डेटासेट में टाइटैनिक के यात्रियों के बारे में जानकारी होती है। इस डेटासेट पर नाममात्र का कार्य यह भविष्यवाणी करना है कि कौन बच गया।
विकिमीडिया से छवि
कच्चे डेटा को आसानी से पंडों के 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 मॉडल में पास कर सकते हैं। उस दृष्टिकोण का नुकसान यह है कि यदि आप अपने मॉडल को सहेजते हैं और निर्यात करते हैं तो इसके साथ प्रीप्रोसेसिंग सहेजा नहीं जाता है। केरस प्रीप्रोसेसिंग परतें इस समस्या से बचती हैं क्योंकि वे मॉडल का हिस्सा हैं।
इस उदाहरण में, आप एक ऐसा मॉडल बनाएंगे जो केरस फंक्शनल एपीआई का उपयोग करके प्रीप्रोसेसिंग लॉजिक को लागू करता है। आप इसे सबक्लासिंग करके भी कर सकते हैं।
कार्यात्मक एपीआई "प्रतीकात्मक" टेंसर पर काम करता है। सामान्य "उत्सुक" टेंसर का एक मूल्य होता है। इसके विपरीत ये "प्रतीकात्मक" टेंसर नहीं करते हैं। इसके बजाय वे ट्रैक करते हैं कि उन पर कौन से ऑपरेशन चल रहे हैं, और गणना का प्रतिनिधित्व करते हैं, जिसे आप बाद में चला सकते हैं। यहाँ एक त्वरित उदाहरण है:
# Create a symbolic input
input = tf.keras.Input(shape=(), dtype=tf.float32)
# Perform a calculation using the input
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
का एक सेट बनाकर शुरू करें। इनपुट ऑब्जेक्ट्स, सीएसवी कॉलम के नाम और डेटा-प्रकार से मेल खाते हैं।
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 = layers.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]
स्ट्रिंग इनपुट के लिए tf.keras.layers.StringLookup
फ़ंक्शन का उपयोग किसी शब्दावली में स्ट्रिंग्स से पूर्णांक इंडेक्स तक मैप करने के लिए करें। इसके बाद, tf.keras.layers.CategoryEncoding
का उपयोग करके इंडेक्स को मॉडल के लिए उपयुक्त फ्लोट32 डेटा में float32
।
tf.keras.layers.CategoryEncoding
परत के लिए डिफ़ॉल्ट सेटिंग्स प्रत्येक इनपुट के लिए एक-हॉट वेक्टर बनाती हैं। एक परत। layers.Embedding
भी काम करेगी। इस विषय पर अधिक जानकारी के लिए प्रीप्रोसेसिंग लेयर गाइड और ट्यूटोरियल देखें।
for name, input in inputs.items():
if input.dtype == tf.float32:
continue
lookup = layers.StringLookup(vocabulary=np.unique(titanic_features[name]))
one_hot = layers.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.प्लेसहोल्डर26
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, 28), dtype=float32, numpy= array([[-0.61 , 0.395, -0.479, -0.497, 0. , 0. , 1. , 0. , 0. , 0. , 1. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 1. , 0. , 0. , 0. , 1. , 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 4ms/step - loss: 0.8017 Epoch 2/10 20/20 [==============================] - 0s 4ms/step - loss: 0.5913 Epoch 3/10 20/20 [==============================] - 0s 5ms/step - loss: 0.5212 Epoch 4/10 20/20 [==============================] - 0s 5ms/step - loss: 0.4841 Epoch 5/10 20/20 [==============================] - 0s 5ms/step - loss: 0.4615 Epoch 6/10 20/20 [==============================] - 0s 5ms/step - loss: 0.4470 Epoch 7/10 20/20 [==============================] - 0s 5ms/step - loss: 0.4367 Epoch 8/10 20/20 [==============================] - 0s 5ms/step - loss: 0.4304 Epoch 9/10 20/20 [==============================] - 0s 4ms/step - loss: 0.4265 Epoch 10/10 20/20 [==============================] - 0s 5ms/step - loss: 0.4239 <keras.callbacks.History at 0x7f70b1f82a50>प्लेसहोल्डर33
चूंकि प्रीप्रोसेसिंग मॉडल का हिस्सा है, आप मॉडल को सहेज सकते हैं और इसे कहीं और पुनः लोड कर सकते हैं और समान परिणाम प्राप्त कर सकते हैं:
titanic_model.save('test')
reloaded = tf.keras.models.load_model('test')
2022-01-26 06:36:18.822459: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them. 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.791]], shape=(1, 1), dtype=float32) tf.Tensor([[-1.791]], shape=(1, 1), dtype=float32)
tf.डेटा का उपयोग करना
पिछले अनुभाग में आपने मॉडल को प्रशिक्षित करते समय मॉडल के अंतर्निहित डेटा फेरबदल और बैचिंग पर भरोसा किया था।
यदि आपको इनपुट डेटा पाइपलाइन पर अधिक नियंत्रण की आवश्यकता है या डेटा का उपयोग करने की आवश्यकता है जो आसानी से मेमोरी में फिट नहीं होता है: 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
देता है जो TensorFlow में उपरोक्त slices
फ़ंक्शन के सामान्यीकृत संस्करण को लागू करता है।
features_ds = tf.data.Dataset.from_tensor_slices(titanic_features_dict)
आप एक 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
फ़ंक्शन नेस्टेड शब्दकोशों या टुपल्स की किसी भी संरचना को संभाल सकता है। निम्नलिखित कोड (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
को पास करने के बजाय, आप डेटासेट पास करते हैं:
titanic_model.fit(titanic_batches, epochs=5)
Epoch 1/5 20/20 [==============================] - 0s 5ms/step - loss: 0.4230 Epoch 2/5 20/20 [==============================] - 0s 5ms/step - loss: 0.4216 Epoch 3/5 20/20 [==============================] - 0s 5ms/step - loss: 0.4203 Epoch 4/5 20/20 [==============================] - 0s 5ms/step - loss: 0.4198 Epoch 5/5 20/20 [==============================] - 0s 5ms/step - loss: 0.4194 <keras.callbacks.History at 0x7f70b12485d0>
एक ही फाइल से
अब तक इस ट्यूटोरियल ने इन-मेमोरी डेटा के साथ काम किया है। 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 40960/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'male' b'female' b'male' b'male'] age : [27. 18. 15. 46. 50.] n_siblings_spouses : [0 0 0 1 0] parch : [0 0 0 0 0] fare : [ 7.896 7.796 7.225 61.175 13. ] class : [b'Third' b'Third' b'Third' b'First' b'Second'] deck : [b'unknown' b'unknown' b'unknown' b'E' b'unknown'] embark_town : [b'Southampton' b'Southampton' b'Cherbourg' b'Southampton' b'Southampton'] alone : [b'y' b'y' b'y' b'n' b'y'] label : [0 0 1 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 1us/step 417792/405373 [==============================] - 1s 1us/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 : [280.56 266.79 281.64 292.71 270.48] rain_1h : [0. 0. 0. 0. 0.] snow_1h : [0. 0. 0. 0. 0.] clouds_all : [46 90 90 0 64] weather_main : [b'Clear' b'Clouds' b'Mist' b'Clear' b'Clouds'] weather_description : [b'sky is clear' b'overcast clouds' b'mist' b'Sky is Clear' b'broken clouds'] date_time : [b'2012-11-05 20:00:00' b'2012-12-17 23:00:00' b'2013-10-06 19:00:00' b'2013-08-23 22:00:00' b'2013-11-11 05:00:00'] label : [2415 966 3459 2633 2576]
कैशिंग
सीएसवी डेटा को पार्स करने के लिए कुछ ओवरहेड है। छोटे मॉडलों के लिए यह प्रशिक्षण में अड़चन हो सकती है।
आपके उपयोग के मामले के आधार पर 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.7 s, total: 18.6 s Wall time: 11.2 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.43 s, sys: 173 ms, total: 1.6 s Wall time: 1.28 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()
WARNING:tensorflow:From <timed exec>:1: snapshot (from tensorflow.python.data.experimental.ops.snapshot) is deprecated and will be removed in a future version. Instructions for updating: Use `tf.data.Dataset.snapshot(...)`. ............................................................................................... CPU times: user 2.17 s, sys: 460 ms, total: 2.63 s Wall time: 1.6 s
यदि csv फ़ाइलों को लोड करने से आपका डेटा लोड धीमा हो जाता है, और cache
और snapshot
आपके उपयोग के मामले के लिए अपर्याप्त हैं, तो अपने डेटा को अधिक सुव्यवस्थित प्रारूप में फिर से एन्कोड करने पर विचार करें।
एकाधिक फ़ाइलें
इस खंड में अब तक के सभी उदाहरण tf.data
के बिना आसानी से किए जा सकते हैं। फाइलों के संग्रह से निपटने के दौरान एक जगह जहां tf.data
वास्तव में चीजों को सरल बना सकता है।
उदाहरण के लिए, कैरेक्टर फॉन्ट इमेज डेटासेट को सीएसवी फाइलों के संग्रह के रूप में वितरित किया जाता है, एक प्रति फॉन्ट।
पिक्साबे से विली हीडलबैक द्वारा छवि
डेटासेट डाउनलोड करें, और अंदर की फाइलों पर एक नजर डालें:
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 160325632/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
.make_csv_dataset फ़ंक्शन में पास कर सकते हैं। फ़ाइलों का क्रम प्रत्येक पुनरावृत्ति में फेरबदल किया जाता है।
समानांतर में कितनी फाइलें पढ़ी जाती हैं और एक साथ इंटरलीव की जाती हैं, यह निर्धारित करने के लिए 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'HANDPRINT' b'NIAGARA' b'EUROROMAN' b'NIAGARA' b'CENTAUR' b'NINA' b'GOUDY' b'SITKA' b'BELL' b'SITKA'] fontVariant : [b'scanned' b'NIAGARA SOLID' b'EUROROMAN' b'NIAGARA SOLID' b'CENTAUR' b'NINA' b'GOUDY STOUT' b'SITKA TEXT' b'BELL MT' b'SITKA TEXT'] m_label : [ 49 8482 245 88 174 9643 77 974 117 339] strength : [0.4 0.4 0.4 0.4 0.4 0.4 0.4 0.4 0.4 0.4] italic : [0 0 0 1 0 0 1 0 1 0] orientation : [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] m_top : [ 0 32 24 32 28 57 38 48 51 64] m_left : [ 0 20 24 20 22 24 27 23 25 23] originalH : [20 27 55 47 50 15 51 50 27 34] originalW : [ 4 33 25 33 50 15 116 43 28 53] h : [20 20 20 20 20 20 20 20 20 20] w : [20 20 20 20 20 20 20 20 20 20] r0c0 : [ 1 255 255 1 1 255 1 1 1 1] r0c1 : [ 1 255 255 1 1 255 1 1 1 1] r0c2 : [ 1 217 255 1 1 255 54 1 1 1] r0c3 : [ 1 213 255 1 1 255 255 1 1 64] ... [total: 412 features]
वैकल्पिक: पैकिंग फ़ील्ड
आप शायद इस तरह के अलग-अलग कॉलम में प्रत्येक पिक्सेल के साथ काम नहीं करना चाहते हैं। इस डेटासेट का उपयोग करने का प्रयास करने से पहले पिक्सेल को इमेज-टेंसर में पैक करना सुनिश्चित करें।
यहां कोड है जो प्रत्येक उदाहरण के लिए छवियों को बनाने के लिए कॉलम नामों को पार करता है:
import re
def make_images(features):
image = [None]*400
new_feats = {}
for name, value in features.items():
match = re.match('r(\d+)c(\d+)', name)
if match:
image[int(match.group(1))*20+int(match.group(2))] = value
else:
new_feats[name] = value
image = tf.stack(image, axis=0)
image = tf.reshape(image, [20, 20, -1])
new_feats['image'] = image
return new_feats
डेटासेट में प्रत्येक बैच में उस फ़ंक्शन को लागू करें:
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
इंटरफ़ेस प्रदान करता है: कॉलम हेडर पार्सिंग, कॉलम प्रकार-अनुमान, स्वचालित फेरबदल, फ़ाइल इंटरलीविंग।
यह कंस्ट्रक्टर io.parse_csv
की तरह ही record_defaults
का उपयोग करता है:
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
.CsvDataset का उपयोग करके फ़ॉन्ट डेटासेट को पार्स करने के लिए, आपको पहले 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
केवल पहले दो फ़ील्ड स्ट्रिंग हैं, बाकी इंट्स या फ़्लोट हैं, और आप कॉमा की गणना करके सुविधाओं की कुल संख्या प्राप्त कर सकते हैं:
num_font_features = font_line.count(',')+1
font_column_types = [str(), str()] + [float()]*(num_font_features-2)
CsvDatasaet
कंस्ट्रक्टर इनपुट फ़ाइलों की एक सूची ले सकता है, लेकिन उन्हें क्रमिक रूप से पढ़ता है। CSV की सूची में पहली फ़ाइल AGENCY.csv
है:
font_csvs[0]
'fonts/AGENCY.csv'
इसलिए जब आप फाइलों की सूची CsvDataset को पास करते हैं तो 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
का उपयोग करें।
यहां एक प्रारंभिक डेटासेट है जिसमें csv फ़ाइल नाम शामिल हैं:
font_files = tf.data.Dataset.list_files("fonts/*.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/CORBEL.csv' b'fonts/GLOUCESTER.csv' b'fonts/GABRIOLA.csv' b'fonts/FORTE.csv' b'fonts/GILL.csv' ... Epoch 2: b'fonts/MONEY.csv' b'fonts/ISOC.csv' b'fonts/DUTCH801.csv' b'fonts/CALIBRI.csv' b'fonts/ROMANTIC.csv' ...
interleave
विधि एक map_func
लेती है जो माता-पिता के प्रत्येक तत्व के लिए एक बच्चा- Dataset
बनाता है- 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
तीन फ़ॉन्ट फ़ाइलों पर चक्रित होता है:
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 24.3 s, sys: 1.46 s, total: 25.7 s Wall time: 10.9 s
टेक्स्ट लाइनों के बैच को decode_csv
में पास करना लगभग 5 सेकंड में तेजी से चलता है:
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 8.77 s, sys: 0 ns, total: 8.77 s Wall time: 1.57 s
बड़े बैचों का उपयोग करके सीएसवी प्रदर्शन बढ़ाने के एक अन्य उदाहरण के लिए ओवरफिट और अंडरफिट ट्यूटोरियल देखें।
इस प्रकार का दृष्टिकोण काम कर सकता है, लेकिन cache
और snapshot
जैसे अन्य विकल्पों पर विचार करें, या अपने डेटा को अधिक सुव्यवस्थित प्रारूप में फिर से एन्कोड करें।