این صفحه به‌وسیله ‏Cloud Translation API‏ ترجمه شده است.
Switch to English

tf.data: ساخت خطوط لوله ورودی TensorFlow

مشاهده در TensorFlow.org در Google Colab اجرا کنید مشاهده منبع در GitHub بارگیری نوت بوک

API tf.data شما را قادر می سازد خطوط لوله ورودی پیچیده را از قطعات ساده و قابل استفاده مجدد بسازید. به عنوان مثال ، خط لوله برای یک مدل تصویر ممکن است داده های پرونده ها را در یک سیستم فایل توزیع شده جمع کند ، اختلالات تصادفی را برای هر تصویر اعمال کند و تصاویر انتخاب شده به طور تصادفی را در یک دسته برای آموزش ادغام کند. خط لوله برای یک مدل متن ممکن است مستلزم استخراج نمادها از داده های متنی خام ، تبدیل آنها به شناسه های تعبیه شده با یک جدول جستجو ، و ترتیب دادن توالی هایی با طول های مختلف باشد. API tf.data امکان دستیابی به مقادیر زیادی از داده ها ، خواندن از قالب های مختلف داده و انجام تحولات پیچیده را ممکن می سازد.

API tf.data یک انتزاع tf.data.Dataset معرفی می کند که توالی از عناصر را نشان می دهد ، که در آن هر عنصر از یک یا چند مؤلفه تشکیل شده است. به عنوان مثال ، در یک خط لوله تصویر ، یک عنصر می تواند یک نمونه آموزشی واحد باشد ، با یک جفت از اجزای کششی نشان دهنده تصویر و برچسب آن.

دو روش مشخص برای ایجاد مجموعه داده وجود دارد:

  • یک منبع Dataset از داده های ذخیره شده در حافظه یا در یک یا چند پرونده ، یک Dataset را ایجاد می کند.

  • یک تبدیل داده یک مجموعه داده از یک یا چند اشیاء tf.data.Dataset می کند.

 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)
 

مکانیک پایه

برای ایجاد خط لوله ورودی ، باید از یک منبع داده شروع کنید. به عنوان مثال ، برای ساخت Dataset از داده های موجود در حافظه ، می توانید از tf.data.Dataset.from_tensors() یا tf.data.Dataset.from_tensor_slices() . از طرف دیگر ، اگر داده ورودی شما در یک پرونده با فرمت توصیه شده TFRecord ذخیره می شود ، می توانید از tf.data.TFRecordDataset() استفاده کنید.

هنگامی که یک شیء Dataset دارید ، می توانید با استفاده از زنجیره ای فراخوانی در شیء tf.data.Dataset آن را به یک Dataset جدید تبدیل کنید. به عنوان مثال ، می توانید تحولات هر عنصر مانند Dataset.map() ، و تحولات چند عنصری مانند Dataset.batch() . برای لیست کاملی از تحولات ، اسناد مربوط به tf.data.Dataset ببینید.

شیء Dataset یک Python قابل تکرار است. این امر باعث می شود كه عناصر آن با استفاده از حلقه for:

 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

یا با صراحت ایجاد یک تکرارکننده Python با استفاده از iter و مصرف عناصر آن با استفاده از next :

 it = iter(dataset)

print(next(it).numpy())
 
8

روش دیگر، مجموعه داده عناصر را می توان با استفاده از مصرف reduce تحول، که باعث کاهش تمام عناصر برای تولید یک نتیجه واحد است. مثال زیر چگونگی استفاده از تحول reduce برای محاسبه مجموع مجموعه داده های صحیح را نشان می دهد.

 print(dataset.reduce(0, lambda state, value: state + value).numpy())
 
22

ساختار مجموعه داده

یک مجموعه داده شامل عناصری است که هر یک از ساختار یکسان (تو در تو) برخوردار هستند و اجزای جداگانه ساختار می توانند از هر نوع قابل نمایش با tf.TypeSpec ، از جمله tf.Tensor ، tf.sparse.SparseTensor ، tf.RaggedTensor ، tf.TensorArray ، یا tf.data.Dataset .

خاصیت Dataset.element_spec به شما امکان می دهد نوع هر مؤلفه عنصر را بررسی کنید. این ویژگی ساختار تو در تو را از اجسام tf.TypeSpec برمی گرداند ، مطابق با ساختار عنصر ، که ممکن است یک جزء واحد ، یک جزء از اجزاء یا یک توپی تو در تو تو در تو باشد. مثلا:

 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 از مجموعه داده های هر ساختار پشتیبانی می کند. هنگام استفاده از Dataset.map() و Dataset.filter() كه تابعی را برای هر عنصر اعمال می كند ، ساختار عنصر آرگومان های تابع را تعیین می كند:

 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())
 
[8 1 2 6 1 7 2 6 1 3]
[6 5 6 5 3 5 2 5 3 6]
[5 8 4 8 3 1 4 6 4 8]
[2 4 5 8 3 5 7 9 4 2]

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

خواندن داده های ورودی

مصرف آرایه های NumPy

برای مثالهای دیگر بارگیری آرایه های NumPy را مشاهده کنید.

اگر همه داده های ورودی شما در حافظه جا داشته باشند ، ساده ترین راه برای ایجاد Dataset از آنها ، تبدیل آنها به اشیاء tf.Tensor و استفاده از Dataset.from_tensor_slices() .

 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 [==============================] - 0s 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)>

