Bir sorunuz mu var? TensorFlow Forum Ziyaret Forumunda toplulukla bağlantı kurun

CSV verilerini yükle

TensorFlow.org'da görüntüleyin Google Colab'de çalıştırın Kaynağı GitHub'da görüntüleyinDefteri indirin

Bu eğitici, CSV verilerinin TensorFlow ile nasıl kullanılacağına dair örnekler sağlar.

Bunun iki ana bölümü var:

  1. Verileri diskten yükleme
  2. Eğitime uygun bir formda ön işlemden geçirin.

Bu eğitim, yüklemeye odaklanır ve bazı hızlı ön işleme örnekleri verir. Ön işleme yönüne odaklanan bir eğitim için ön işleme katmanları kılavuzu ve öğreticiye bakın .

Kurulum

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

Bellek verilerinde

Herhangi bir küçük CSV veri kümesi için bir TensorFlow modelini eğitmenin en basit yolu, onu pandas Veri Çerçevesi veya NumPy dizisi olarak belleğe yüklemektir.

Nispeten basit bir örnek, deniz kulağı veri kümesidir .

  • Veri kümesi küçük.
  • Tüm giriş özelliklerinin tümü sınırlı aralıklı kayan nokta değerleridir.

Verileri Pandas DataFrame nasıl indireceğiniz aşağıda 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()

Veri seti, bir tür deniz salyangozu olan denizkulağının bir dizi ölçümünü içerir.

bir deniz kulağı kabuğu

"Abalone kabuğu" ( Nicki Dugan Pogue , CC BY-SA 2.0)

Bu veri kümesinin nominal görevi, diğer ölçümlerden yaşı tahmin etmektir, bu nedenle eğitim için özellikleri ve etiketleri ayırın:

abalone_features = abalone_train.copy()
abalone_labels = abalone_features.pop('Age')

Bu veri kümesi için tüm özellikleri aynı şekilde ele alacaksınız. Özellikleri tek bir NumPy dizisinde paketleyin .:

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

Sonra yaşı tahmin etmek için bir regresyon modeli yapın. Sadece tek bir giriş tensörü olduğundan, bir keras.Sequential . keras.Sequential model burada yeterlidir.

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

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

Bu modeli eğitmek için, özellikleri ve etiketleri Model.fit :

abalone_model.fit(abalone_features, abalone_labels, epochs=10)
Epoch 1/10
104/104 [==============================] - 1s 2ms/step - loss: 61.2118
Epoch 2/10
104/104 [==============================] - 0s 2ms/step - loss: 11.9831
Epoch 3/10
104/104 [==============================] - 0s 2ms/step - loss: 8.7308
Epoch 4/10
104/104 [==============================] - 0s 1ms/step - loss: 8.1889
Epoch 5/10
104/104 [==============================] - 0s 2ms/step - loss: 7.6973
Epoch 6/10
104/104 [==============================] - 0s 2ms/step - loss: 7.2868
Epoch 7/10
104/104 [==============================] - 0s 2ms/step - loss: 6.9842
Epoch 8/10
104/104 [==============================] - 0s 1ms/step - loss: 6.7556
Epoch 9/10
104/104 [==============================] - 0s 1ms/step - loss: 6.6239
Epoch 10/10
104/104 [==============================] - 0s 2ms/step - loss: 6.5126
<tensorflow.python.keras.callbacks.History at 0x7f4bf8402410>

CSV verilerini kullanarak bir modeli eğitmenin en basit yolunu gördünüz. Daha sonra, sayısal sütunları normalleştirmek için ön işlemenin nasıl uygulanacağını öğreneceksiniz.

Temel ön işleme

Girdileri modelinize göre normalleştirmek iyi bir uygulamadır. experimental.preprocessing katmanları, bu normalleştirmeyi modelinize yerleştirmek için uygun bir yol sağlar.

Katman, her sütunun ortalamasını ve varyansını önceden hesaplayacak ve verileri normalleştirmek için bunları kullanacaktır.

İlk önce katmanı oluşturursunuz:

normalize = preprocessing.Normalization()

