তারিখটা মনে রেখো! গুগল I / O মে 18-20 মে এখনই রেজিস্টার করুন
This page was translated by the Cloud Translation API.
Switch to English

tf.data: টেনসরফ্লো ইনপুট পাইপলাইনগুলি তৈরি করুন

টেনসরফ্লো.আর.জে দেখুন গুগল কোলাবে চালান গিটহাবের উত্স দেখুন নোটবুক ডাউনলোড করুন

tf.data API আপনাকে সহজ, পুনরায় ব্যবহারযোগ্য টুকরাগুলি থেকে জটিল ইনপুট পাইপলাইনগুলি তৈরি করতে সক্ষম করে। উদাহরণস্বরূপ, কোনও চিত্র মডেলের পাইপলাইন কোনও বিতরণকৃত ফাইল সিস্টেমে ফাইলগুলি থেকে ডেটা একত্রিত করতে পারে, প্রতিটি চিত্রের সাথে এলোমেলো প্রতিচ্ছবি প্রয়োগ করতে পারে এবং প্রশিক্ষণের জন্য এলোমেলোভাবে নির্বাচিত চিত্রগুলিকে ব্যাচে মিশ্রিত করতে পারে। কোনও পাঠ্য মডেলের পাইপলাইনে কাঁচা পাঠ্য ডেটা থেকে প্রতীকগুলি বের করা, তাদেরকে একটি অনুসন্ধান টেবিলের সাহায্যে শনাক্তকারীদের এমবেডিংয়ে রূপান্তর করা এবং বিভিন্ন দৈর্ঘ্যের ক্রমগুলি একসাথে জড়িত থাকতে পারে। tf.data API এটিকে প্রচুর পরিমাণে ডেটা হ্যান্ডেল করা, বিভিন্ন ডেটা ফর্ম্যাট থেকে পড়া এবং জটিল রূপান্তর সম্পাদন সম্ভব করে তোলে।

tf.data API একটিtf.data.Dataset অ্যাবস্ট্রাকশন উপস্থাপন করে যা উপাদানগুলির ক্রমকে উপস্থাপন করে, যেখানে প্রতিটি উপাদান এক বা একাধিক উপাদান নিয়ে গঠিত। উদাহরণস্বরূপ, একটি চিত্র পাইপলাইনে, কোনও উপাদান একক প্রশিক্ষণের উদাহরণ হতে পারে, চিত্র এবং এর লেবেলের প্রতিনিধিত্বকারী এক জোড়া টেনসর উপাদান রয়েছে।

একটি ডেটাসেট তৈরির দুটি স্বতন্ত্র উপায়:

  • একটি ডেটা সোর্স মেমরিতে বা এক বা একাধিক ফাইলে সঞ্চিত ডেটা থেকে একটি Dataset করে।

  • একটি ডেটা ট্রান্সফর্মেশন এক বা একাধিকtf.data.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 বস্তু, যদি আপনি একটি নতুন সেটিকে রুপান্তর করতে পারেন Dataset উপর পদ্ধতি কল chaining দ্বারাtf.data.Dataset অবজেক্ট। উদাহরণস্বরূপ, আপনি Dataset.map() এবং Dataset.batch() মতো মাল্টি-এলিমেন্ট ট্রান্সফরমেশনগুলির জন্য প্রতি-উপাদান রূপান্তরগুলি প্রয়োগ করতে পারেন। রূপান্তরগুলির সম্পূর্ণ তালিকার জন্যtf.data.Dataset জন্য ডকুমেন্টেশন দেখুন।

Dataset অবজেক্টটি পাইথন পুনরুক্তযোগ্য। এটি লুপের জন্য এটি ব্যবহার করে এর উপাদানগুলি গ্রাস করা সম্ভব করে:

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

অথবা স্পষ্টভাবে একটি পাইথন তৈরি পুনরুক্তিকারীর ব্যবহার করে iter এবং তার উপাদানগুলি ব্যবহার করে গ্রাসকারী next :

it = iter(dataset)

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