مصرف کننده ژنراتورهای پایتون

یکی دیگر از منابع رایج داده ای که به راحتی به عنوان tf.data.Dataset است تولید کننده پایتون است.

 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 ژنراتور پایتون را به یک tf.data.Dataset کاملاً کاربردی tf.data.Dataset .

سازنده یک ورودی را به عنوان ورودی دریافت می کند ، نه یک تکرار کننده. این به آن اجازه می دهد تا هنگام رسیدن به انتها ، مجدداً راه اندازی شود. طول می کشد اختیاری args استدلال، که به عنوان استدلال قابل فراخوانی گذشت.

آرگومان output_types لازم است زیرا tf.data یک tf.Graph داخل ایجاد می کند ، و لبه های نمودار نیاز به یک 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 استدلال مورد نیاز نمی باشد اما بسیار به عنوان بسیاری از عملیات tensorflow توصیه نمی تانسورها با رتبه ناشناخته پشتیبانی نمی کند. اگر طول یک محور خاص ناشناخته یا متغیر است ، آن را به عنوان None در output_shapes .

این نیز مهم است که توجه داشته باشید که output_shapes و output_types پیروی از قوانین تودرتو همان روش های مجموعه داده است.

در اینجا یک مولد مثال وجود دارد که هر دو جنبه را نشان می دهد ، نوارهای آرایه را برمی گرداند ، جایی که آرایه دوم یک بردار با طول ناشناخته است.

 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.978  -1.0531  0.1959 -2.1618]
1 : [ 1.9185 -0.1874  0.5084]
2 : [0.1441 0.3987 0.7737 0.9266 1.5057 0.9151]
3 : [ 0.681  -0.6155 -0.1231 -0.2429  0.6892  1.2571 -1.7588 -1.6575 -0.5375]
4 : [-0.5567  1.5298  0.7242  0.2213]
5 : [ 1.5572 -0.6856]
6 : [-1.0965 -0.336   1.2405  0.6006]

خروجی اول int32 و دوم float32 .

مورد اول مقیاس ، شکل () و مورد دوم یک بردار با طول و شکل ناشناخته است (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)>

اکنون می تواند مانند یک tf.data.Dataset معمولی استفاده شود. توجه داشته باشید که هنگام جمع کردن یک مجموعه داده با یک شکل متغیر ، باید از 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())
 
[ 2 10 18  3  6 15 25 23  0  4]

[[ 1.2665 -0.6274  0.4076  1.0146  0.      0.      0.      0.    ]
 [ 0.8091 -0.0683 -0.1464  0.2734  0.7461 -0.1009  0.      0.    ]
 [-0.9381  1.5075  0.      0.      0.      0.      0.      0.    ]
 [ 1.5705  0.4438  0.      0.      0.      0.      0.      0.    ]
 [-0.4692 -1.8328 -2.2838  0.7418  0.0172 -0.3547 -1.4502 -1.2786]
 [-1.574   0.      0.      0.      0.      0.      0.      0.    ]
 [-0.9274  1.4758  0.      0.      0.      0.      0.      0.    ]
 [-0.5043  0.7066  0.9599 -1.2986  0.      0.      0.      0.    ]
 [ 0.      0.      0.      0.      0.      0.      0.      0.    ]
 [-0.4893 -0.6937  0.      0.      0.      0.      0.      0.    ]]

برای یک مثال واقعی تر ، سعی کنید preprocessing.image.ImageDataGenerator به عنوان tf.data.Dataset .

ابتدا داده ها را بارگیری کنید:

 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 [==============================] - 2s 0us/step

image.ImageDataGenerator ایجاد کنید

 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(
    img_gen.flow_from_directory, args=[flowers], 
    output_types=(tf.float32, tf.float32), 
    output_shapes=([32,256,256,3], [32,5])
)

ds
 
<FlatMapDataset shapes: ((32, 256, 256, 3), (32, 5)), types: (tf.float32, tf.float32)>

مصرف داده TFRecord

بارگیری TFRecords را برای یک مثال پایان به انتها مراجعه کنید.

API tf.data انواع مختلفی از فرمت های فایل را پشتیبانی می کند تا بتوانید مجموعه داده های بزرگی را که در حافظه جا نمی شوند پردازش کنید. به عنوان مثال ، فرمت فایل TFRecord یک قالب باینری ضبط گرا است که بسیاری از برنامه های TensorFlow برای آموزش داده استفاده می کنند. کلاس tf.data.TFRecordDataset به شما امکان می دهد تا بیش از محتوای یک یا چند فایل TFRecord به عنوان بخشی از یک خط لوله ورودی جریان پیدا کنید.

در اینجا مثالی با استفاده از فایل تست از نشانه های خیابان فرانسوی (FSNS) استفاده شده است.

 # 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

آرگومان filenames اولیه TFRecordDataset می تواند یک رشته ، لیستی از رشته ها یا یک tf.Tensor رشته ها باشد. بنابراین اگر دو مجموعه پرونده برای اهداف آموزش و اعتبار سنجی دارید ، می توانید یک روش کارخانه را تولید کنید که مجموعه داده را تولید می کند ، و نام های پرونده را به عنوان یک آرگومان ورودی در نظر می گیرد:

 dataset = tf.data.TFRecordDataset(filenames = [fsns_test_file])
dataset
 
<TFRecordDatasetV2 shapes: (), types: tf.string>

