![]() | ![]() | ![]() | ![]() |
tf.data
API, basit, yeniden kullanılabilir parçalardan karmaşık girdi ardışık tf.data
oluşturmanıza olanak tanır. Örneğin, bir görüntü modelinin ardışık düzeni, dağıtılmış bir dosya sistemindeki dosyalardan verileri toplayabilir, her görüntüye rastgele pertürbasyonlar uygulayabilir ve rastgele seçilen görüntüleri eğitim için bir grup halinde birleştirebilir. Bir metin modeli için boru hattı, ham metin verilerinden sembollerin çıkarılmasını, bunları bir arama tablosu ile tanımlayıcıların gömülmesini ve farklı uzunluklardaki dizilerin bir araya toplanmasını içerebilir. tf.data
API, büyük miktarda veriyi işlemeyi, farklı veri biçimlerinden okumayı ve karmaşık dönüşümler gerçekleştirmeyi mümkün kılar.
tf.data
API, her bir öğenin bir veya daha fazla bileşenden oluştuğu bir dizi öğeyi temsil eden birtf.data.Dataset
soyutlaması sunar. Örneğin, bir görüntü ardışık düzeninde bir öğe, görüntüyü ve etiketini temsil eden bir çift tensör bileşenine sahip tek bir eğitim örneği olabilir.
Veri kümesi oluşturmanın iki farklı yolu vardır:
Bir veri kaynağı , bellekte veya bir veya daha fazla dosyada depolanan verilerden bir
Dataset
oluşturur.Bir veri dönüşümü , bir veya daha fazla
tf.data.Dataset
nesnesinden bir veri kümesi oluşturur.
import tensorflow as tf
import pathlib
import os
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
np.set_printoptions(precision=4)
Temel mekanik
Bir giriş ardışık düzeni oluşturmak için bir veri kaynağıyla başlamalısınız. Örneğin, bellekteki verilerden bir Dataset
oluşturmak için tf.data.Dataset.from_tensors()
veya tf.data.Dataset.from_tensor_slices()
. Alternatif olarak, girdi verileriniz önerilen TFRecord biçimindeki bir dosyada saklanıyorsa, tf.data.TFRecordDataset()
kullanabilirsiniz.
Bir Dataset
nesnesine sahip olduğunuzda,tf.data.Dataset
nesnesinde yöntem çağrılarını zincirleyerek onu yeni bir Dataset
dönüştürebilirsiniz . Örneğin, Dataset.map()
gibi öğe başına dönüşümleri ve Dataset.map()
gibi çok öğeli dönüşümleri Dataset.batch()
.tf.data.Dataset
tam listesi içintf.data.Dataset
belgelerine bakın.
Dataset
nesnesi bir Python yinelenebilirdir. Bu, öğelerini bir for döngüsü kullanarak tüketmeyi mümkün kılar:
dataset = tf.data.Dataset.from_tensor_slices([8, 3, 0, 8, 2, 1])
dataset
<TensorSliceDataset shapes: (), types: tf.int32>
for elem in dataset:
print(elem.numpy())
8 3 0 8 2 1
Veya iter
kullanarak açıkça bir Python yineleyicisi oluşturarak ve next
öğelerini kullanarak öğelerini tüketerek:
it = iter(dataset)
print(next(it).numpy())
8
Alternatif olarak, veri kümesi öğeleri, tek bir sonuç üretmek için tüm öğeleri azaltan reduce
dönüşümü kullanılarak tüketilebilir. Aşağıdaki örnek, tamsayılardan oluşan bir veri kümesinin toplamını hesaplamak için reduce
dönüşümünün nasıl kullanılacağını gösterir.
print(dataset.reduce(0, lambda state, value: state + value).numpy())
22
Veri kümesi yapısı
Veri kümesi her biri aynı (iç içe) bir yapıya sahip ve yapısı tek tek bileşenleri herhangi bir tip gösterilebilen ait olabilmektedir öğeleri içeren tf.TypeSpec
de dahil olmak üzere, tf.Tensor
, tf.sparse.SparseTensor
,tf.RaggedTensor
, tf.TensorArray
, veyatf.data.Dataset
.
Dataset.element_spec
özelliği, her bir öğe bileşeninin türünü incelemenizi sağlar. Özellik, tf.TypeSpec
nesnelerinin iç içe geçmiş bir yapısını döndürür; bu, tek bir bileşen, bileşenlerin bir demeti veya bileşenlerin iç içe geçmiş bir demeti olabilen öğenin yapısıyla tf.TypeSpec
. Örneğin:
dataset1 = tf.data.Dataset.from_tensor_slices(tf.random.uniform([4, 10]))
dataset1.element_spec
TensorSpec(shape=(10,), dtype=tf.float32, name=None)
dataset2 = tf.data.Dataset.from_tensor_slices(
(tf.random.uniform([4]),
tf.random.uniform([4, 100], maxval=100, dtype=tf.int32)))
dataset2.element_spec
(TensorSpec(shape=(), dtype=tf.float32, name=None), TensorSpec(shape=(100,), dtype=tf.int32, name=None))
dataset3 = tf.data.Dataset.zip((dataset1, dataset2))
dataset3.element_spec
(TensorSpec(shape=(10,), dtype=tf.float32, name=None), (TensorSpec(shape=(), dtype=tf.float32, name=None), TensorSpec(shape=(100,), dtype=tf.int32, name=None)))
# Dataset containing a sparse tensor.
dataset4 = tf.data.Dataset.from_tensors(tf.SparseTensor(indices=[[0, 0], [1, 2]], values=[1, 2], dense_shape=[3, 4]))
dataset4.element_spec
SparseTensorSpec(TensorShape([3, 4]), tf.int32)
# Use value_type to see the type of value represented by the element spec
dataset4.element_spec.value_type
tensorflow.python.framework.sparse_tensor.SparseTensor
Dataset
kümesi dönüşümleri, herhangi bir yapının veri kümelerini destekler. Kullanırken Dataset.map()
, ve Dataset.filter()
her bir elemanı için bir işlev geçerli dönüşümler, eleman yapısı fonksiyonunun bağımsız değişkenler belirler:
dataset1 = tf.data.Dataset.from_tensor_slices(
tf.random.uniform([4, 10], minval=1, maxval=10, dtype=tf.int32))
dataset1
<TensorSliceDataset shapes: (10,), types: tf.int32>
for z in dataset1:
print(z.numpy())
[4 6 7 3 1 1 6 7 3 7] [6 6 1 7 3 8 9 8 9 4] [2 3 2 2 7 1 8 8 5 9] [6 6 7 8 8 9 2 3 7 8]
dataset2 = tf.data.Dataset.from_tensor_slices(
(tf.random.uniform([4]),
tf.random.uniform([4, 100], maxval=100, dtype=tf.int32)))
dataset2
<TensorSliceDataset shapes: ((), (100,)), types: (tf.float32, tf.int32)>
dataset3 = tf.data.Dataset.zip((dataset1, dataset2))
dataset3
<ZipDataset shapes: ((10,), ((), (100,))), types: (tf.int32, (tf.float32, tf.int32))>
for a, (b,c) in dataset3:
print('shapes: {a.shape}, {b.shape}, {c.shape}'.format(a=a, b=b, c=c))
shapes: (10,), (), (100,) shapes: (10,), (), (100,) shapes: (10,), (), (100,) shapes: (10,), (), (100,)
Giriş verilerini okuma
NumPy dizilerini tüketmek
Daha fazla örnek için NumPy dizilerini yükleme konusuna bakın.
Tüm giriş verileriniz belleğe sığıyorsa, bunlardan bir Dataset
oluşturmanın en basit yolu, onları tf.Tensor
nesnelerine dönüştürmek ve Dataset.from_tensor_slices()
kullanmaktır.
train, test = tf.keras.datasets.fashion_mnist.load_data()
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz 32768/29515 [=================================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz 26427392/26421880 [==============================] - 1s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz 8192/5148 [===============================================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz 4423680/4422102 [==============================] - 0s 0us/step
images, labels = train
images = images/255
dataset = tf.data.Dataset.from_tensor_slices((images, labels))
dataset
<TensorSliceDataset shapes: ((28, 28), ()), types: (tf.float64, tf.uint8)>
Python jeneratörlerini tüketmek
tf.data.Dataset
olarak kolayca alınabilen diğer bir yaygın veri kaynağı da python oluşturucudur.
def count(stop):
i = 0
while i<stop:
yield i
i += 1
for n in count(5):
print(n)
0 1 2 3 4
Dataset.from_generator
yapıcısı, python oluşturucuyu tamamen işlevsel birtf.data.Dataset
.
Yapıcı, bir yineleyici değil, giriş olarak çağrılabilir bir alır. Bu, sona ulaştığında jeneratörü yeniden başlatmasına izin verir. args
argümanlar olarak iletilen isteğe bağlı bir argüman argümanını alır.
output_types
için bağımsız değişkeni gereklidir tf.data
bir inşa tf.Graph
dahili ve grafik kenarları gerektirir tf.dtype
.
ds_counter = tf.data.Dataset.from_generator(count, args=[25], output_types=tf.int32, output_shapes = (), )
for count_batch in ds_counter.repeat().batch(10).take(10):
print(count_batch.numpy())
[0 1 2 3 4 5 6 7 8 9] [10 11 12 13 14 15 16 17 18 19] [20 21 22 23 24 0 1 2 3 4] [ 5 6 7 8 9 10 11 12 13 14] [15 16 17 18 19 20 21 22 23 24] [0 1 2 3 4 5 6 7 8 9] [10 11 12 13 14 15 16 17 18 19] [20 21 22 23 24 0 1 2 3 4] [ 5 6 7 8 9 10 11 12 13 14] [15 16 17 18 19 20 21 22 23 24]
output_shapes
argümanı gerekli değildir, ancak birçok tensorflow işlemi bilinmeyen dereceye sahip tensörleri desteklemediğinden şiddetle tavsiye edilir. Belirli bir eksenin uzunluğu bilinmiyorsa veya değişkense, bunu output_shapes
None
olarak output_shapes
.
Ayrıca output_shapes
ve output_types
output_shapes
diğer veri kümesi yöntemleriyle aynı iç içe geçme kurallarını izlediğine dikkat etmek önemlidir.
İşte her iki yönü de gösteren bir örnek oluşturucu, ikinci dizinin bilinmeyen uzunlukta bir vektör olduğu dizilerin demetlerini döndürür.
def gen_series():
i = 0
while True:
size = np.random.randint(0, 10)
yield i, np.random.normal(size=(size,))
i += 1
for i, series in gen_series():
print(i, ":", str(series))
if i > 5:
break
0 : [-1.8423 -0.1016 0.2763 0.815 0.0137 0.1228 0.0773] 1 : [ 0.4419 0.6819 -0.576 ] 2 : [-0.8961 -0.8613 -0.5917 0.7749 -0.2283 0.4406 -2.4833 0.1952 0.9962] 3 : [] 4 : [0.2609 0.854 2.96 ] 5 : [] 6 : [ 1.0899 -0.377 0.4295 -1.835 -0.4915 -0.0435 -0.6999 -0.9527]
İlk çıktı bir int32
, ikincisi ise float32
.
İlk öğe bir skaler, şekil ()
ve ikincisi, bilinmeyen uzunlukta bir vektördür (None,)
ds_series = tf.data.Dataset.from_generator(
gen_series,
output_types=(tf.int32, tf.float32),
output_shapes=((), (None,)))
ds_series
<FlatMapDataset shapes: ((), (None,)), types: (tf.int32, tf.float32)>
Artık normal birtf.data.Dataset
gibi kullanılabilir. Değişken şekilli bir veri kümesini toplu Dataset.padded_batch
kullanmanız Dataset.padded_batch
.
ds_series_batch = ds_series.shuffle(20).padded_batch(10)
ids, sequence_batch = next(iter(ds_series_batch))
print(ids.numpy())
print()
print(sequence_batch.numpy())
[12 0 21 20 19 2 13 6 16 15] [[ 0.6409 0. 0. 0. 0. 0. 0. 0. 0. ] [-0.3158 -1.1566 0.5766 0.2067 0.2566 -0.7567 0. 0. 0. ] [ 1.703 0. 0. 0. 0. 0. 0. 0. 0. ] [ 1.577 0. 0. 0. 0. 0. 0. 0. 0. ] [ 0. 0. 0. 0. 0. 0. 0. 0. 0. ] [-1.1427 1.779 1.5403 0.428 -0.0309 0.8038 -0.4779 0.3646 -0.3527] [-1.0069 0.6749 -1.4268 0.0887 0.4798 0.769 0.5454 0. 0. ] [-0.3393 0.5725 -0.8578 -3.5323 -0.9053 0.261 -1.7785 0.5377 -0.4388] [ 0.5343 1.609 -0.9407 1.1031 0.4216 0. 0. 0. 0. ] [ 1.1637 0.6195 1.6317 -0.759 -0.4261 -3.2933 1.9672 -0.2561 1.341 ]]
Daha gerçekçi bir örnek için preprocessing.image.ImageDataGenerator
tf.data.Dataset
olaraktf.data.Dataset
deneyin.
Önce verileri indirin:
flowers = tf.keras.utils.get_file(
'flower_photos',
'https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz',
untar=True)
Downloading data from https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz 228818944/228813984 [==============================] - 11s 0us/step
image.ImageDataGenerator
oluşturun
img_gen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255, rotation_range=20)
images, labels = next(img_gen.flow_from_directory(flowers))
Found 3670 images belonging to 5 classes.
print(images.dtype, images.shape)
print(labels.dtype, labels.shape)
float32 (32, 256, 256, 3) float32 (32, 5)
ds = tf.data.Dataset.from_generator(
lambda: img_gen.flow_from_directory(flowers),
output_types=(tf.float32, tf.float32),
output_shapes=([32,256,256,3], [32,5])
)
ds.element_spec
(TensorSpec(shape=(32, 256, 256, 3), dtype=tf.float32, name=None), TensorSpec(shape=(32, 5), dtype=tf.float32, name=None))
for images, label in ds.take(1):
print('images.shape: ', images.shape)
print('labels.shape: ', labels.shape)
Found 3670 images belonging to 5 classes. images.shape: (32, 256, 256, 3) labels.shape: (32, 5)
TFRecord verilerini tüketme
Uçtan uca bir örnek için TFRecords Yükleme bölümüne bakın.
tf.data
API, belleğe sığmayan büyük veri kümelerini işleyebilmeniz için çeşitli dosya biçimlerini destekler. Örneğin, TFRecord dosya biçimi, birçok TensorFlow uygulamasının eğitim verileri için kullandığı basit bir kayıt odaklı ikili biçimdir. tf.data.TFRecordDataset
sınıfı, bir giriş ardışık düzeninin parçası olarak bir veya daha fazla TFRecord dosyasının içeriği üzerinden akış yapmanızı sağlar.
Fransız Sokak Adı İşaretlerinden (FSNS) alınan test dosyasını kullanan bir örnek aşağıda verilmiştir.
# Creates a dataset that reads all of the examples from two files.
fsns_test_file = tf.keras.utils.get_file("fsns.tfrec", "https://storage.googleapis.com/download.tensorflow.org/data/fsns-20160927/testdata/fsns-00000-of-00001")
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/fsns-20160927/testdata/fsns-00000-of-00001 7905280/7904079 [==============================] - 0s 0us/step
TFRecordDataset
başlatıcısının filenames
bağımsız değişkeni bir dize, dizeler listesi veya dizelerin tf.Tensor
. Bu nedenle, eğitim ve doğrulama amacıyla iki dosya kümeniz varsa, veri kümesini üreten bir fabrika yöntemi oluşturabilirsiniz, dosya adlarını girdi bağımsız değişkeni olarak alabilirsiniz:
dataset = tf.data.TFRecordDataset(filenames = [fsns_test_file])
dataset
<TFRecordDatasetV2 shapes: (), types: tf.string>
Birçok TensorFlow projesi, TFRecord dosyalarında serileştirilmiş tf.train.Example
kayıtları kullanır. Bunların incelenmeden önce kodunun çözülmesi gerekir:
raw_example = next(iter(dataset))
parsed = tf.train.Example.FromString(raw_example.numpy())
parsed.features.feature['image/text']
bytes_list { value: "Rue Perreyon" }
Metin verilerini tüketmek
Uçtan uca bir örnek için Metin Yükleme konusuna bakın.
Birçok veri kümesi bir veya daha fazla metin dosyası olarak dağıtılır. tf.data.TextLineDataset
, bir veya daha fazla metin dosyasından satır ayıklamak için kolay bir yol sağlar. Bir veya daha fazla dosya adı verildiğinde, bir TextLineDataset
bu dosyaların her satırı için dize değerli bir öğe üretir.
directory_url = 'https://storage.googleapis.com/download.tensorflow.org/data/illiad/'
file_names = ['cowper.txt', 'derby.txt', 'butler.txt']
file_paths = [
tf.keras.utils.get_file(file_name, directory_url + file_name)
for file_name in file_names
]
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/illiad/cowper.txt 819200/815980 [==============================] - 0s 0us/step Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/illiad/derby.txt 811008/809730 [==============================] - 0s 0us/step Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/illiad/butler.txt 811008/807992 [==============================] - 0s 0us/step
dataset = tf.data.TextLineDataset(file_paths)
İşte ilk dosyanın ilk birkaç satırı:
for line in dataset.take(5):
print(line.numpy())
b"\xef\xbb\xbfAchilles sing, O Goddess! Peleus' son;" b'His wrath pernicious, who ten thousand woes' b"Caused to Achaia's host, sent many a soul" b'Illustrious into Ades premature,' b'And Heroes gave (so stood the will of Jove)'
Dosyalar arasında satırları değiştirmek için Dataset.interleave
kullanın. Bu, dosyaları birlikte karıştırmayı kolaylaştırır. İşte her çevirinin birinci, ikinci ve üçüncü satırları:
files_ds = tf.data.Dataset.from_tensor_slices(file_paths)
lines_ds = files_ds.interleave(tf.data.TextLineDataset, cycle_length=3)
for i, line in enumerate(lines_ds.take(9)):
if i % 3 == 0:
print()
print(line.numpy())
b"\xef\xbb\xbfAchilles sing, O Goddess! Peleus' son;" b"\xef\xbb\xbfOf Peleus' son, Achilles, sing, O Muse," b'\xef\xbb\xbfSing, O goddess, the anger of Achilles son of Peleus, that brought' b'His wrath pernicious, who ten thousand woes' b'The vengeance, deep and deadly; whence to Greece' b'countless ills upon the Achaeans. Many a brave soul did it send' b"Caused to Achaia's host, sent many a soul" b'Unnumbered ills arose; which many a soul' b'hurrying down to Hades, and many a hero did it yield a prey to dogs and'
Varsayılan olarak, bir TextLineDataset
her dosyanın her satırını verir; bu istenmeyebilir, örneğin, dosya bir başlık satırıyla başlıyorsa veya yorumlar içeriyorsa. Bu satırlar Dataset.skip()
veya Dataset.filter()
dönüşümleri kullanılarak kaldırılabilir. Burada, ilk satırı atlar, ardından yalnızca hayatta kalanları bulmak için filtre uygularsınız.
titanic_file = tf.keras.utils.get_file("train.csv", "https://storage.googleapis.com/tf-datasets/titanic/train.csv")
titanic_lines = tf.data.TextLineDataset(titanic_file)
Downloading data from https://storage.googleapis.com/tf-datasets/titanic/train.csv 32768/30874 [===============================] - 0s 0us/step
for line in titanic_lines.take(10):
print(line.numpy())
b'survived,sex,age,n_siblings_spouses,parch,fare,class,deck,embark_town,alone' b'0,male,22.0,1,0,7.25,Third,unknown,Southampton,n' b'1,female,38.0,1,0,71.2833,First,C,Cherbourg,n' b'1,female,26.0,0,0,7.925,Third,unknown,Southampton,y' b'1,female,35.0,1,0,53.1,First,C,Southampton,n' b'0,male,28.0,0,0,8.4583,Third,unknown,Queenstown,y' b'0,male,2.0,3,1,21.075,Third,unknown,Southampton,n' b'1,female,27.0,0,2,11.1333,Third,unknown,Southampton,n' b'1,female,14.0,1,0,30.0708,Second,unknown,Cherbourg,n' b'1,female,4.0,1,1,16.7,Third,G,Southampton,n'
def survived(line):
return tf.not_equal(tf.strings.substr(line, 0, 1), "0")
survivors = titanic_lines.skip(1).filter(survived)
for line in survivors.take(10):
print(line.numpy())
b'1,female,38.0,1,0,71.2833,First,C,Cherbourg,n' b'1,female,26.0,0,0,7.925,Third,unknown,Southampton,y' b'1,female,35.0,1,0,53.1,First,C,Southampton,n' b'1,female,27.0,0,2,11.1333,Third,unknown,Southampton,n' b'1,female,14.0,1,0,30.0708,Second,unknown,Cherbourg,n' b'1,female,4.0,1,1,16.7,Third,G,Southampton,n' b'1,male,28.0,0,0,13.0,Second,unknown,Southampton,y' b'1,female,28.0,0,0,7.225,Third,unknown,Cherbourg,y' b'1,male,28.0,0,0,35.5,First,A,Southampton,y' b'1,female,38.0,1,5,31.3875,Third,unknown,Southampton,n'
CSV verilerini tüketme
Daha fazla örnek için bkz. CSV Dosyalarını Yükleme ve Pandas Veri Çerçevelerini Yükleme .
CSV dosya formatı, tablo şeklindeki verileri düz metin olarak depolamak için popüler bir formattır.
Örneğin:
titanic_file = tf.keras.utils.get_file("train.csv", "https://storage.googleapis.com/tf-datasets/titanic/train.csv")
df = pd.read_csv(titanic_file)
df.head()
Verileriniz belleğe Dataset.from_tensor_slices
, aynı Dataset.from_tensor_slices
yöntemi sözlükler üzerinde çalışır ve bu verilerin kolayca içe aktarılmasına izin verir:
titanic_slices = tf.data.Dataset.from_tensor_slices(dict(df))
for feature_batch in titanic_slices.take(1):
for key, value in feature_batch.items():
print(" {!r:20s}: {}".format(key, value))
'survived' : 0 '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'
Daha ölçeklenebilir bir yaklaşım, gerektiğinde diskten yüklemektir.
tf.data
modülü, RFC 4180 ile uyumlu bir veya daha fazla CSV dosyasından kayıtları ayıklamak için yöntemler sağlar.
experimental.make_csv_dataset
işlevi, csv dosya kümelerini okumak için yüksek düzeyli bir arabirimdir. Kullanımı basitleştirmek için sütun türü çıkarımını ve yığınlama ve karıştırma gibi diğer birçok özelliği destekler.
titanic_batches = tf.data.experimental.make_csv_dataset(
titanic_file, batch_size=4,
label_name="survived")
for feature_batch, label_batch in titanic_batches.take(1):
print("'survived': {}".format(label_batch))
print("features:")
for key, value in feature_batch.items():
print(" {!r:20s}: {}".format(key, value))
'survived': [0 0 0 1] features: 'sex' : [b'male' b'male' b'male' b'female'] 'age' : [11. 16. 28. 19.] 'n_siblings_spouses': [5 4 0 0] 'parch' : [2 1 0 2] 'fare' : [46.9 39.6875 7.75 26.2833] 'class' : [b'Third' b'Third' b'Third' b'First'] 'deck' : [b'unknown' b'unknown' b'unknown' b'D'] 'embark_town' : [b'Southampton' b'Southampton' b'Queenstown' b'Southampton'] 'alone' : [b'n' b'n' b'y' b'n']
Yalnızca bir sütun alt kümesine ihtiyacınız varsa, select_columns
bağımsız değişkenini kullanabilirsiniz.
titanic_batches = tf.data.experimental.make_csv_dataset(
titanic_file, batch_size=4,
label_name="survived", select_columns=['class', 'fare', 'survived'])
for feature_batch, label_batch in titanic_batches.take(1):
print("'survived': {}".format(label_batch))
for key, value in feature_batch.items():
print(" {!r:20s}: {}".format(key, value))
'survived': [0 1 1 0] 'fare' : [ 0. 12.2875 30. 7.75 ] 'class' : [b'Second' b'Third' b'First' b'Third']
Daha ince taneli kontrol sağlayan daha düşük seviyeli bir experimental.CsvDataset
sınıfı da vardır. Sütun türü çıkarımını desteklemez. Bunun yerine, her bir sütunun türünü belirtmelisiniz.
titanic_types = [tf.int32, tf.string, tf.float32, tf.int32, tf.int32, tf.float32, tf.string, tf.string, tf.string, tf.string]
dataset = tf.data.experimental.CsvDataset(titanic_file, titanic_types , header=True)
for line in dataset.take(10):
print([item.numpy() for item in line])
[0, b'male', 22.0, 1, 0, 7.25, b'Third', b'unknown', b'Southampton', b'n'] [1, b'female', 38.0, 1, 0, 71.2833, b'First', b'C', b'Cherbourg', b'n'] [1, b'female', 26.0, 0, 0, 7.925, b'Third', b'unknown', b'Southampton', b'y'] [1, b'female', 35.0, 1, 0, 53.1, b'First', b'C', b'Southampton', b'n'] [0, b'male', 28.0, 0, 0, 8.4583, b'Third', b'unknown', b'Queenstown', b'y'] [0, b'male', 2.0, 3, 1, 21.075, b'Third', b'unknown', b'Southampton', b'n'] [1, b'female', 27.0, 0, 2, 11.1333, b'Third', b'unknown', b'Southampton', b'n'] [1, b'female', 14.0, 1, 0, 30.0708, b'Second', b'unknown', b'Cherbourg', b'n'] [1, b'female', 4.0, 1, 1, 16.7, b'Third', b'G', b'Southampton', b'n'] [0, b'male', 20.0, 0, 0, 8.05, b'Third', b'unknown', b'Southampton', b'y']
Bazı sütunlar boşsa, bu düşük düzeyli arabirim sütun türleri yerine varsayılan değerler sağlamanıza olanak tanır.
%%writefile missing.csv
1,2,3,4
,2,3,4
1,,3,4
1,2,,4
1,2,3,
,,,
Writing missing.csv
# Creates a dataset that reads all of the records from two CSV files, each with
# four float columns which may have missing values.
record_defaults = [999,999,999,999]
dataset = tf.data.experimental.CsvDataset("missing.csv", record_defaults)
dataset = dataset.map(lambda *items: tf.stack(items))
dataset
<MapDataset shapes: (4,), types: tf.int32>
for line in dataset:
print(line.numpy())
[1 2 3 4] [999 2 3 4] [ 1 999 3 4] [ 1 2 999 4] [ 1 2 3 999] [999 999 999 999]
Varsayılan olarak, bir CsvDataset
dosyanın her satırının her sütununu verir ve bu istenmeyebilir, örneğin dosya yok sayılması gereken bir başlık satırıyla başlıyorsa veya girdide bazı sütunlar gerekli değilse. Bu satırlar ve alanlar sırasıyla header
ve select_cols
argümanları ile kaldırılabilir.
# Creates a dataset that reads all of the records from two CSV files with
# headers, extracting float data from columns 2 and 4.
record_defaults = [999, 999] # Only provide defaults for the selected columns
dataset = tf.data.experimental.CsvDataset("missing.csv", record_defaults, select_cols=[1, 3])
dataset = dataset.map(lambda *items: tf.stack(items))
dataset
<MapDataset shapes: (2,), types: tf.int32>
for line in dataset:
print(line.numpy())
[2 4] [2 4] [999 4] [2 4] [ 2 999] [999 999]
Dosya setleri tüketmek
Her dosyanın bir örnek olduğu bir dizi dosya olarak dağıtılmış birçok veri kümesi vardır.
flowers_root = tf.keras.utils.get_file(
'flower_photos',
'https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz',
untar=True)
flowers_root = pathlib.Path(flowers_root)
Kök dizin, her sınıf için bir dizin içerir:
for item in flowers_root.glob("*"):
print(item.name)
sunflowers daisy LICENSE.txt roses tulips dandelion
Her bir sınıf dizinindeki dosyalar örnektir:
list_ds = tf.data.Dataset.list_files(str(flowers_root/'*/*'))
for f in list_ds.take(5):
print(f.numpy())
b'/home/kbuilder/.keras/datasets/flower_photos/sunflowers/4868595281_1e58083785.jpg' b'/home/kbuilder/.keras/datasets/flower_photos/daisy/5883162120_dc7274af76_n.jpg' b'/home/kbuilder/.keras/datasets/flower_photos/tulips/12883412424_cb5086b43f_n.jpg' b'/home/kbuilder/.keras/datasets/flower_photos/roses/13264214185_d6aa79b3bd.jpg' b'/home/kbuilder/.keras/datasets/flower_photos/roses/6690926183_afedba9f15_n.jpg'
tf.io.read_file
işlevini kullanarak verileri okuyun ve etiketi yoldantf.io.read_file
(image, label)
çiftleri döndürür:
def process_path(file_path):
label = tf.strings.split(file_path, os.sep)[-2]
return tf.io.read_file(file_path), label
labeled_ds = list_ds.map(process_path)
for image_raw, label_text in labeled_ds.take(1):
print(repr(image_raw.numpy()[:100]))
print()
print(label_text.numpy())
b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xfe\x00\x0cAppleMark\n\xff\xe2\x05(ICC_PROFILE\x00\x01\x01\x00\x00\x05\x18appl\x02 \x00\x00scnrRGB XYZ \x07\xd3\x00\x07\x00\x01\x00\x00\x00\x00\x00\x00acspAPPL\x00\x00\x00\x00' b'sunflowers'
Veri kümesi öğelerini gruplama
Basit gruplama
En basit gruplama biçimi, bir veri kümesinin n
ardışık öğesini tek bir öğede yığınlar. Dataset.batch()
dönüşümü, öğelerin her bileşenine uygulanan tf.stack()
operatörü ile aynı kısıtlamalarla tam olarak bunu yapar: yani, her i bileşeni için, tüm öğeler tam olarak aynı şekle sahip bir tensöre sahip olmalıdır.
inc_dataset = tf.data.Dataset.range(100)
dec_dataset = tf.data.Dataset.range(0, -100, -1)
dataset = tf.data.Dataset.zip((inc_dataset, dec_dataset))
batched_dataset = dataset.batch(4)
for batch in batched_dataset.take(4):
print([arr.numpy() for arr in batch])
[array([0, 1, 2, 3]), array([ 0, -1, -2, -3])] [array([4, 5, 6, 7]), array([-4, -5, -6, -7])] [array([ 8, 9, 10, 11]), array([ -8, -9, -10, -11])] [array([12, 13, 14, 15]), array([-12, -13, -14, -15])]
tf.data
şekil bilgilerini tf.data
çalışırken, Dataset.batch
varsayılan ayarları, son toplu iş dolu olmayabileceğinden bilinmeyen bir yığın boyutuyla sonuçlanır. Şekildeki None
edin:
batched_dataset
<BatchDataset shapes: ((None,), (None,)), types: (tf.int64, tf.int64)>
Son kümeyi yok saymak ve tam şekil yayılımı elde etmek için drop_remainder
bağımsız değişkenini kullanın:
batched_dataset = dataset.batch(7, drop_remainder=True)
batched_dataset
<BatchDataset shapes: ((7,), (7,)), types: (tf.int64, tf.int64)>
Dolgulu harmanlama tensörleri
Yukarıdaki tarif, hepsi aynı boyutta olan tensörler için işe yarar. Bununla birlikte, birçok model (örneğin, dizi modelleri) değişen boyutlara sahip olabilen girdi verileriyle çalışır (örneğin, farklı uzunluktaki diziler). Bu durumu ele almak için, Dataset.padded_batch
dönüşümü, içinde doldurulabilecekleri bir veya daha fazla boyut belirleyerek farklı şekildeki tensörleri Dataset.padded_batch
olanak tanır.
dataset = tf.data.Dataset.range(100)
dataset = dataset.map(lambda x: tf.fill([tf.cast(x, tf.int32)], x))
dataset = dataset.padded_batch(4, padded_shapes=(None,))
for batch in dataset.take(2):
print(batch.numpy())
print()
[[0 0 0] [1 0 0] [2 2 0] [3 3 3]] [[4 4 4 4 0 0 0] [5 5 5 5 5 0 0] [6 6 6 6 6 6 0] [7 7 7 7 7 7 7]]
Dataset.padded_batch
dönüşümü, her bileşenin her bir boyutu için farklı dolgu ayarlamanıza olanak tanır ve değişken uzunlukta (yukarıdaki örnekte None
ile belirtilir) veya sabit uzunlukta olabilir. Varsayılan olarak 0 olan doldurma değerini geçersiz kılmak da mümkündür.
Eğitim iş akışları
Birden çok dönemi işleme
tf.data
API, aynı verilerin birden çok dönemini işlemek için iki ana yol sunar.
Bir veri kümesi üzerinde birden çok çağda yineleme yapmanın en basit yolu, Dataset.repeat()
dönüşümünü kullanmaktır. İlk olarak, titanik verilerden bir veri kümesi oluşturun:
titanic_file = tf.keras.utils.get_file("train.csv", "https://storage.googleapis.com/tf-datasets/titanic/train.csv")
titanic_lines = tf.data.TextLineDataset(titanic_file)
def plot_batch_sizes(ds):
batch_sizes = [batch.shape[0] for batch in ds]
plt.bar(range(len(batch_sizes)), batch_sizes)
plt.xlabel('Batch number')
plt.ylabel('Batch size')
Dataset.repeat()
dönüşümünün bağımsız değişken olmadan uygulanması, girdiyi süresiz olarak tekrar eder.
Dataset.repeat
dönüşümü, bir dönemin sonunu ve sonraki dönemin başlangıcını bildirmeden bağımsız değişkenlerini birleştirir. Bu nedenle bir Dataset.batch
sonra uygulanır Dataset.repeat
toplu verecektir Üstüne binilir dönem sınırları olun:
titanic_batches = titanic_lines.repeat(3).batch(128)
plot_batch_sizes(titanic_batches)
Net bir dönem ayrımına ihtiyacınız varsa, Dataset.batch
önce Dataset.batch
koyun:
titanic_batches = titanic_lines.batch(128).repeat(3)
plot_batch_sizes(titanic_batches)
Her dönemin sonunda özel bir hesaplama (örneğin, istatistik toplamak için) gerçekleştirmek isterseniz, en basit yöntem, her çağda veri kümesi yinelemesini yeniden başlatmaktır:
epochs = 3
dataset = titanic_lines.batch(128)
for epoch in range(epochs):
for batch in dataset:
print(batch.shape)
print("End of epoch: ", epoch)
(128,) (128,) (128,) (128,) (116,) End of epoch: 0 (128,) (128,) (128,) (128,) (116,) End of epoch: 1 (128,) (128,) (128,) (128,) (116,) End of epoch: 2
Girdi verilerini rastgele karıştırmak
Dataset.shuffle()
dönüşümü, sabit boyutlu bir arabelleği korur ve sonraki öğeyi bu arabellekten rastgele rastgele olarak seçer.
Etkisini görebilmek için veri kümesine bir dizin ekleyin:
lines = tf.data.TextLineDataset(titanic_file)
counter = tf.data.experimental.Counter()
dataset = tf.data.Dataset.zip((counter, lines))
dataset = dataset.shuffle(buffer_size=100)
dataset = dataset.batch(20)
dataset
<BatchDataset shapes: ((None,), (None,)), types: (tf.int64, tf.string)>
buffer_size
100 olduğundan ve toplu iş boyutu 20 olduğundan, ilk grup 120'den büyük indeksi olan hiçbir öğe içermez.
n,line_batch = next(iter(dataset))
print(n.numpy())
[ 90 75 39 84 102 5 98 101 51 72 54 33 104 59 110 29 92 50 36 103]
Olduğu gibi Dataset.batch
göre sipariş Dataset.repeat
konularda.
Dataset.shuffle
, karıştırma arabelleği boşalana kadar bir dönemin sonunu Dataset.shuffle
. Dolayısıyla, bir tekrardan önce yerleştirilen bir karıştırma, bir dönemin her öğesini bir sonrakine geçmeden önce gösterir:
dataset = tf.data.Dataset.zip((counter, lines))
shuffled = dataset.shuffle(buffer_size=100).batch(10).repeat(2)
print("Here are the item ID's near the epoch boundary:\n")
for n, line_batch in shuffled.skip(60).take(5):
print(n.numpy())
Here are the item ID's near the epoch boundary: [550 618 614 435 556 530 578 451 590 604] [464 453 610 412 282 596 601 612 584 606] [368 469 575 607 586 537 444 300] [ 15 98 65 26 40 39 101 54 32 10] [ 8 102 68 108 12 96 2 87 80 37]
shuffle_repeat = [n.numpy().mean() for n, line_batch in shuffled]
plt.plot(shuffle_repeat, label="shuffle().repeat()")
plt.ylabel("Mean item ID")
plt.legend()
<matplotlib.legend.Legend at 0x7f3f083eebe0>
Ancak bir karıştırma işleminden önce bir tekrar, çağın sınırlarını birbirine karıştırır:
dataset = tf.data.Dataset.zip((counter, lines))
shuffled = dataset.repeat(2).shuffle(buffer_size=100).batch(10)
print("Here are the item ID's near the epoch boundary:\n")
for n, line_batch in shuffled.skip(55).take(15):
print(n.numpy())
Here are the item ID's near the epoch boundary: [576 618 527 9 602 612 21 574 504 622] [623 26 32 616 626 482 617 598 0 614] [476 1 473 14 10 267 29 31 43 48] [588 13 470 467 12 596 619 46 28 528] [609 2 52 542 607 23 35 38 620 523] [509 477 571 15 56 74 565 525 58 19] [359 40 22 627 317 54 526 16 562 33] [ 67 500 584 531 49 86 51 81 78 583] [ 24 557 452 47 124 485 610 45 27 17] [379 66 85 91 599 97 499 112 108 11] [ 39 164 101 96 543 64 109 564 82 18] [533 120 30 63 115 88 95 75 133 34] [ 92 65 102 132 76 119 131 475 572 50] [ 94 145 144 603 152 505 621 140 448 122] [ 70 159 146 84 71 160 42 72 41 139]
repeat_shuffle = [n.numpy().mean() for n, line_batch in shuffled]
plt.plot(shuffle_repeat, label="shuffle().repeat()")
plt.plot(repeat_shuffle, label="repeat().shuffle()")
plt.ylabel("Mean item ID")
plt.legend()
<matplotlib.legend.Legend at 0x7f3f0838c860>
Ön işleme verileri
Dataset.map(f)
dönüşümü, girdi veri kümesinin her bir öğesine belirli bir f
işlevini uygulayarak yeni bir veri kümesi üretir. İşlevsel programlama dillerinde listelere (ve diğer yapılara) yaygın olarak uygulanan map()
işlevine dayanmaktadır. f
işlevi, tf.Tensor
tek bir öğeyi temsil eden tf.Tensor
nesnelerini alır ve yeni veri kümesindeki tek bir öğeyi temsil edecek tf.Tensor
nesnelerini döndürür. Uygulaması, bir öğeyi diğerine dönüştürmek için standart TensorFlow işlemlerini kullanır.
Bu bölüm, Dataset.map()
nin nasıl kullanılacağına Dataset.map()
yaygın örnekleri kapsar.
Görüntü verilerinin kodunu çözme ve yeniden boyutlandırma
Bir sinir ağını gerçek dünyadaki görüntü verileri üzerinde eğitirken, genellikle farklı boyutlardaki görüntüleri ortak bir boyuta dönüştürmek gerekir, böylece sabit bir boyuta toplu hale getirilebilirler.
Çiçek dosya adları veri kümesini yeniden oluşturun:
list_ds = tf.data.Dataset.list_files(str(flowers_root/'*/*'))
Veri kümesi öğelerini işleyen bir işlev yazın.
# Reads an image from a file, decodes it into a dense tensor, and resizes it
# to a fixed shape.
def parse_image(filename):
parts = tf.strings.split(filename, os.sep)
label = parts[-2]
image = tf.io.read_file(filename)
image = tf.image.decode_jpeg(image)
image = tf.image.convert_image_dtype(image, tf.float32)
image = tf.image.resize(image, [128, 128])
return image, label
Çalıştığını test edin.
file_path = next(iter(list_ds))
image, label = parse_image(file_path)
def show(image, label):
plt.figure()
plt.imshow(image)
plt.title(label.numpy().decode('utf-8'))
plt.axis('off')
show(image, label)
Veri kümesi üzerinde eşleyin.
images_ds = list_ds.map(parse_image)
for image, label in images_ds.take(2):
show(image, label)
Keyfi Python mantığını uygulama
Performans nedenleriyle, verilerinizi mümkün olduğunca önişlemek için TensorFlow işlemlerini kullanın. Ancak, bazen girdi verilerinizi ayrıştırırken harici Python kitaplıklarını çağırmak yararlı olabilir. Dataset.map()
dönüşümünde tf.py_function()
işlemini kullanabilirsiniz.
Örneğin, rastgele bir döndürme uygulamak istiyorsanız, tf.image
modülünde yalnızca tf.image.rot90
ve bu, görüntü büyütme için pek kullanışlı değildir.
Göstermek için tf.py_function
, kullanmayı deneyin scipy.ndimage.rotate
yerine işlevi:
import scipy.ndimage as ndimage
def random_rotate_image(image):
image = ndimage.rotate(image, np.random.uniform(-30, 30), reshape=False)
return image
image, label = next(iter(images_ds))
image = random_rotate_image(image)
show(image, label)
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Bu fonksiyonu kullanmak için Dataset.map
aynı uyarılar olduğu gibi uygulamak Dataset.from_generator
, size işlevini uyguladığınızda dönüş şekil ve türlerini tanımlamak gerekir:
def tf_random_rotate_image(image, label):
im_shape = image.shape
[image,] = tf.py_function(random_rotate_image, [image], [tf.float32])
image.set_shape(im_shape)
return image, label
rot_ds = images_ds.map(tf_random_rotate_image)
for image, label in rot_ds.take(2):
show(image, label)
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers). Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
tf.Example
ayrıştırma. tf.Example
protokol tampon mesajları
Birçok girdi ardışık tf.train.Example
protokol arabellek mesajlarını bir TFRecord formatından çıkarır. Her tf.train.Example
kaydı bir veya daha fazla "özellik" içerir ve giriş ardışık tf.train.Example
tipik olarak bu özellikleri tensörlere dönüştürür.
fsns_test_file = tf.keras.utils.get_file("fsns.tfrec", "https://storage.googleapis.com/download.tensorflow.org/data/fsns-20160927/testdata/fsns-00000-of-00001")
dataset = tf.data.TFRecordDataset(filenames = [fsns_test_file])
dataset
<TFRecordDatasetV2 shapes: (), types: tf.string>
Sen çalışabilirsiniz tf.train.Example
a protos dışarıdantf.data.Dataset
verileri anlamak:
raw_example = next(iter(dataset))
parsed = tf.train.Example.FromString(raw_example.numpy())
feature = parsed.features.feature
raw_img = feature['image/encoded'].bytes_list.value[0]
img = tf.image.decode_png(raw_img)
plt.imshow(img)
plt.axis('off')
_ = plt.title(feature["image/text"].bytes_list.value[0])
raw_example = next(iter(dataset))
def tf_parse(eg):
example = tf.io.parse_example(
eg[tf.newaxis], {
'image/encoded': tf.io.FixedLenFeature(shape=(), dtype=tf.string),
'image/text': tf.io.FixedLenFeature(shape=(), dtype=tf.string)
})
return example['image/encoded'][0], example['image/text'][0]
img, txt = tf_parse(raw_example)
print(txt.numpy())
print(repr(img.numpy()[:20]), "...")
b'Rue Perreyon' b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x02X' ...
decoded = dataset.map(tf_parse)
decoded
<MapDataset shapes: ((), ()), types: (tf.string, tf.string)>
image_batch, text_batch = next(iter(decoded.batch(10)))
image_batch.shape
TensorShape([10])
Zaman serisi pencereleme
Uçtan uca zaman serisi örneği için bkz: Zaman serisi tahmini .
Zaman serisi verileri genellikle zaman ekseni bozulmadan düzenlenir.
Dataset.range
için basit bir Dataset.range
kullanın:
range_ds = tf.data.Dataset.range(100000)
Tipik olarak, bu tür verilere dayalı modeller bitişik bir zaman dilimi isteyecektir.
En basit yaklaşım, verileri gruplamak olacaktır:
batch
kullanma
batches = range_ds.batch(10, drop_remainder=True)
for batch in batches.take(5):
print(batch.numpy())
[0 1 2 3 4 5 6 7 8 9] [10 11 12 13 14 15 16 17 18 19] [20 21 22 23 24 25 26 27 28 29] [30 31 32 33 34 35 36 37 38 39] [40 41 42 43 44 45 46 47 48 49]
Ya da geleceğe doğru bir adım ileride yoğun tahminlerde bulunmak için, özellikleri ve etiketleri birbirine göre bir adım kaydırabilirsiniz:
def dense_1_step(batch):
# Shift features and labels one step relative to each other.
return batch[:-1], batch[1:]
predict_dense_1_step = batches.map(dense_1_step)
for features, label in predict_dense_1_step.take(3):
print(features.numpy(), " => ", label.numpy())
[0 1 2 3 4 5 6 7 8] => [1 2 3 4 5 6 7 8 9] [10 11 12 13 14 15 16 17 18] => [11 12 13 14 15 16 17 18 19] [20 21 22 23 24 25 26 27 28] => [21 22 23 24 25 26 27 28 29]
Sabit bir ofset yerine tüm bir pencereyi tahmin etmek için grupları iki bölüme ayırabilirsiniz:
batches = range_ds.batch(15, drop_remainder=True)
def label_next_5_steps(batch):
return (batch[:-5], # Take the first 5 steps
batch[-5:]) # take the remainder
predict_5_steps = batches.map(label_next_5_steps)
for features, label in predict_5_steps.take(3):
print(features.numpy(), " => ", label.numpy())
[0 1 2 3 4 5 6 7 8 9] => [10 11 12 13 14] [15 16 17 18 19 20 21 22 23 24] => [25 26 27 28 29] [30 31 32 33 34 35 36 37 38 39] => [40 41 42 43 44]
Bir grubun özellikleri ile diğerinin etiketleri arasında bir miktar örtüşmeye izin vermek için Dataset.zip
kullanın:
feature_length = 10
label_length = 3
features = range_ds.batch(feature_length, drop_remainder=True)
labels = range_ds.batch(feature_length).skip(1).map(lambda labels: labels[:label_length])
predicted_steps = tf.data.Dataset.zip((features, labels))
for features, label in predicted_steps.take(5):
print(features.numpy(), " => ", label.numpy())
[0 1 2 3 4 5 6 7 8 9] => [10 11 12] [10 11 12 13 14 15 16 17 18 19] => [20 21 22] [20 21 22 23 24 25 26 27 28 29] => [30 31 32] [30 31 32 33 34 35 36 37 38 39] => [40 41 42] [40 41 42 43 44 45 46 47 48 49] => [50 51 52]
window
kullanarak
Dataset.batch
kullanılırken daha hassas kontrole ihtiyaç duyabileceğiniz durumlar vardır. Dataset.window
yöntemi size tam kontrol sağlar, ancak biraz özen gerektirir: bir Dataset
Datasets
Dataset
döndürür. Ayrıntılar için Veri kümesi yapısına bakın.
window_size = 5
windows = range_ds.window(window_size, shift=1)
for sub_ds in windows.take(5):
print(sub_ds)
<_VariantDataset shapes: (), types: tf.int64> <_VariantDataset shapes: (), types: tf.int64> <_VariantDataset shapes: (), types: tf.int64> <_VariantDataset shapes: (), types: tf.int64> <_VariantDataset shapes: (), types: tf.int64>
Dataset.flat_map
yöntemi, veri kümelerinden oluşan bir veri kümesini alabilir ve bunu tek bir veri kümesinde düzleştirebilir:
for x in windows.flat_map(lambda x: x).take(30):
print(x.numpy(), end=' ')
0 1 2 3 4 1 2 3 4 5 2 3 4 5 6 3 4 5 6 7 4 5 6 7 8 5 6 7 8 9
Neredeyse tüm durumlarda, önce veri kümesini .batch
isteyeceksiniz:
def sub_to_batch(sub):
return sub.batch(window_size, drop_remainder=True)
for example in windows.flat_map(sub_to_batch).take(5):
print(example.numpy())
[0 1 2 3 4] [1 2 3 4 5] [2 3 4 5 6] [3 4 5 6 7] [4 5 6 7 8]
Şimdi, shift
argümanının her pencerenin ne kadar hareket edeceğini kontrol ettiğini görebilirsiniz.
Bunu bir araya getirerek şu işlevi yazabilirsiniz:
def make_window_dataset(ds, window_size=5, shift=1, stride=1):
windows = ds.window(window_size, shift=shift, stride=stride)
def sub_to_batch(sub):
return sub.batch(window_size, drop_remainder=True)
windows = windows.flat_map(sub_to_batch)
return windows
ds = make_window_dataset(range_ds, window_size=10, shift = 5, stride=3)
for example in ds.take(10):
print(example.numpy())
[ 0 3 6 9 12 15 18 21 24 27] [ 5 8 11 14 17 20 23 26 29 32] [10 13 16 19 22 25 28 31 34 37] [15 18 21 24 27 30 33 36 39 42] [20 23 26 29 32 35 38 41 44 47] [25 28 31 34 37 40 43 46 49 52] [30 33 36 39 42 45 48 51 54 57] [35 38 41 44 47 50 53 56 59 62] [40 43 46 49 52 55 58 61 64 67] [45 48 51 54 57 60 63 66 69 72]
Ardından, daha önce olduğu gibi etiketleri çıkarmak kolaydır:
dense_labels_ds = ds.map(dense_1_step)
for inputs,labels in dense_labels_ds.take(3):
print(inputs.numpy(), "=>", labels.numpy())
[ 0 3 6 9 12 15 18 21 24] => [ 3 6 9 12 15 18 21 24 27] [ 5 8 11 14 17 20 23 26 29] => [ 8 11 14 17 20 23 26 29 32] [10 13 16 19 22 25 28 31 34] => [13 16 19 22 25 28 31 34 37]
Yeniden örnekleme
Sınıf açısından oldukça dengesiz bir veri kümesiyle çalışırken, veri kümesini yeniden örneklemek isteyebilirsiniz. tf.data
bunu yapmak için iki yöntem sağlar. Kredi kartı dolandırıcılığı veri kümesi, bu tür bir soruna iyi bir örnektir.
zip_path = tf.keras.utils.get_file(
origin='https://storage.googleapis.com/download.tensorflow.org/data/creditcard.zip',
fname='creditcard.zip',
extract=True)
csv_path = zip_path.replace('.zip', '.csv')
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/creditcard.zip 69156864/69155632 [==============================] - 3s 0us/step
creditcard_ds = tf.data.experimental.make_csv_dataset(
csv_path, batch_size=1024, label_name="Class",
# Set the column types: 30 floats and an int.
column_defaults=[float()]*30+[int()])
Şimdi, sınıfların dağılımını kontrol edin, oldukça çarpık:
def count(counts, batch):
features, labels = batch
class_1 = labels == 1
class_1 = tf.cast(class_1, tf.int32)
class_0 = labels == 0
class_0 = tf.cast(class_0, tf.int32)
counts['class_0'] += tf.reduce_sum(class_0)
counts['class_1'] += tf.reduce_sum(class_1)
return counts
counts = creditcard_ds.take(10).reduce(
initial_state={'class_0': 0, 'class_1': 0},
reduce_func = count)
counts = np.array([counts['class_0'].numpy(),
counts['class_1'].numpy()]).astype(np.float32)
fractions = counts/counts.sum()
print(fractions)
[0.9952 0.0048]
Dengesiz bir veri kümesiyle eğitime yönelik yaygın bir yaklaşım, onu dengelemektir. tf.data
, bu iş akışını etkinleştiren birkaç yöntem içerir:
Veri kümeleri örnekleme
Bir veri kümesini yeniden örneklemeye yönelik bir yaklaşım, sample_from_datasets
kullanmaktır. Bu, her sınıf için ayrı birdata.Dataset
sahip olduğunuzda daha uygulanabilirdir.
Burada, kredi kartı dolandırıcılık verilerinden oluşturmak için filtreyi kullanın:
negative_ds = (
creditcard_ds
.unbatch()
.filter(lambda features, label: label==0)
.repeat())
positive_ds = (
creditcard_ds
.unbatch()
.filter(lambda features, label: label==1)
.repeat())
for features, label in positive_ds.batch(10).take(1):
print(label.numpy())
[1 1 1 1 1 1 1 1 1 1]
tf.data.experimental.sample_from_datasets
kullanmak için veri kümelerini ve her birinin ağırlığını tf.data.experimental.sample_from_datasets
:
balanced_ds = tf.data.experimental.sample_from_datasets(
[negative_ds, positive_ds], [0.5, 0.5]).batch(10)
Artık veri kümesi, her bir sınıfın örneklerini 50/50 olasılıkla üretir:
for features, labels in balanced_ds.take(10):
print(labels.numpy())
[1 0 1 0 1 1 0 0 1 0] [0 0 1 1 1 1 0 0 1 1] [1 1 0 1 1 0 1 1 0 0] [1 0 1 1 0 0 0 0 0 1] [1 1 0 1 1 0 0 0 1 0] [1 0 1 1 1 0 0 0 1 1] [0 1 1 0 0 0 1 0 1 0] [0 1 1 1 1 0 1 1 1 0] [0 0 1 1 1 1 0 0 1 1] [0 0 0 0 1 0 0 1 0 0]
Reddetme yeniden örnekleme
Yukarıdaki experimental.sample_from_datasets
yaklaşımıyla ilgili bir sorun, sınıf başına ayrı birtf.data.Dataset
gerektirmesidir. Dataset.filter
kullanmak çalışır, ancak tüm verilerin iki kez yüklenmesine neden olur.
data.experimental.rejection_resample
işlevi, bir veri kümesini yalnızca bir kez yüklerken yeniden dengelemek için uygulanabilir. Dengeyi sağlamak için veri kümesinden öğeler çıkarılacaktır.
data.experimental.rejection_resample
bir class_func
bağımsız değişkeni alır. Bu class_func
, her veri kümesi öğesine uygulanır ve dengeleme amacıyla bir örneğin hangi sınıfa ait olduğunu belirlemek için kullanılır.
creditcard_ds
öğeleri zaten (features, label)
çiftleridir. Dolayısıyla, class_func
yalnızca bu etiketleri döndürmelidir:
def class_func(features, label):
return label
Yeniden örnekleyicinin ayrıca bir hedef dağıtıma ve isteğe bağlı olarak bir ilk dağıtım tahminine ihtiyacı vardır:
resampler = tf.data.experimental.rejection_resample(
class_func, target_dist=[0.5, 0.5], initial_dist=fractions)
Yeniden örnekleyici, ayrı örneklerle ilgilenir, bu nedenle yeniden örnekleyiciyi uygulamadan önce veri kümesini unbatch
gerekir:
resample_ds = creditcard_ds.unbatch().apply(resampler).batch(10)
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/data/experimental/ops/resampling.py:156: Print (from tensorflow.python.ops.logging_ops) is deprecated and will be removed after 2018-08-20. Instructions for updating: Use tf.print instead of tf.Print. Note that tf.print returns a no-output operator that directly prints the output. Outside of defuns or eager mode, this operator will not be executed unless it is directly specified in session.run or used as a control dependency for other operators. This is only a concern in graph mode. Below is an example of how to ensure tf.print executes in graph mode:
Yeniden örnekleyici, class_func
çıktısından (class, example)
çiftler oluşturur. Bu durumda, example
bir zaten (feature, label)
kullanımı çifti, bu yüzden map
etiketlerin fazladan bir kopyasını düşmesi:
balanced_ds = resample_ds.map(lambda extra_label, features_and_label: features_and_label)
Artık veri kümesi, her sınıfın örneklerini 50/50 olasılıkla üretir:
for features, labels in balanced_ds.take(10):
print(labels.numpy())
[0 1 0 1 1 1 0 1 1 1] [0 1 1 1 1 0 1 0 0 1] [1 0 1 1 0 1 0 1 1 1] [1 0 0 1 1 0 0 0 1 0] [1 1 1 1 1 0 0 0 1 0] [0 0 0 0 1 0 1 1 0 1] [0 1 0 1 1 1 0 1 1 0] [1 0 0 0 0 1 0 1 0 0] [0 1 1 1 0 1 1 1 1 0] [0 1 1 1 1 0 1 1 1 0]
Yineleyici Kontrol İşaretleme
Tensorflow, eğitim süreciniz yeniden başladığında ilerlemesinin çoğunu kurtarmak için en son kontrol noktasını geri yükleyebilmesi için kontrol noktaları almayı destekler. Model değişkenlerini kontrol etmeye ek olarak, veri kümesi yineleyicisinin ilerlemesini de kontrol edebilirsiniz. Büyük bir veri kümeniz varsa ve veri kümesini her yeniden başlatmada baştan başlatmak istemiyorsanız bu yararlı olabilir. Ancak, shuffle
ve prefetch
gibi dönüşümler yineleyici içinde arabelleğe alma öğeleri gerektirdiğinden yineleyici denetim noktalarının büyük olabileceğini unutmayın.
Yineleyicinizi bir denetim noktasına dahil etmek için yineleyiciyi tf.train.Checkpoint
yapıcısına tf.train.Checkpoint
.
range_ds = tf.data.Dataset.range(20)
iterator = iter(range_ds)
ckpt = tf.train.Checkpoint(step=tf.Variable(0), iterator=iterator)
manager = tf.train.CheckpointManager(ckpt, '/tmp/my_ckpt', max_to_keep=3)
print([next(iterator).numpy() for _ in range(5)])
save_path = manager.save()
print([next(iterator).numpy() for _ in range(5)])
ckpt.restore(manager.latest_checkpoint)
print([next(iterator).numpy() for _ in range(5)])
[0, 1, 2, 3, 4] [5, 6, 7, 8, 9] [5, 6, 7, 8, 9]
Tf.data'yı tf.keras ile kullanma
tf.keras
API, makine öğrenimi modellerini oluşturmanın ve tf.keras
birçok yönünü basitleştirir. .fit()
ve .evaluate()
ve .predict()
API'leri veri kümelerini girdi olarak destekler. İşte hızlı bir veri kümesi ve model kurulumu:
train, test = tf.keras.datasets.fashion_mnist.load_data()
images, labels = train
images = images/255.0
labels = labels.astype(np.int32)
fmnist_train_ds = tf.data.Dataset.from_tensor_slices((images, labels))
fmnist_train_ds = fmnist_train_ds.shuffle(5000).batch(32)
model = tf.keras.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(10)
])
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
Model.fit
ve Model.evaluate
için gereken tek şey (feature, label)
çiftinden oluşan bir veri Model.evaluate
:
model.fit(fmnist_train_ds, epochs=2)
Epoch 1/2 1875/1875 [==============================] - 4s 2ms/step - loss: 0.7804 - accuracy: 0.7374 Epoch 2/2 1875/1875 [==============================] - 3s 2ms/step - loss: 0.4711 - accuracy: 0.8393 <tensorflow.python.keras.callbacks.History at 0x7f3ef05b1390>
Örneğin Dataset.repeat()
çağırarak sonsuz bir veri kümesi geçirirseniz, steps_per_epoch
bağımsız değişkenini de steps_per_epoch
gerekir:
model.fit(fmnist_train_ds.repeat(), epochs=2, steps_per_epoch=20)
Epoch 1/2 20/20 [==============================] - 0s 2ms/step - loss: 0.4312 - accuracy: 0.8562 Epoch 2/2 20/20 [==============================] - 0s 2ms/step - loss: 0.4509 - accuracy: 0.8344 <tensorflow.python.keras.callbacks.History at 0x7f3ef062e198>
Değerlendirme için değerlendirme adımlarının sayısını geçebilirsiniz:
loss, accuracy = model.evaluate(fmnist_train_ds)
print("Loss :", loss)
print("Accuracy :", accuracy)
1875/1875 [==============================] - 4s 2ms/step - loss: 0.4347 - accuracy: 0.8516 Loss : 0.43466493487358093 Accuracy : 0.8515999913215637
Uzun veri kümeleri için değerlendirilecek adımların sayısını ayarlayın:
loss, accuracy = model.evaluate(fmnist_train_ds.repeat(), steps=10)
print("Loss :", loss)
print("Accuracy :", accuracy)
10/10 [==============================] - 0s 2ms/step - loss: 0.4131 - accuracy: 0.8750 Loss : 0.41311272978782654 Accuracy : 0.875
Model.predict
etiketlere gerek Model.predict
.
predict_ds = tf.data.Dataset.from_tensor_slices(images).batch(32)
result = model.predict(predict_ds, steps = 10)
print(result.shape)
(320, 10)
Ancak, bunları içeren bir veri kümesini geçirirseniz etiketler yok sayılır:
result = model.predict(fmnist_train_ds, steps = 10)
print(result.shape)
(320, 10)