বিকল্পভাবে, ডেটাসেট উপাদানগুলি reduce রূপান্তর ব্যবহার করে গ্রাস করা যেতে পারে, যা একক ফলাফল তৈরি করতে সমস্ত উপাদানকে হ্রাস করে। নিম্নলিখিত উদাহরণটি ব্যাখ্যা করে যে কীভাবে reduce রূপান্তরটি পূর্ণসংখ্যার একটি ডেটাসেটের যোগফল গণনা করতে হয়।

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

ডেটাসেট কাঠামো

একটি ডেটাসেটের উপাদান, যেখানে প্রতিটি উপাদান একই (নেস্টেড) উপাদান কাঠামো একটি ক্রম উৎপন্ন হয়। tf.Tensor , tf.sparse.SparseTensor ,tf.RaggedTensor , tf.TensorArray , বাtf.data.Dataset সহ কাঠামোর স্বতন্ত্র উপাদানগুলি tf.TypeSpec দ্বারা যে কোনও ধরণের প্রতিনিধিত্বযোগ্য হতে পারে।

পাইথন নির্মান যে উপাদানের (নেস্টেড) গঠন প্রকাশ করার ব্যবহার করা যেতে পারে অন্তর্ভুক্ত tuple , dict , NamedTuple এবং OrderedDict । বিশেষত, list ডাটাবেস উপাদানগুলির কাঠামো প্রকাশ করার জন্য একটি বৈধ নির্মাণ নয়। এর কারণ তাড়াতাড়ি tf.data ব্যবহারকারীরা list ইনপুটগুলি সম্পর্কে উদারভাবে অনুভব করেছিলেন (যেমন, tf.data.Dataset.from_tensors ) স্বয়ংক্রিয়ভাবে tf.data.Dataset.from_tensors এবং list আউটপুট হিসাবে প্যাক করা (যেমন ব্যবহারকারী-সংজ্ঞায়িত ফাংশনগুলির রিটার্ন মানগুলি) একটি tuple জোর করে। ফলত, যদি আপনি একটি চাই list ইনপুট একটি কাঠামো হিসাবে চিকিত্সা করা, আপনি তা রূপান্তর করতে হবে tuple এবং যদি আপনি একটি চাই list আউটপুট একটি একক উপাদান বলে, তাহলে আপনি স্পষ্টভাবে ব্যবহার করে এটি প্যাক করার প্রয়োজন tf.stack

Dataset.element_spec সম্পত্তি আপনাকে প্রতিটি উপাদান উপাদানগুলির ধরনটি পরীক্ষা করতে দেয়। বৈশিষ্ট্যটি tf.TypeSpec অবজেক্টের একটি নেস্টেড কাঠামো দেয় , tf.TypeSpec কাঠামোর সাথে মিলে যায়, যা কোনও একক উপাদান উপাদানগুলির একটি মূল অংশ বা উপাদানগুলির নেস্টেড 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 সমর্থন করে। 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())
[1 7 5 6 1 3 1 2 2 6]
[1 9 6 4 8 4 2 4 1 8]
[7 2 8 5 4 6 2 8 7 6]
[2 5 8 7 9 4 6 6 1 7]
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 হিসাবে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 রূপান্তর করে।

কনস্ট্রাক্টর ইনপুট হিসাবে কলযোগ্য গ্রহণ করে, পুনরুক্তিকারী নয়। এটি জেনারেটরটি যখন শেষের দিকে পৌঁছে তখন এটি পুনরায় চালু করতে দেয়। এটি একটি alচ্ছিক 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 আর্গুমেন্টের প্রয়োজন হয় না তবে এটি বেশিরভাগ ক্ষেত্রেই পুনরায় সংস্থাপিত হয় কারণ অনেকগুলি টেনসরফ্লো অপারেশন অজানা র‌্যাঙ্কযুক্ত টেনারগুলিকে সমর্থন করে না। যদি কোনও নির্দিষ্ট অক্ষের দৈর্ঘ্য অজানা বা পরিবর্তনশীল হয় তবে output_shapes এটিকে None হিসাবে সেট করুন না।