بسیاری از پروژه های tf.train.Example پرونده های سریال tf.train.Example در پرونده های TFRecord استفاده می کنند. قبل از بازرسی باید این موارد رمزگشایی شود:

 raw_example = next(iter(dataset))
parsed = tf.train.Example.FromString(raw_example.numpy())

parsed.features.feature['image/text']
 
bytes_list {
  value: "Rue Perreyon"
}

مصرف داده های متنی

به عنوان مثال برای بارگذاری پایان ، بارگیری متن را مشاهده کنید.

بسیاری از مجموعه داده ها به عنوان یک یا چند فایل متنی توزیع می شوند. tf.data.TextLineDataset روشی آسان برای استخراج خطوط از یک یا چند فایل متنی فراهم می کند. با توجه به یک یا چند نام TextLineDataset ، یک TextLineDataset یک عنصر با ارزش رشته در هر خط از آن پرونده ها تولید می کند.

 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)
 

در اینجا چند خط اول پرونده اول آورده شده است:

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

برای متناوب خطوط بین پرونده ها از Dataset.interleave استفاده کنید. این باعث می شود که پرونده ها را با هم راحت تر کنید. در اینجا سطر اول ، دوم و سوم از هر ترجمه آورده شده است:

 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'

به طور پیش فرض ، یک TextLineDataset هر خط از هر پرونده را به دست می آورد ، که ممکن است مطلوب نباشد ، برای مثال ، اگر پرونده با یک خط هدر شروع شود ، یا حاوی نظرات باشد. این خطوط با استفاده از Dataset.skip() یا Dataset.filter() قابل حذف هستند. در اینجا ، شما خط اول را پرش می کنید ، سپس فیلتر می کنید تا فقط بازماندگان را پیدا کنید.

 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

برای مثالهای دیگر بارگیری پرونده های CSV ، و بارگیری داده های Pandas DataFrames را مشاهده کنید .

فرمت فایل CSV یک فرمت محبوب برای ذخیره داده های جدولی در متن ساده است.

مثلا:

 titanic_file = tf.keras.utils.get_file("train.csv", "https://storage.googleapis.com/tf-datasets/titanic/train.csv")
 
 df = pd.read_csv(titanic_file, index_col=None)
df.head()
 

اگر داده های شما در حافظه متناسب باشد ، همان روش Dataset.from_tensor_slices روی دیکشنری ها کار می کند ، اجازه می دهد این داده ها به راحتی وارد شوند:

 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'

یک رویکرد مقیاس پذیرتر بارگذاری دیسک در صورت لزوم است.

ماژول tf.data روشهایی را برای استخراج سوابق از یک یا چند پرونده CSV که مطابق با RFC 4180 هستند فراهم می کند.

عملکرد experimental.make_csv_dataset .make_csv_dataset رابط سطح بالایی برای خواندن مجموعه فایلهای CSV است. این نرم افزار از استنتاج نوع ستون و بسیاری از ویژگی های دیگر مانند دسته بندی و زدن آن استفاده می کند تا کاربرد آن ساده شود.

 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 1 0 0]
features:
  'sex'               : [b'male' b'female' b'male' b'male']
  'age'               : [28. 42. 43. 21.]
  'n_siblings_spouses': [0 0 0 0]
  'parch'             : [0 0 0 0]
  'fare'              : [47.1    13.      8.05    8.6625]
  'class'             : [b'First' b'Second' b'Third' b'Third']
  'deck'              : [b'unknown' b'unknown' b'unknown' b'unknown']
  'embark_town'       : [b'Southampton' b'Southampton' b'Southampton' b'Southampton']
  'alone'             : [b'y' b'y' b'y' b'y']

اگر فقط به زیر مجموعه ستون ها نیاز دارید می توانید از آرگومان select_columns استفاده کنید.

 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': [1 0 1 1]
  'fare'              : [24.15    0.     13.8583 53.1   ]
  'class'             : [b'Third' b'Second' b'Second' b'First']

همچنین یک کلاس experimental.CsvDataset سطح پایین تر.CsvDataset وجود دارد که کنترل دانه ریزتری را ارائه می دهد. از استنتاج نوع ستون پشتیبانی نمی کند. در عوض باید نوع هر ستون را مشخص کنید.

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

اگر برخی از ستونها خالی باشد ، این رابط سطح پایین به شما امکان می دهد به جای انواع ستون ، مقادیر پیش فرض را ارائه دهید.

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

به طور پیش فرض ، یک CsvDataset هر ستون از هر سطر فایل را به دست می آورد ، که ممکن است مطلوب نباشد ، به عنوان مثال اگر پرونده با یک خط هدر شروع می شود که باید نادیده گرفته شود ، یا اگر بعضی از ستون ها در ورودی لازم نیست. این سطرها و زمینه ها به ترتیب با آرگومانهای header و select_cols قابل حذف هستند.

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

مجموعه ای از پرونده ها را مصرف می کنید

مجموعه داده های زیادی به عنوان مجموعه ای از پرونده ها توزیع شده است ، که در آن هر پرونده به عنوان نمونه است.

 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)

 

فهرست اصلی شامل دایرکتوری برای هر کلاس است:

 for item in flowers_root.glob("*"):
  print(item.name)
 
sunflowers
daisy
LICENSE.txt
roses
tulips
dandelion

پرونده های موجود در هر فهرست راهنما کلاس هستند:

 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/dandelion/7243478942_30bf542a2d_m.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/tulips/4525067924_177ea3bfb4.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/tulips/7002703410_3e97b29da5_n.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/daisy/6299910262_336309ffa5_n.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/sunflowers/6140661443_bb48344226.jpg'