Ardından, normalleştirme katmanını verilerinize uyarlamak için Normalization.adapt() yöntemini kullanırsınız.

normalize.adapt(abalone_features)

Ardından modelinizdeki normalleştirme katmanını kullanın:

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.2295
Epoch 2/10
104/104 [==============================] - 0s 2ms/step - loss: 52.6606
Epoch 3/10
104/104 [==============================] - 0s 2ms/step - loss: 15.8834
Epoch 4/10
104/104 [==============================] - 0s 2ms/step - loss: 5.6510
Epoch 5/10
104/104 [==============================] - 0s 2ms/step - loss: 5.0132
Epoch 6/10
104/104 [==============================] - 0s 2ms/step - loss: 4.9937
Epoch 7/10
104/104 [==============================] - 0s 2ms/step - loss: 4.9871
Epoch 8/10
104/104 [==============================] - 0s 2ms/step - loss: 4.9607
Epoch 9/10
104/104 [==============================] - 0s 2ms/step - loss: 4.9417
Epoch 10/10
104/104 [==============================] - 0s 2ms/step - loss: 4.9781
<tensorflow.python.keras.callbacks.History at 0x7f4bf8188490>

Karışık veri türleri

"Titanik" veri kümesi, Titanik'teki yolcular hakkında bilgi içerir. Bu veri setindeki nominal görev, kimin hayatta kaldığını tahmin etmektir.

Titanik

Wikimedia'dan görüntü

Ham veriler, Pandas DataFrame olarak kolayca yüklenebilir, ancak bir TensorFlow modeline girdi olarak hemen kullanılamaz.

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

Farklı veri türleri ve aralıkları nedeniyle özellikleri NumPy dizisine istifleyemez ve bir keras.Sequential modeline keras.Sequential . Her sütunun ayrı ayrı ele alınması gerekir.

Bir seçenek olarak, kategorik sütunları sayısal sütunlara dönüştürmek için verilerinizi çevrimdışı olarak (istediğiniz herhangi bir aracı kullanarak) önceden işleyebilir, ardından işlenen çıktıyı TensorFlow modelinize iletebilirsiniz. Bu yaklaşımın dezavantajı, modelinizi kaydedip dışa aktarırsanız, ön işlemin onunla birlikte kaydedilmemesidir. experimental.preprocessing katmanları, modelin bir parçası oldukları için bu sorunu önler.

Bu örnekte, Keras işlevsel API'sini kullanarak ön işleme mantığını uygulayan bir model oluşturacaksınız. Bunu alt sınıflara ayırarak da yapabilirsiniz.

İşlevsel API, "sembolik" tensörler üzerinde çalışır. Normal "istekli" tensörlerin bir değeri vardır. Bunun aksine, bu "sembolik" tensörler bunu yapmaz. Bunun yerine, üzerlerinde hangi işlemlerin çalıştırıldığını izlerler ve daha sonra çalıştırabileceğiniz hesaplamanın temsilini oluştururlar. İşte hızlı bir örnek:

# 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

Önişleme modelini oluşturmak için, CSV sütunlarının adlarını ve veri türlerini eşleştiren bir dizi sembolik keras.Input nesneleri 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')>}

Ön işleme mantığınızın ilk adımı, sayısal girişleri bir araya getirip bir normalleştirme katmanından geçirmektir:

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

Daha sonra birleştirmek için tüm sembolik ön işleme sonuçlarını toplayın.

preprocessed_inputs = [all_numeric_inputs]

Dize girdileri için, bir sözcük dağarcığındaki dizelerden tamsayı dizinlerine eşlemek için preprocessing.StringLookup işlevini kullanın. Ardından, dizinleri modele uygun float32 verilerine dönüştürmek için preprocessing.CategoryEncoding kullanın.

preprocessing.CategoryEncoding katmanı için varsayılan ayarlar, her girdi için bir sıcak vektör oluşturur. layers.Embedding de işe layers.Embedding . Bu konu hakkında daha fazla bilgi için ön işleme katmanları kılavuzuna ve eğiticiye bakın.

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 ve processed_inputs inputs koleksiyonuyla, önceden processed_inputs tüm girdileri bir araya getirebilir ve ön işlemeyi işleyen bir model oluşturabilirsiniz:

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)