এটাও গুরুত্বপূর্ণ যে 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 : [ 0.0406 -1.1395  0.1461  1.1128  0.2999  0.407  -0.4695]
1 : [ 0.2245 -0.2066 -1.8607]
2 : []
3 : [ 1.4813 -1.5021]
4 : [-0.523   2.0254 -1.3379 -0.7026  1.1167 -0.8914]
5 : [ 0.1134  0.6948 -0.9116  0.726 ]
6 : [ 2.0992 -0.6726  1.3971]

প্রথম আউটপুটটি একটি 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 করার সময়, আপনাকে 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())
[ 1 10  2 14  9  8 21 17 16 19]

[[ 0.      0.      0.      0.      0.      0.      0.      0.      0.    ]
 [-1.1061 -0.7509 -1.8781 -0.2469  0.1069 -1.159   0.7171  0.0187 -0.638 ]
 [-0.1725  0.7828 -1.6536  0.8356 -0.4334  0.      0.      0.      0.    ]
 [ 0.7425  0.0505 -0.8275 -0.093   0.      0.      0.      0.      0.    ]
 [-0.6104 -1.7805  1.9596 -0.7051  0.1891  0.      0.      0.      0.    ]
 [ 0.6521  0.      0.      0.      0.      0.      0.      0.      0.    ]
 [-1.1652 -0.1417 -0.3912  0.      0.      0.      0.      0.      0.    ]
 [-0.5748 -0.4071  0.7315  0.4816  0.8288  1.4523  0.6656  0.      0.    ]
 [-0.5187 -1.1124 -0.3008 -1.0433  0.3527  2.4732  0.9108  0.      0.    ]
 [ 0.6676 -0.8961 -0.4914 -1.1748  0.4043  0.2664  1.987  -0.722   0.7257]]

একটি আরো বাস্তবসম্মত উদাহরণস্বরূপ, মোড়কে চেষ্টা 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 [==============================] - 1s 0us/step