داده ها را با استفاده از عملکرد tf.io.read_file و برچسب را از مسیر ، جفت های برگشتی (image, label) :

 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\x01\x00H\x00H\x00\x00\xff\xe2\x0cXICC_PROFILE\x00\x01\x01\x00\x00\x0cHLino\x02\x10\x00\x00mntrRGB XYZ \x07\xce\x00\x02\x00\t\x00\x06\x001\x00\x00acspMSFT\x00\x00\x00\x00IEC sRGB\x00\x00\x00\x00\x00\x00'

b'tulips'

عناصر مجموعه داده دسته بندی می شود

دسته بندی ساده

ساده ترین شکل جداجدا سفارش داده شده پشته n عناصر متوالی از یک مجموعه داده به یک عنصر. تبدیل Dataset.batch() دقیقاً همین کار را انجام می دهد ، با همان محدودیت هایی که tf.stack() برای هر مؤلفه عناصر اعمال می کند: یعنی برای هر مؤلفه i ، همه عناصر باید یک تانسور دقیقاً به همان شکل داشته باشند.

 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 سعی در انتشار اطلاعات شکل دارد ، تنظیمات پیش فرض Dataset.batch به اندازه دسته ناشناخته منجر می شود زیرا آخرین دسته ممکن است کامل نباشد. توجه داشته باشید که None در شکل نیست:

 batched_dataset
 
<BatchDataset shapes: ((None,), (None,)), types: (tf.int64, tf.int64)>

از آرگومان drop_remainder برای نادیده گرفتن آخرین دسته استفاده کنید و انتشار کامل شکل را بدست آورید:

 batched_dataset = dataset.batch(7, drop_remainder=True)
batched_dataset
 
<BatchDataset shapes: ((7,), (7,)), types: (tf.int64, tf.int64)>

دسته دهی به طناب با بالشتک

دستور العمل فوق برای تنسورهایی کار می کند که همه دارای اندازه یکسان هستند. با این حال ، بسیاری از مدل ها (به عنوان مثال مدل های دنباله) با داده های ورودی کار می کنند که می توانند اندازه های مختلفی داشته باشند (به عنوان مثال توالی هایی با طول های مختلف). برای رسیدگی به این مورد ، انتقال Dataset.padded_batch به شما امکان می دهد تا با مشخص کردن یک یا چند بعد که ممکن است در آن قرار بگیرند ، دسته های مختلفی از شکل های مختلف را جمع کنید.

 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 به شما امکان می دهد برای هر بعد از هر مؤلفه ، لایه های مختلفی را تنظیم کنید ، و ممکن است طول متغیر باشد (که در مثال بالا توسط None مشخص شده است) یا طول ثابت. همچنین می توان مقدار padding را که پیش فرض 0 است ، نادیده گرفت.

گردش کار آموزش

پردازش چندین دوره

API tf.data دو روش اصلی برای پردازش چندین دوره از داده های مشابه ارائه می دهد.

ساده ترین راه برای تکرار بیش از یک مجموعه داده در چند دوره استفاده از تبدیل Dataset.repeat() . ابتدا یک مجموعه داده از داده های تایتانیک ایجاد کنید:

 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() بدون هیچگونه استدلال ، ورودی را به طور نامحدود تکرار خواهید کرد.

تحول Dataset.repeat استدلالهای خود را بدون نشان دادن پایان یک دوره و آغاز دوره بعدی به نتیجه می رساند. از آنجا که از این Dataset.batch اعمال پس از Dataset.repeat خواهد دسته عملکرد که مرزهای عصر دریافت اتصال:

 titanic_batches = titanic_lines.repeat(3).batch(128)
plot_batch_sizes(titanic_batches)
 

png

اگر به جدایی Dataset.batch واضح نیاز دارید ، Dataset.batch قبل از تکرار قرار دهید:

 titanic_batches = titanic_lines.batch(128).repeat(3)

plot_batch_sizes(titanic_batches)
 

png

اگر مایل هستید در پایان هر دوره یک محاسبه سفارشی (به عنوان مثال جمع آوری آمار) انجام دهید ، ساده ترین راه اندازی مجدد تکرار مجموعه داده در هر دوره است:

 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

به طور تصادفی داده های ورودی را تغییر دهید

Dataset.shuffle() یک بافر در اندازه ثابت را حفظ می کند و عنصر بعدی را به طور تصادفی از آن بافر انتخاب می کند.

یک فهرست به مجموعه داده اضافه کنید تا جلوه را مشاهده کنید:

 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 است و اندازه دسته 20 است ، دسته اول هیچ عنصر با نمایه بالای 120 ندارد.

 n,line_batch = next(iter(dataset))
print(n.numpy())
 
[ 63  48 101  12 103  52   6  39   4   9  93  91   5  86  79  64  95  33
 102  50]

همانند Dataset.batch را نسبت به Dataset.repeat .

Dataset.shuffle تا انتهای یک دوره تأیید نمی شود. بنابراین یک تغییر شکل داده شده قبل از تکرار ، همه عناصر یک دوره را قبل از حرکت به مرحله بعدی نشان می دهد:

 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:

[613 609 624 553 608 583 493 617 611 610]
[217 508 579 601 319 616 606 549 618 623]
[416 567 404 622 283 458 503 602]
[ 87  68  56  16   6  62   1  89  58 106]
[98 80 43 10 67 44 19 34 13 57]

 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 0x7fe0a00a1d68>

png

اما یک تکرار قبل از زدن حرکت ، مرزهای دوره را با هم مخلوط می کند:

 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:

[440  15   8 599 567  18 550   5  19  17]
[ 12 501 571 473 466  21 531 596 580 555]
[  3 573  38 563  25 416 595  29  46 602]
[485 566 561  16 331 615 386  28 609  41]
[611 622 575  10 589  61 598 527  52  35]
[ 55 597  42  23  13  47  11 505  68 582]
[612 613  75  43   7 392  74 452  82 509]
[  9  44  62 491  71 343  51 590  60  98]
[  6  95 619  86 625 537 617  85 465   0]
[ 88  27  92 101 109 111 104  24  36 113]
[103 118  79  53  70  40 121 100  65  33]
[562 588 124 125  64  84  83  67 610 130]
[  4 142 131  90 518 129 143 112   2 551]
[377  91 140  76  50  48 526 553 156 591]
[105 128  69 114  93 520 154  56 145 115]

 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 0x7fe0582fbb70>

png

پردازش داده ها

تبدیل Dataset.map(f) با استفاده از یک تابع داده شده f در هر عنصر از مجموعه داده های ورودی ، یک مجموعه داده جدید ایجاد می کند. این مبتنی بر عملکرد map() است که معمولاً در زبانها (و سایر ساختارها) در زبانهای برنامه نویسی کاربردی اعمال می شود. تابع f از اشیاء tf.Tensor استفاده می کند که یک عنصر واحد را در ورودی نشان می دهد و اشیاء tf.Tensor را که یک عنصر واحد در مجموعه داده های جدید هستند نمایان می کند. اجرای آن با استفاده از عملیات استاندارد TensorFlow برای تبدیل یک عنصر به عنصر دیگر.

در این بخش نمونه های متداول نحوه استفاده از Dataset.map() .

رمزگشایی داده های تصویر و تغییر اندازه آن

هنگام آموزش شبکه عصبی بر روی داده های تصویر در دنیای واقعی ، اغلب لازم است تصاویر با اندازه های مختلف به اندازه مشترک تبدیل شوند ، به طوری که ممکن است در یک اندازه ثابت دسته بندی شوند.

بازسازی مجموعه داده نام پرونده های گل:

 list_ds = tf.data.Dataset.list_files(str(flowers_root/'*/*'))
 

تابعی بنویسید که عناصر مجموعه داده را دستکاری کند.

 # 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
 

تست کنید که کار کند.

 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)
 

png

نقشه آن را روی مجموعه داده قرار دهید.

 images_ds = list_ds.map(parse_image)

for image, label in images_ds.take(2):
  show(image, label)
 

png

png

استفاده از منطق پایتون دلخواه

به دلایل عملکرد ، از عملیات TensorFlow برای پیش پردازش داده های خود در هر زمان ممکن استفاده کنید. با این حال ، گاهی اوقات استفاده از کتابخانه های خارجی پایتون هنگام تجزیه داده های ورودی شما مفید است. می توانید از عملکرد tf.py_function() در یک تبدیل Dataset.map() استفاده کنید.

به عنوان مثال ، اگر می خواهید یک چرخش تصادفی اعمال کنید ، ماژول tf.image فقط دارای tf.image.rot90 که برای تقویت تصویر بسیار مفید نیست.

برای نشان دادن tf.py_function ، سعی کنید به جای آن از عملکرد scipy.ndimage.rotate استفاده کنید:

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

png

برای استفاده از این تابع با Dataset.map همان هشدارهایی که مانند Dataset.from_generator اعمال می شود ، باید هنگام استفاده از این تابع ، شکل ها و انواع برگشت را شرح دهید:

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

png

png

تجزیه tf.Example پیام های بافر پروتکل

بسیاری از خطوط لوله ورودی پیامهای بافر پروتکل tf.train.Example را از قالب TFRecord استخراج می کنند. هر رکورد tf.train.Example شامل یک یا چند "ویژگی" است ، و خط لوله ورودی به طور معمول این ویژگی ها را به tf.train.Example تبدیل می کند.

 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>

برای درک داده ها می توانید با tf.train.Example اولیه tf.train.Example نمونه از tf.data.Dataset کنید:

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

png

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

سیم پیچ سری زمانی

به عنوان مثال برای پایان دادن به پایان سریال سریال به بخش پیش بینی زمان مراجعه کنید.

داده های سری زمانی اغلب با دست نخورده محور زمان سازماندهی می شوند.

برای نشان دادن از یک Dataset.range ساده استفاده کنید:

 range_ds = tf.data.Dataset.range(100000)
 

به طور معمول ، مدلهای مبتنی بر این نوع داده ها ، برش زمانی مبهم را می خواهند.

ساده ترین روش جمع آوری داده ها خواهد بود:

با استفاده از batch

 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]

یا برای پیش بینی های متراکم یک قدم به آینده ، ممکن است ویژگی ها و برچسب ها را با یک قدم نسبت به یکدیگر تغییر دهید:

 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]

برای پیش بینی یک پنجره کامل به جای یک جبران ثابت می توانید دسته ها را به دو قسمت تقسیم کنید:

 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]

برای اینکه بین ویژگی های یک دسته و برچسب های دیگر Dataset.zip ، از Dataset.zip استفاده کنید:

 feature_length = 10