png

Bu model yalnızca giriş ön işlemesini içerir. Verilerinize ne yaptığını görmek için çalıştırabilirsiniz. Keras modelleri, Pandas DataFrames otomatik olarak dönüştürmez çünkü tek bir DataFrames mi yoksa bir tensör sözlüğüne mi dönüştürülmesi gerektiği açık değildir. Öyleyse onu tensör sözlüğüne dönüştürün:

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

İlk eğitim örneğini dilimleyin ve bu ön işleme modeline iletin, sayısal özellikleri ve tek hots dizisinin bir araya getirildiğini görürsünüz:

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

Şimdi modeli bunun üzerine inşa edin:

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)

Modeli eğittiğinizde, özellikler sözlüğünü x ve etiketi y olarak y .

titanic_model.fit(x=titanic_features_dict, y=titanic_labels, epochs=10)
Epoch 1/10
20/20 [==============================] - 1s 4ms/step - loss: 0.6321
Epoch 2/10
20/20 [==============================] - 0s 4ms/step - loss: 0.5221
Epoch 3/10
20/20 [==============================] - 0s 4ms/step - loss: 0.4835
Epoch 4/10
20/20 [==============================] - 0s 4ms/step - loss: 0.4595
Epoch 5/10
20/20 [==============================] - 0s 4ms/step - loss: 0.4463
Epoch 6/10
20/20 [==============================] - 0s 4ms/step - loss: 0.4381
Epoch 7/10
20/20 [==============================] - 0s 4ms/step - loss: 0.4299
Epoch 8/10
20/20 [==============================] - 0s 4ms/step - loss: 0.4272
Epoch 9/10
20/20 [==============================] - 0s 4ms/step - loss: 0.4238
Epoch 10/10
20/20 [==============================] - 0s 4ms/step - loss: 0.4236
<tensorflow.python.keras.callbacks.History at 0x7f4c97f3a0d0>

Ön işleme modelin bir parçası olduğundan, modeli kaydedip başka bir yere yeniden yükleyebilir ve aynı sonuçları elde edebilirsiniz:

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.878]], shape=(1, 1), dtype=float32)
tf.Tensor([[-1.878]], shape=(1, 1), dtype=float32)

Tf.data kullanma

Önceki bölümde, modeli eğitirken modelin yerleşik veri karıştırma ve gruplamasına güvendiniz.

Giriş veri hattı üzerinde daha fazla kontrole ihtiyacınız varsa veya belleğe kolayca sığmayan verileri kullanmanız gerekiyorsa: tf.data kullanın.

Daha fazla örnek için tf.data kılavuzuna bakın .

Hafıza verilerinde açık

tf.data CSV verilerine uygulamanın ilk örneği olarak, önceki bölümdeki özellikler sözlüğünü manuel olarak dilimlemek için aşağıdaki kodu göz önünde bulundurun. Her dizin için, her özellik için bu dizini alır:

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

Bunu çalıştırın ve ilk örneği yazdırın:

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

Bellek veri yükleyicisindeki en temeltf.data.Dataset , Dataset.from_tensor_slices yapıcısıdır. Bu,tf.data.Dataset yukarıdaki slices işlevinin genelleştirilmiş bir sürümünü uygulayan birtf.data.Dataset döndürür.

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

tf.data.Dataset diğer herhangi bir python gibi birtf.data.Dataset üzerinde yineleme yapabilirsiniz:

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 işlevi, iç içe geçmiş sözlüklerin veya tuple'ların herhangi bir yapısını işleyebilir. Aşağıdaki kod, (features_dict, labels) çiftlerinden oluşan bir veri kümesi oluşturur:

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

Bu Dataset kullanarak bir modeli eğitmek için, en azından verileri shuffle ve batch gerekir.

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

features ve labels Model.fit geçirmek yerine, veri kümesini iletirsiniz:

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

Tek bir dosyadan

Şimdiye kadar bu eğitim, bellek içi verilerle çalıştı. tf.data , veri ardışık tf.data için oldukça ölçeklenebilir bir araç setidir ve CSV dosyalarının yüklenmesiyle ilgili birkaç işlev sağlar.

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