image.ImageDataGenerator তৈরি করুন 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(
    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 ডেটা গ্রহণ করা

একটি শেষ-শেষের উদাহরণের জন্য টিএফআরকার্ডগুলি লোড করা দেখুন।

tf.data API বিভিন্ন ধরণের ফাইল ফর্ম্যাটকে সমর্থন করে যাতে আপনি মেমরির সাথে খাপ tf.data না এমন বড় ডেটাসেটগুলি প্রক্রিয়া করতে পারেন। উদাহরণস্বরূপ, TFRecord ফাইল ফর্ম্যাটটি একটি সাধারণ রেকর্ড-ভিত্তিক বাইনারি ফর্ম্যাট যা অনেক টেনসরফ্লো অ্যাপ্লিকেশন প্রশিক্ষণ ডেটার জন্য ব্যবহার করে। tf.data.TFRecordDataset বর্গ আপনাকে একটি ইনপুট পাইপলাইনের অংশ হিসাবে এক বা একাধিক TFRecord ফাইলের বিষয়বস্তু প্রবাহিত করতে সক্ষম করে।

ফ্রেঞ্চ স্ট্রিট নেম সাইনস (এফএসএনএস) থেকে টেস্ট ফাইলটি ব্যবহার করে এখানে একটি উদাহরণ দেওয়া আছে।

# 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 প্রারম্ভকালীন filenames নামের আর্গুমেন্ট হয় স্ট্রিং, স্ট্রিংগুলির একটি তালিকা বা স্ট্রিংগুলির tf.Tensor হতে পারে। সুতরাং প্রশিক্ষণ এবং বৈধতার জন্য যদি আপনার কাছে দুটি সেট ফাইল থাকে তবে আপনি একটি কারখানা পদ্ধতি তৈরি করতে পারেন যা ডেটাसेट তৈরি করে, ইনপুট যুক্তি হিসাবে ফাইলের নাম গ্রহণ করে:

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

অনেক টেনসরফ্লো প্রকল্প তাদের TFRecord ফাইলগুলিতে সিরিয়ালযুক্ত tf.train.Example রেকর্ড ব্যবহার করে। এগুলি পরিদর্শন করার আগে এগুলি ডিকোড করা দরকার:

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 সেই ফাইলগুলির প্রতি লাইনে একটি স্ট্রিং-মূল্যবান উপাদান তৈরি করবে।

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 ব্যবহার 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'

সিএসভি ডেটা গ্রহণ করা

আরও উদাহরণের জন্য সিএসভি ফাইল লোড করা এবং পান্ডাস ডেটা ফ্রেমগুলি লোড করা দেখুন।

সরল পাঠ্যে টেবুলার ডেটা সংরক্ষণ করার জন্য সিএসভি ফাইল ফর্ম্যাট একটি জনপ্রিয় ফর্ম্যাট।

উদাহরণ স্বরূপ:

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

যদি আপনার ডেটা একই Dataset.from_tensor_slices পদ্ধতিটি 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 মডিউলটি এক বা একাধিক সিএসভি ফাইল থেকে রেকর্ডগুলি আহরণের জন্য পদ্ধতি সরবরাহ করে যা আরএফসি 4180 মেনে চলে।

experimental.make_csv_dataset ফাংশন হ'ল সিএসভি ফাইলগুলির সেট পড়ার জন্য উচ্চ স্তরের ইন্টারফেস। এটি কলামের ধরণের অনুমিতি এবং ব্যাচিং এবং শিফলিংয়ের মতো আরও অনেকগুলি বৈশিষ্ট্য সমর্থন করে যাতে ব্যবহারকে সহজ করে তোলে।

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': [1 1 1 0]
features:
  'sex'               : [b'female' b'female' b'female' b'male']
  'age'               : [28. 42. 31. 65.]
  'n_siblings_spouses': [0 0 1 0]
  'parch'             : [0 0 1 0]
  'fare'              : [  7.8792 227.525   20.525   26.55  ]
  'class'             : [b'Third' b'First' b'Third' b'First']
  'deck'              : [b'unknown' b'unknown' b'unknown' b'E']
  'embark_town'       : [b'Queenstown' b'Cherbourg' b'Southampton' b'Southampton']
  'alone'             : [b'y' b'y' b'n' 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 0 0]
  'fare'              : [ 7.925  8.05  24.15   7.75 ]
  'class'             : [b'Third' b'Third' b'Third' b'Third']

এছাড়াও একটি নিম্ন-স্তরের experimental.CsvDataset sসিএসভিডাটাसेट ক্লাস রয়েছে যা সূক্ষ্ম দানাদার নিয়ন্ত্রণ সরবরাহ করে। এটি কলামের ধরণের অনুক্রম সমর্থন করে না। পরিবর্তে আপনাকে অবশ্যই প্রতিটি কলামের ধরণ উল্লেখ করতে হবে।

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 ফাইলের প্রতিটি লাইনটির প্রতিটি কলাম দেয়, এটি পছন্দসই নয় example উদাহরণস্বরূপ, যদি ফাইলটি শিরোনামের সাথে শুরু হয় যা উপেক্ষা করা উচিত, অথবা যদি ইনপুটটিতে কিছু কলাম প্রয়োজন না হয়। এই লাইনগুলি এবং ক্ষেত্রগুলি যথাক্রমে 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/roses/7316409504_7cf3707f8a_m.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/dandelion/1273326361_b90ea56d0d_m.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/sunflowers/1008566138_6927679c8a.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/tulips/8690791226_b1f015259f_n.jpg'
b'/home/kbuilder/.keras/datasets/flower_photos/tulips/17781940352_a45e4289a5.jpg'

tf.io.read_file ফাংশন ব্যবহার করে ডেটা পড়ুন এবং পথ (image, label) জোড়ায় ফিরে (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\x00\x00\x01\x00\x01\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 উপাদানগুলি ac 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.padded_batch ট্রান্সফর্মেশন আপনাকে এক বা একাধিক মাত্রা নির্দিষ্ট করে নির্দিষ্ট আকারে বিভিন্ন আকারের 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 দ্বারা Dataset.padded_batch ) বা ধ্রুবক দৈর্ঘ্য হতে পারে। প্যাডিং মানটি ওভাররাইড করাও সম্ভব, যা 0 এ ডিফল্ট হয়।

প্রশিক্ষণ কর্মপ্রবাহ

একাধিক যুগের প্রক্রিয়াজাতকরণ

tf.data API একই ডেটার একাধিক পর্বগুলি প্রক্রিয়া করার জন্য দুটি প্রধান উপায় সরবরাহ করে।

একাধিক Dataset.repeat() ডেটাসেটের মাধ্যমে পুনরাবৃত্তি করার সহজ উপায় 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.repeat রূপান্তরটি একটি যুগের শেষ এবং পরবর্তী যুগের সূচনা না করেই তার যুক্তিগুলিকে Dataset.repeat । এ কারণে Dataset.batch পরে একটি Dataset.batch প্রয়োগ করা হয়েছে Dataset.repeat ব্যাচগুলি Dataset.repeat করবে যা যুগের সীমানাগুলিকে বিস্তৃত করে:

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

পিএনজি

আপনার যদি স্পষ্ট যুগের বিচ্ছেদ প্রয়োজন হয় তবে পুনরাবৃত্তির আগে Dataset.batch :

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

plot_batch_sizes(titanic_batches)

পিএনজি

আপনি যদি প্রতিটি যুগের শেষে একটি পছন্দসই গণনা (উদাহরণস্বরূপ পরিসংখ্যান সংগ্রহ করা) করতে চান তবে প্রতিটি যুগের উপর ডেটাসেট পুনরাবৃত্তি পুনরায় আরম্ভ করা সহজ:

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 এর বেশি buffer_size কোনও উপাদান থাকে না।

n,line_batch = next(iter(dataset))
print(n.numpy())
[ 25  41  71  50  12  98  83   3  22  62  10  66  30  81 100  44   6  65
 113   1]

সঙ্গে Dataset.batch অর্ডার আপেক্ষিক Dataset.repeat বিষয়।

Dataset.shuffle কোনও যুগের শেষের সিগন্যাল দেয় না যতক্ষণ না 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:

[362 613 575 338 606 504 517 386 592 505]
[627 347 622 496 500 625 509 579 489 555]
[619 617 482 550 387 581 477 431]
[ 98  25  87  73  78  19  40  64  34 100]
[ 29 107  70   2   8  49  13  63  89  77]
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 0x7f2f6c1fcf28>

পিএনজি

তবে কোনও রদবদলের আগে একটি পুনরাবৃত্তি যুগের সীমানা একসাথে মিশে:

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:

[581 620 370  16   8 585 611 567  29 595]
[452  13 602 436 592 234 530 528   7  31]
[564 377 357  37 623  24 554 418 522   6]
[536  20  11 566 464  32 605 540 449  49]
[ 54 482  42  21  47 579  65 627 598  91]
[546 501  48  52 516  66 519 573   4  59]
[608  68  62 324  69   9 531 447 577  90]
[507   5  60  45 410  71  78  55  44 428]
[ 58 426 601 596  70  97  99 624  89  79]
[545 497  85 108 111 105  57  12  83  33]
[106 613  14 523  30  81  41  18 500 129]
[459  17   2 618 128 621  84  25 332  40]
[ 50  46 134 524  63 119 126 617 121  61]
[513 131 305  91  93 130 122  15 117 118]
[133 593 147 140 158  35 146  88 110  43]
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 0x7f2f6c286a58>

পিএনজি

প্রাক তথ্য প্রক্রিয়াকরণ

Dataset.map(f) রূপান্তর একটি প্রদত্ত ফাংশন প্রয়োগের দ্বারা একটি নতুন ডেটা সেটটি উত্পাদন করে f ইনপুট ডেটা সেটটি প্রতিটি উপাদানে। এটি map() ফাংশনের উপর ভিত্তি করে যা সাধারণত কার্যকরী প্রোগ্রামিং ভাষাগুলিতে তালিকাগুলিতে (এবং অন্যান্য কাঠামো) প্রয়োগ হয়। ফাংশন f লাগে tf.Tensor বস্তু যে ইনপুট একটি একক উপাদান প্রতিনিধিত্ব, এবং ফেরৎ tf.Tensor যে বস্তু নতুন ডেটাসেটের মধ্যে একটি একক উপাদান প্রতিনিধিত্ব করবে। এর প্রয়োগটি একটি উপাদানকে অন্যটিতে রূপান্তর করতে স্ট্যান্ডার্ড টেনসরফ্লো অপারেশন ব্যবহার করে।

এই বিভাগে 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)