label_length = 5

features = range_ds.batch(feature_length, drop_remainder=True)
labels = range_ds.batch(feature_length).skip(1).map(lambda labels: labels[:-5])

predict_5_steps = tf.data.Dataset.zip((features, labels))

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]
[10 11 12 13 14 15 16 17 18 19]  =>  [20 21 22 23 24]
[20 21 22 23 24 25 26 27 28 29]  =>  [30 31 32 33 34]

با استفاده از window

در حالی که از Dataset.batch استفاده می کنید ، موقعیت هایی وجود دارد که ممکن است شما نیاز به کنترل دقیق تری داشته باشید. روش Dataset.window کنترل کاملی به شما می دهد ، اما Dataset.window به کمی دقت دارد: این یک Dataset از Datasets را برمی گرداند. برای جزئیات بیشتر به ساختار Dataset مراجعه کنید.

 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 می تواند مجموعه ای از مجموعه داده ها را بدست آورد و آن را در یک مجموعه داده واحد قرار دهد:

  for x in windows.flat_map(lambda x: x).take(30):
   print(x.numpy(), end=' ')
 
WARNING:tensorflow:AutoGraph could not transform <function <lambda> at 0x7fe0582dbbf8> and will run it as-is.
Cause: could not parse the source code:

for x in windows.flat_map(lambda x: x).take(30):

This error may be avoided by creating the lambda in a standalone statement.

To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function <lambda> at 0x7fe0582dbbf8> and will run it as-is.
Cause: could not parse the source code:

for x in windows.flat_map(lambda x: x).take(30):

This error may be avoided by creating the lambda in a standalone statement.

To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
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 

تقریباً در همه موارد ، ابتدا می خواهید مجموعه داده را .batch کنید:

 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]

اکنون می توانید مشاهده کنید که آرگومان shift مقدار میزان حرکت هر پنجره را کنترل می کند.

با هم قرار دادن این ممکن است این عملکرد را بنویسید:

 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]

سپس استخراج برچسب ها مانند گذشته آسان است:

 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]

تغییر شکل

هنگام کار با مجموعه داده ای که بسیار متعادل کلاس است ، ممکن است بخواهید مجموعه داده را مجدداً تغییر دهید. tf.data برای این کار دو روش ارائه می دهد. مجموعه داده های کلاهبرداری کارت اعتباری نمونه خوبی از این نوع مشکل است.

 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 [==============================] - 10s 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()])
 

در حال حاضر ، توزیع کلاس ها را بررسی کنید ، بسیار تند و تیز است:

 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.996 0.004]

یک روش مشترک برای آموزش با یک مجموعه داده نامتوازن ، تعادل آن است. tf.data شامل چند روش است که این گردش کار را فعال می کند:

نمونه گیری از مجموعه داده ها

یکی از روشهای تغییر شکل داده ها ، استفاده از sample_from_datasets . این مورد زمانی کاربرد دارد که داده های جداگانه data.Dataset برای هر کلاس داشته باشید.

در اینجا ، فقط از فیلتر استفاده کنید تا آنها را از داده های کلاهبرداری کارت اعتباری تولید کنید:

 negative_ds = (
  creditcard_ds
    .unbatch()
    .filter(lambda features, label: label==0)
    .repeat())
positive_ds = (
  creditcard_ds
    .unbatch()
    .filter(lambda features, label: label==1)
    .repeat())
 
WARNING:tensorflow:AutoGraph could not transform <function <lambda> at 0x7fe0a01fd1e0> and will run it as-is.
Cause: could not parse the source code:

    .filter(lambda features, label: label==0)

This error may be avoided by creating the lambda in a standalone statement.

To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function <lambda> at 0x7fe0a01fd1e0> and will run it as-is.
Cause: could not parse the source code:

    .filter(lambda features, label: label==0)

This error may be avoided by creating the lambda in a standalone statement.

To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING:tensorflow:AutoGraph could not transform <function <lambda> at 0x7fe058159620> and will run it as-is.
Cause: could not parse the source code:

    .filter(lambda features, label: label==1)

This error may be avoided by creating the lambda in a standalone statement.

To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function <lambda> at 0x7fe058159620> and will run it as-is.
Cause: could not parse the source code:

    .filter(lambda features, label: label==1)

This error may be avoided by creating the lambda in a standalone statement.

To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert

 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 مجموعه داده ها را تصویب می کنید ، و وزن هر یک:

 balanced_ds = tf.data.experimental.sample_from_datasets(
    [negative_ds, positive_ds], [0.5, 0.5]).batch(10)
 

اکنون مجموعه داده نمونه هایی از هر کلاس را با احتمال 50/50 تولید می کند:

 for features, labels in balanced_ds.take(10):
  print(labels.numpy())
 
[0 0 0 1 0 0 1 1 0 0]
[1 1 0 0 1 1 0 0 0 1]
[1 1 0 0 0 0 0 0 1 1]
[1 0 0 1 1 0 0 0 1 0]
[1 1 0 0 0 1 1 0 0 1]
[0 0 1 1 1 0 0 1 1 0]
[0 0 0 1 0 0 0 1 1 1]
[1 1 0 1 0 0 1 0 1 1]
[0 1 0 0 1 1 0 0 0 1]
[0 1 0 0 1 0 0 1 1 0]

تغییر مجدد رد