Şimdi CSV verilerini dosyadan okuyun ve birtf.data.Dataset .

(Tam dokümantasyon için tf.data.experimental.make_csv_dataset bakın)

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

Bu işlev birçok kullanışlı özelliği içerir, böylece verilerle çalışmak kolaydır. Bu içerir:

  • Sütun başlıklarını sözlük tuşları olarak kullanma.
  • Her bir sütunun türünü otomatik olarak belirleme.
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'male' b'male' b'male']
age                 : [28. 44. 40. 16. 25.]
n_siblings_spouses  : [8 0 0 0 1]
parch               : [2 0 0 0 0]
fare                : [69.55   7.925  0.    10.5   91.079]
class               : [b'Third' b'Third' b'First' b'Second' b'First']
deck                : [b'unknown' b'unknown' b'B' b'unknown' b'B']
embark_town         : [b'Southampton' b'Southampton' b'Southampton' b'Southampton' b'Cherbourg']
alone               : [b'n' b'y' b'y' b'y' b'n']

label               : [0 1 0 0 1]

Ayrıca verileri anında sıkıştırabilir. İşte metropol eyaletler arası trafik veri kümesini içeren gzip'lenmiş bir CSV dosyası

Trafik sıkışıklığı.

Wikimedia'dan görüntü

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

Doğrudan sıkıştırılmış dosyadan okumak için compression_type bağımsız değişkenini ayarlayın:

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                : [291.08 273.08 296.58 301.02 288.18]
rain_1h             : [0.   0.   0.25 0.   0.  ]
snow_1h             : [0. 0. 0. 0. 0.]
clouds_all          : [ 1 90  0  0  0]
weather_main        : [b'Clear' b'Clouds' b'Rain' b'Clear' b'Clear']
weather_description : [b'sky is clear' b'overcast clouds' b'light rain' b'Sky is Clear'
 b'Sky is Clear']
date_time           : [b'2013-05-17 01:00:00' b'2013-04-11 08:00:00' b'2013-06-12 19:00:00'
 b'2013-08-26 23:00:00' b'2013-07-25 05:00:00']

label               : [ 475 3069 3342 1133 2903]

Önbelleğe almak

Csv verilerini ayrıştırmanın bazı ek yükleri vardır. Küçük modeller için bu, eğitimdeki darboğaz olabilir.

Kullanım durumunuza bağlı olarak, csv verilerinin yalnızca ilk dönemde ayrıştırılması için Dataset.cache veya data.experimental.snapshot kullanmak iyi bir fikir olabilir.

cache ve snapshot yöntemleri arasındaki temel fark, cache dosyalarının yalnızca onları oluşturan TensorFlow işlemi tarafından kullanılabilmesi, ancak snapshot dosyalarının diğer işlemler tarafından okunabilmesidir.

Örneğin, yineleme traffic_volume_csv_gz_ds 20 kez, önbelleğe alma ~ 2s önbelleğe alma olmadan ~ 15 saniye sürer, ya da.

%%time
for i, (batch, label) in enumerate(traffic_volume_csv_gz_ds.repeat(20)):
  if i % 40 == 0:
    print('.', end='')
print()
...............................................................................................
CPU times: user 16.8 s, sys: 4.11 s, total: 20.9 s
Wall time: 12.9 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.55 s, sys: 198 ms, total: 1.75 s
Wall time: 1.37 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.31 s, sys: 396 ms, total: 2.7 s
Wall time: 1.64 s

Veri yüklemeniz csv dosyaları yüklenerek yavaşladıysa ve cache ve snapshot kullanım durumunuz için yetersizse, verilerinizi daha akıcı bir biçimde yeniden kodlamayı düşünün.

Birden çok dosya

Bu bölümde şimdiye kadarki tüm örnekler tf.data olmadan kolaylıkla yapılabilir. tf.data işleri gerçekten basitleştirebileceği yerlerden biri de dosya koleksiyonlarıyla uğraşırken.