পিএনজি

এটি ডেটাসেটের উপরে মানচিত্র করুন।

images_ds = list_ds.map(parse_image)

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

পিএনজি

পিএনজি

যথেচ্ছ পাইথন যুক্তি প্রয়োগ করা

পারফরম্যান্স কারণে, যখনই সম্ভব আপনার ডেটা প্রি-প্রসেসিংয়ের জন্য টেনসরফ্লো অপারেশনগুলি ব্যবহার করুন। তবে আপনার ইনপুট ডেটা পার্স করার সময় কখনও কখনও বাহ্যিক পাইথন লাইব্রেরি কল করা কার্যকর হয় call আপনি Dataset.map() রূপান্তরকরণে tf.py_function() অপারেশন ব্যবহার করতে পারেন।

উদাহরণস্বরূপ, আপনি যদি এলোমেলো রোটেশন প্রয়োগ করতে চান তবে tf.image মডিউলে কেবল tf.image.rot90 যা চিত্র বৃদ্ধির জন্য খুব কার্যকর নয় 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).

পিএনজি

এই ফাংশনটি 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).

পিএনজি

পিএনজি

tf.Example প্রোটোকল বাফার বার্তা পার্সিং

অনেক ইনপুট পাইপলাইনগুলি tf.train.Example এক্সট্রা প্রোটোকল বাফার বার্তা একটি টিএফআরকার্ড ফর্ম্যাট থেকে বের করে। প্রতিটি 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])