یکی از مشکلات رویکرد experimental.sample_from_datasets فوق. tf.data.Dataset این است که به یک کلاس جداگانه tf.data.Dataset نیاز دارد. با استفاده از Dataset.filter کار می کند ، اما باعث می شود همه داده ها دو بار بارگذاری شوند.

تابع data.experimental.rejection_resample را می توان برای یک تعادل دوباره به یک مجموعه داده اعمال کرد ، در حالی که فقط یک بار بارگذاری می شود. عناصر برای دستیابی به تعادل از مجموعه داده ها حذف می شوند.

data.experimental.rejection_resample طول می کشد یک class_func استدلال است. این class_func برای هر عنصر مجموعه داده اعمال می شود و برای تعیین تعادل از کدام کلاس به عنوان کلاس استفاده می شود.

عناصر creditcard_ds از قبل (features, label) جفت هستند. بنابراین class_func فقط باید آن برچسب ها را برگرداند:

 def class_func(features, label):
  return label
 

resampler همچنین به توزیع هدف نیاز دارد و به صورت اختیاری یک تخمین توزیع اولیه:

 resampler = tf.data.experimental.rejection_resample(
    class_func, target_dist=[0.5, 0.5], initial_dist=fractions)
 

معاملات نمونهبردار مجدد با نمونه های منحصر به فرد، بنابراین شما باید unbatch مجموعه داده قبل از استفاده از نمونهبردار مجدد:

 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:


بازگرداندن resampler از خروجی class_func جفت (class, example) ایجاد می کند. در این حالت ، example قبلاً یک جفت (feature, label) ، بنابراین از map استفاده کنید تا نسخه اضافی برچسب ها را رها کنید:

 balanced_ds = resample_ds.map(lambda extra_label, features_and_label: features_and_label)
 

اکنون مجموعه داده نمونه هایی از هر کلاس را با احتمال 50/50 تولید می کند:

 for features, labels in balanced_ds.take(10):
  print(labels.numpy())
 
[1 0 1 1 1 1 0 1 1 1]
[0 0 1 1 1 0 1 0 1 1]
[1 0 0 1 0 0 0 0 0 1]
[1 1 1 1 1 1 0 1 1 1]
[1 1 0 1 0 0 0 0 1 0]
[1 0 0 0 1 0 1 0 1 0]
[0 0 0 0 0 0 1 0 0 0]
[0 0 0 1 1 0 0 1 0 1]
[0 0 1 1 1 1 0 0 1 1]
[0 0 1 1 0 1 0 1 1 0]

نشانه گذاری Iterator

Tensorflow از گرفتن پاسگاه ها پشتیبانی می کند به طوری که وقتی فرایند آموزش شما دوباره آغاز شد ، می تواند آخرین بازرسی را بازیابی کند تا بیشتر پیشرفت های خود را بازیابی کند. علاوه بر چک کردن روی متغیرهای مدل ، می توانید پیشرفت تکرار مجموعه داده را نیز بررسی کنید. در صورت داشتن مجموعه داده های بزرگ و اگر نمی خواهید مجموعه داده را از ابتدا در هر راه اندازی مجدد شروع کنید ، می تواند مفید باشد. توجه داشته باشید با این حال که پست های بازرسی تکرارکننده ممکن است بزرگ، از تحولات مانند shuffle و prefetch نیاز به عناصر بافر در تکرارکننده.

برای قرار دادن تکرارکننده خود در یک ایست بازرسی ، تکرار را به سازنده 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]

با استفاده از API های سطح بالا

tf.keras

API tf.keras بسیاری از جنبه های ایجاد و اجرای مدل های یادگیری ماشین را ساده می کند. .fit() و .evaluate() و .predict() داده ها را به عنوان ورودی پشتیبانی می کند. در اینجا مجموعه داده ای سریع و راه اندازی مدل ارائه شده است:

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

عبور از مجموعه داده (feature, label) جفت (feature, label) تمام مواردی است که برای Model.fit و Model.evaluate :

 model.fit(fmnist_train_ds, epochs=2)
 
Epoch 1/2
WARNING:tensorflow:Layer flatten is casting an input tensor from dtype float64 to the layer's dtype of float32, which is new behavior in TensorFlow 2.  The layer has dtype float32 because it's dtype defaults to floatx.

If you intended to run this layer in float32, you can safely ignore this warning. If in doubt, this warning is likely only an issue if you are porting a TensorFlow 1.X model to TensorFlow 2.

To change all layers to have dtype float64 by default, call `tf.keras.backend.set_floatx('float64')`. To change just this layer, pass dtype='float64' to the layer constructor. If you are the author of this layer, you can disable autocasting by passing autocast=False to the base Layer constructor.

1875/1875 [==============================] - 4s 2ms/step - loss: 0.6031 - accuracy: 0.7937
Epoch 2/2
1875/1875 [==============================] - 3s 2ms/step - loss: 0.4620 - accuracy: 0.8416

<tensorflow.python.keras.callbacks.History at 0x7fe13f9ed3c8>

اگر به عنوان مثال با فراخوانی Dataset.repeat() از یک مجموعه داده نامحدود عبور کرده اید ، فقط باید آرگومان steps_per_epoch را نیز تصویب کنید:

 model.fit(fmnist_train_ds.repeat(), epochs=2, steps_per_epoch=20)
 
Epoch 1/2
20/20 [==============================] - 0s 2ms/step - loss: 0.4050 - accuracy: 0.8672
Epoch 2/2
20/20 [==============================] - 0s 2ms/step - loss: 0.4077 - accuracy: 0.8703