Örneğin, karakter yazı tipi görüntüleri veri kümesi, her yazı tipi için bir csv dosyaları koleksiyonu olarak dağıtılır.

Yazı tipleri

Tarafından Görüntü Willi Heidelbach dan Pixabay

Veri kümesini indirin ve içindeki dosyalara bir göz atın:

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

Bir grup file_pattern uğraşırken, glob tarzı bir file_pattern experimental.make_csv_dataset işlevine geçirebilirsiniz. Dosyaların sırası her yinelemede karıştırılır.

Paralel olarak kaç dosyanın okunduğunu ve birbirine num_parallel_reads ayarlamak için num_parallel_reads bağımsız değişkenini kullanın.

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)

Bu csv dosyalarında görüntüler tek bir satırda düzleştirilmiştir. Sütun adları r{row}c{column} olarak biçimlendirilmiştir. İşte ilk parti:

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'CANDARA' b'SWIS721' b'BROADWAY' b'MONOTYPE' b'VIVALDI' b'SWIS721'
 b'MINGLIU' b'SNAP' b'BROADWAY' b'OCRA']
fontVariant         : [b'CANDARA' b'SWIS721 LTEX BT' b'BROADWAY' b'MONOTYPE CORSIVA' b'VIVALDI'
 b'SWIS721 LTEX BT' b'MINGLIU_HKSCS-EXTB' b'SNAP ITC' b'BROADWAY'
 b'scanned']