পিএনজি

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 = 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 ব্যবহার করে

Dataset.batch কাজগুলি ব্যবহার করার সময়, এমন পরিস্থিতি রয়েছে যেখানে আপনার আরও সূক্ষ্ম নিয়ন্ত্রণের প্রয়োজন হতে পারে। Dataset.window পদ্ধতি সম্পূর্ণ নিয়ন্ত্রণ দেয়, কিন্তু কিছু যত্ন প্রয়োজন হয়: এটি একটি ফেরৎ Dataset এর Datasets । বিশদগুলির জন্য ডেটাসেট কাঠামো দেখুন।

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=' ')
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 আর্গুমেন্ট প্রতিটি উইন্ডোটির উপরে কতটা 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 [==============================] - 2s 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.9951 0.0049]

ভারসাম্যহীন ডেটাসেটের সাথে প্রশিক্ষণের একটি সাধারণ পদ্ধতির মধ্যে ভারসাম্য বজায় রাখা। tf.data কয়েকটি পদ্ধতি রয়েছে যা এই কর্মপ্রবাহকে সক্ষম করে:

ডেটাসেটের নমুনা

একটি ডেটাসেট sample_from_datasets জন্য একটি পদ্ধতির sample_from_datasets ব্যবহার করা। আপনার আরও আলাদাdata.Dataset এটি আরও প্রযোজ্য। প্রতিটি শ্রেণীর জন্য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())
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 1 0 0 1 1 1 1 1 0]
[0 0 0 0 1 1 0 0 0 1]
[1 0 1 1 1 1 0 0 1 1]
[1 1 1 0 0 0 1 0 1 0]
[1 1 1 0 0 0 0 1 1 0]
[1 0 1 0 1 0 0 1 0 1]
[1 1 0 0 1 1 1 1 1 0]
[1 1 0 1 1 0 1 1 1 0]
[0 0 0 1 0 1 1 1 0 1]
[0 1 1 1 0 1 1 0 1 1]

প্রত্যাখ্যান পুনরায় মডেলিং

উপরোক্ত 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 কেবল এই লেবেলগুলি ফিরিয়ে class_func হবে:

def class_func(features, label):
  return label

পুনরায় মডেলারের জন্য একটি লক্ষ্য বিতরণ এবং optionচ্ছিকভাবে একটি প্রাথমিক বিতরণ অনুমান প্রয়োজন:

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

রিস্যাম্পলারটি পৃথক উদাহরণগুলির সাথে কাজ করে, তাই আপনাকে unbatch প্রয়োগ করার আগে অবশ্যই 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:

রিস্যাম্পলার রিটার্ন 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 1 1 1 1 1 0 0 0 1]
[0 0 1 0 1 0 0 1 0 1]
[0 1 1 0 0 0 0 0 1 0]
[1 1 0 0 0 0 1 0 0 0]
[1 1 0 0 0 0 1 0 0 1]
[1 1 0 1 0 1 1 1 0 1]
[1 1 0 1 0 0 1 1 1 1]
[0 0 1 0 0 1 1 1 0 0]
[1 1 0 0 0 0 0 0 0 1]
[1 0 1 0 0 0 1 1 0 0]

Iterator চেকপয়েন্টিং

টেনসরফ্লো চেকপয়েন্টগুলি গ্রহণে সমর্থন করে যাতে আপনার প্রশিক্ষণ প্রক্রিয়াটি পুনরায় চালু হলে এটির বেশিরভাগ অগ্রগতি পুনরুদ্ধার করতে সর্বশেষতম চৌকিটিকে পুনরুদ্ধার করতে পারে। মডেল ভেরিয়েবলগুলিকে চেকপয়েন্টিং করা ছাড়াও আপনি ডেটাসেট পুনরুক্তকারীর অগ্রগতিও পরীক্ষা করতে পারেন। আপনার যদি একটি বড় ডেটাসেট থাকে এবং প্রতিটি পুনরায় আরম্ভের সময় থেকে ডেটাसेट শুরু করতে না চান তবে এটি কার্যকর হতে পারে। উল্লেখ্য তবে পুনরুক্তিকারীর চেকপয়েন্ট বড় হতে পারে যে, যেমন রূপান্তরের যেহেতু shuffle এবং prefetch পুনরুক্তিকারীর মধ্যে বাফার উপলব্ধ উপাদানের প্রয়োজন।

আপনার tf.train.Checkpoint একটি চেকপয়েন্টে অন্তর্ভুক্ত করতে, পুনরুক্তিটি 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.keras ব্যবহার করে tf.data

tf.keras API মেশিন লার্নিং মডেলগুলি তৈরি এবং সম্পাদন করার অনেক দিককে সহজ করে tf.keras এর .fit() এবং .evaluate() এবং .predict() API গুলি ইনপুট হিসাবে .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'])

Model.fit এবং Model.evaluate জন্য প্রয়োজনীয় (feature, label) জোড়াগুলির একটি ডেটাসেট পাস করা:

model.fit(fmnist_train_ds, epochs=2)
Epoch 1/2
1875/1875 [==============================] - 4s 2ms/step - loss: 0.7832 - accuracy: 0.7360
Epoch 2/2
1875/1875 [==============================] - 3s 2ms/step - loss: 0.4691 - accuracy: 0.8378
<tensorflow.python.keras.callbacks.History at 0x7f2f2c60a4e0>

যদি আপনি একটি অসীম ডেটাসেট পাস করেন, উদাহরণস্বরূপ 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.3968 - accuracy: 0.8625
Epoch 2/2
20/20 [==============================] - 0s 2ms/step - loss: 0.4828 - accuracy: 0.8516
<tensorflow.python.keras.callbacks.History at 0x7f2f6c044b38>

মূল্যায়নের জন্য আপনি মূল্যায়নের পদক্ষেপের সংখ্যাটি পাস করতে পারেন:

loss, accuracy = model.evaluate(fmnist_train_ds)
print("Loss :", loss)
print("Accuracy :", accuracy)
1875/1875 [==============================] - 4s 2ms/step - loss: 0.4316 - accuracy: 0.8538
Loss : 0.4315564036369324
Accuracy : 0.853766679763794

দীর্ঘ ডেটাসেটের জন্য, মূল্যায়নের পদক্ষেপের সংখ্যা নির্ধারণ করুন:

loss, accuracy = model.evaluate(fmnist_train_ds.repeat(), steps=10)
print("Loss :", loss)
print("Accuracy :", accuracy)
10/10 [==============================] - 0s 2ms/step - loss: 0.5001 - accuracy: 0.8469
Loss : 0.500092625617981
Accuracy : 0.846875011920929

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)