<tensorflow.python.keras.callbacks.History at 0x7fe0ca13edd8>

برای ارزیابی می توانید تعداد مراحل ارزیابی را پشت سر بگذارید:

 loss, accuracy = model.evaluate(fmnist_train_ds)
print("Loss :", loss)
print("Accuracy :", accuracy)
 
1875/1875 [==============================] - 3s 2ms/step - loss: 0.4474 - accuracy: 0.8439
Loss : 0.4474281072616577
Accuracy : 0.843916654586792

برای مجموعه داده های طولانی ، تعداد مراحل برای ارزیابی را تعیین کنید:

 loss, accuracy = model.evaluate(fmnist_train_ds.repeat(), steps=10)
print("Loss :", loss)
print("Accuracy :", accuracy)
 
10/10 [==============================] - 0s 2ms/step - loss: 0.5262 - accuracy: 0.8156
Loss : 0.5262183547019958
Accuracy : 0.815625011920929

هنگام تماس با Model.predict برچسب ها لازم 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)

اما اگر از مجموعه داده های حاوی آنها استفاده کنید ، از برچسب ها چشم پوشی می شوید:

 result = model.predict(fmnist_train_ds, steps = 10)
print(result.shape)
 
(320, 10)

tf.estimator

برای استفاده از Dataset در input_fn یک tf.estimator.Estimator ، کافیست Dataset از input_fn و چارچوب مراقبت از عناصر آن را برای شما به دست خواهد آورد. مثلا:

 import tensorflow_datasets as tfds

def train_input_fn():
  titanic = tf.data.experimental.make_csv_dataset(
      titanic_file, batch_size=32,
      label_name="survived")
  titanic_batches = (
      titanic.cache().repeat().shuffle(500)
      .prefetch(tf.data.experimental.AUTOTUNE))
  return titanic_batches
 
 embark = tf.feature_column.categorical_column_with_hash_bucket('embark_town', 32)
cls = tf.feature_column.categorical_column_with_vocabulary_list('class', ['First', 'Second', 'Third']) 
age = tf.feature_column.numeric_column('age')
 
 import tempfile
model_dir = tempfile.mkdtemp()
model = tf.estimator.LinearClassifier(
    model_dir=model_dir,
    feature_columns=[embark, cls, age],
    n_classes=2
)
 
INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpefmfuc4o', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

 model = model.train(input_fn=train_input_fn, steps=100)
 
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/ops/resource_variable_ops.py:1666: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/training_util.py:236: Variable.initialized_value (from tensorflow.python.ops.variables) is deprecated and will be removed in a future version.
Instructions for updating:
Use Variable.read_value. Variables in 2.X are initialized automatically both in eager and graph (inside tf.defun) contexts.
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/feature_column/feature_column_v2.py:540: Layer.add_variable (from tensorflow.python.keras.engine.base_layer_v1) is deprecated and will be removed in a future version.
Instructions for updating:
Please use `layer.add_weight` method instead.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/optimizer_v2/ftrl.py:144: calling Constant.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.
Instructions for updating:
Call initializer instance with the dtype argument instead of passing it to the constructor
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...
INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpefmfuc4o/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:loss = 0.6931472, step = 0
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 100...
INFO:tensorflow:Saving checkpoints for 100 into /tmp/tmpefmfuc4o/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 100...
INFO:tensorflow:Loss for final step: 0.58668363.

 result = model.evaluate(train_input_fn, steps=10)

for key, value in result.items():
  print(key, ":", value)
 
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2020-07-23T01:23:29Z
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmpefmfuc4o/model.ckpt-100
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [1/10]
INFO:tensorflow:Evaluation [2/10]
INFO:tensorflow:Evaluation [3/10]
INFO:tensorflow:Evaluation [4/10]
INFO:tensorflow:Evaluation [5/10]
INFO:tensorflow:Evaluation [6/10]
INFO:tensorflow:Evaluation [7/10]
INFO:tensorflow:Evaluation [8/10]
INFO:tensorflow:Evaluation [9/10]
INFO:tensorflow:Evaluation [10/10]
INFO:tensorflow:Inference Time : 0.83507s
INFO:tensorflow:Finished evaluation at 2020-07-23-01:23:30
INFO:tensorflow:Saving dict for global step 100: accuracy = 0.675, accuracy_baseline = 0.58125, auc = 0.71750116, auc_precision_recall = 0.6480325, average_loss = 0.64111984, global_step = 100, label/mean = 0.41875, loss = 0.64111984, precision = 0.85714287, prediction/mean = 0.30204886, recall = 0.26865673
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 100: /tmp/tmpefmfuc4o/model.ckpt-100
accuracy : 0.675
accuracy_baseline : 0.58125
auc : 0.71750116
auc_precision_recall : 0.6480325
average_loss : 0.64111984
label/mean : 0.41875
loss : 0.64111984
precision : 0.85714287
prediction/mean : 0.30204886
recall : 0.26865673
global_step : 100

 for pred in model.predict(train_input_fn):
  for key, value in pred.items():
    print(key, ":", value)
  break
 
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmpefmfuc4o/model.ckpt-100
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
logits : [-0.5965]
logistic : [0.3551]
probabilities : [0.6449 0.3551]
class_ids : [0]
classes : [b'0']
all_class_ids : [0 1]
all_classes : [b'0' b'1']