m_label             : [7901  172  163 1056  214  229  215   48  123   50]
strength            : [0.4 0.4 0.4 0.4 0.4 0.4 0.4 0.4 0.4 0.4]
italic              : [0 1 1 0 1 1 1 0 1 0]
orientation         : [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
m_top               : [37 56 35 42 25 31 42 40 35  0]
m_left              : [23 36 22 25 26 27 22 22 34  0]
originalH           : [48 16 51 40 56 54 35 49 54 32]
originalW           : [39 41 49 40 57 40 40 53 36 22]
h                   : [20 20 20 20 20 20 20 20 20 20]
w                   : [20 20 20 20 20 20 20 20 20 20]
r0c0                : [  1 131   1   1   1   1   1   1   1  24]
r0c1                : [  1 255   1   1   1   1   1   1   1 227]
r0c2                : [  1 255   1   1   1   1   1   1   1  96]
r0c3                : [142 255   1   1   1   1   1   1   1 154]
...
[total: 412 features]

İsteğe bağlı: Paketleme alanları

Muhtemelen her pikselle bunun gibi ayrı sütunlarda çalışmak istemezsiniz. Bu veri kümesini kullanmaya çalışmadan önce pikselleri bir görüntü tensörüne paketlediğinizden emin olun.

Her örnek için görüntüler oluşturmak üzere sütun adlarını ayrıştıran kod:

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

Bu işlevi veri kümesindeki her partiye uygulayın:

fonts_image_ds = fonts_ds.map(make_images)

for features in fonts_image_ds.take(1):
  break

Ortaya çıkan görüntüleri çizin:

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')
/home/kbuilder/.local/lib/python3.7/site-packages/matplotlib/backends/backend_agg.py:240: RuntimeWarning: Glyph 3926 missing from current font.
  font.set_text(s, 0.0, flags=flags)
/home/kbuilder/.local/lib/python3.7/site-packages/matplotlib/backends/backend_agg.py:203: RuntimeWarning: Glyph 3926 missing from current font.
  font.set_text(s, 0, flags=flags)

png

Alt seviye fonksiyonlar

Şimdiye kadar bu eğitim, csv verilerini okumak için en üst düzey yardımcı programlara odaklanmıştır. Kullanım durumunuz temel kalıplara uymuyorsa, ileri düzey kullanıcılar için yararlı olabilecek başka iki API vardır.

Bu bölüm, bu daha düşük düzeydeki işlevselliğin nasıl kullanılabileceğini göstermek için make_csv_dataset tarafından sağlanan işlevselliği yeniden oluşturur.

tf.io.decode_csv

Bu işlev bir dizenin veya dizge listesinin kodunu bir sütun listesine çözer.

make_csv_dataset aksine, bu işlev sütun veri türlerini tahmin etmeye çalışmaz. Her sütun için doğru türde bir değer içeren record_defaults bir listesini sağlayarak sütun türlerini belirtirsiniz.

Titanik verilerini decode_csv kullanarak dizeler olarak okumak için şunu söyleyeceksiniz:

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

Bunları gerçek türleriyle ayrıştırmak için karşılık gelen türlerin record_defaults bir listesini oluşturun:

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 sınıfı, make_csv_dataset işlevinin kolaylık özellikleri olmadan minimal bir CSV Dataset arabirimi sağlar: sütun başlığı ayrıştırma, sütun türü çıkarımı, otomatik karıştırma, dosya araya make_csv_dataset .

Bu yapıcı kullanımları aşağıdaki record_defaults aynı şekilde 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']

Yukarıdaki kod temelde şuna eşdeğerdir:

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

Birden çok dosya

Yazı tipi veri kümesini experimental.CsvDataset kullanarak ayrıştırmak için, önce record_defaults için sütun türlerini belirlemeniz gerekir. Bir dosyanın ilk satırını inceleyerek başlayın:

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

Yalnızca ilk iki alan dizedir, geri kalanı tamsayılar veya kayan alanlardır ve virgül sayarak toplam özellik sayısını elde edebilirsiniz:

num_font_features = font_line.count(',')+1
font_column_types = [str(), str()] + [float()]*(num_font_features-2)

CsvDatasaet yapıcısı, giriş dosyalarının bir listesini alabilir, ancak bunları sırayla okur. AGENCY.csv listesindeki ilk dosya AGENCY.csv :

font_csvs[0]
'fonts/AGENCY.csv'

Eğer dosyaların listesini iletmek geçtiğinde Yani CsvDataaset kayıtları AGENCY.csv ilk okunur:

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'

Birden çok dosyayı araya Dataset.interleave için Dataset.interleave kullanın.

İşte csv dosya adlarını içeren bir ilk veri kümesi:

font_files = tf.data.Dataset.list_files("fonts/*.csv")

Bu, her dönemin dosya adlarını karıştırır:

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/MAIANDRA.csv'
     b'fonts/MODERN.csv'
     b'fonts/VIN.csv'
     b'fonts/CONSTANTIA.csv'
     b'fonts/PROXY.csv'
    ...

Epoch 2:
     b'fonts/ROMAN.csv'
     b'fonts/TAHOMA.csv'
     b'fonts/BRITANNIC.csv'
     b'fonts/OCRA.csv'
     b'fonts/TW.csv'
    ...

interleave yöntem alır map_func içinde bir çocuk yaratır Dataset ebeveyn her bir öğesi için Dataset .

Burada, dosyaların veri kümesinin her öğesinden bir CsvDataset oluşturmak istiyorsunuz:

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

Interleave tarafından döndürülen Dataset , bir dizi alt Dataset üzerinde dönerek öğeleri döndürür. Aşağıda, veri kümesinin cycle_length)=3 üç yazı tipi dosyası üzerinden nasıl 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)

Verim

Daha önce, io.decode_csv bir dizi dizide çalıştırıldığında daha verimli olduğu belirtilmişti.

CSV yükleme performansını iyileştirmek için büyük toplu iş boyutlarını kullanırken bu durumdan yararlanmak mümkündür (ancak önce önbelleğe almayı deneyin).

Yerleşik yükleyici 20 ile, 2048-örnek partiler yaklaşık 17 saniye sürer.

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 27.5 s, sys: 1.53 s, total: 29 s
Wall time: 11.4 s

decode_csv metin satırlarını decode_csv yaklaşık 5 saniyede daha hızlı çalışır:

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.23 s, sys: 0 ns, total: 9.23 s
Wall time: 1.52 s

Büyük gruplar kullanarak csv performansını artırmanın başka bir örneği için, fazla sığdırma ve yetersiz sığdırma eğitimine bakın .

Bu tür bir yaklaşım işe yarayabilir, ancak cache ve snapshot gibi diğer seçenekleri göz önünde bulundurun veya verilerinizi daha akıcı bir biçime yeniden kodlayın.