Google I / O 18-20 मई को लौटता है! जगह आरक्षित करें और अपना शेड्यूल बनाएं अभी रजिस्टर करें
इस पेज का अनुवाद Cloud Translation API से किया गया है.
Switch to English

डेटा वृद्धि

TensorFlow.org पर देखें Google Colab में चलाएं GitHub पर स्रोत देखें नोटबुक डाउनलोड करें

अवलोकन

यह ट्यूटोरियल डेटा संवर्द्धन को प्रदर्शित करता है: बेतरतीब ढंग से (लेकिन यथार्थवादी) परिवर्तनों जैसे कि छवि के रोटेशन को लागू करके अपने प्रशिक्षण की विविधता बढ़ाने के लिए एक तकनीक। आप सीखेंगे कि दो तरीकों से डेटा संवर्द्धन कैसे लागू किया जाए। सबसे पहले, आप केर प्रीप्रोसेसिंग लेयर्स का उपयोग करेंगे। इसके बाद, आप tf.image का उपयोग tf.image

सेट अप

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds

from tensorflow.keras import layers

डेटासेट डाउनलोड करें

यह ट्यूटोरियल tf_flowers डेटासेट का उपयोग करता है। सुविधा के लिए, TensorFlow Datasets का उपयोग करके डेटासेट डाउनलोड करें। यदि आप डेटा आयात करने के अन्य तरीकों के बारे में सीखना चाहते हैं, तो लोड चित्र ट्यूटोरियल देखें।

(train_ds, val_ds, test_ds), metadata = tfds.load(
    'tf_flowers',
    split=['train[:80%]', 'train[80%:90%]', 'train[90%:]'],
    with_info=True,
    as_supervised=True,
)

फूलों के डाटासेट में पांच वर्ग होते हैं।

num_classes = metadata.features['label'].num_classes
print(num_classes)
5

आइए डेटासेट से एक छवि पुनर्प्राप्त करें और डेटा वृद्धि को प्रदर्शित करने के लिए इसका उपयोग करें।

get_label_name = metadata.features['label'].int2str

image, label = next(iter(train_ds))
_ = plt.imshow(image)
_ = plt.title(get_label_name(label))

पींग

केरस प्रीप्रोसेसिंग परतों का प्रयोग करें

आकार बदलना और आकार बदलना

आप अपनी छवियों को एक सुसंगत आकार में बदलने के लिए और पिक्सेल मानों को फिर से स्केल करने के लिए प्रीप्रोसेसिंग परतों का उपयोग कर सकते हैं।

IMG_SIZE = 180

resize_and_rescale = tf.keras.Sequential([
  layers.experimental.preprocessing.Resizing(IMG_SIZE, IMG_SIZE),
  layers.experimental.preprocessing.Rescaling(1./255)
])

आप इन परतों को एक छवि पर लागू करने का परिणाम देख सकते हैं।

result = resize_and_rescale(image)
_ = plt.imshow(result)

पीएनजी

आप सत्यापित कर सकते हैं कि पिक्सेल [0-1]

print("Min and max pixel values:", result.numpy().min(), result.numpy().max())
Min and max pixel values: 0.0 1.0

डेटा वृद्धि

आप डेटा वृद्धि के लिए प्रीप्रोसेसिंग परतों का भी उपयोग कर सकते हैं।

आइए कुछ प्रीप्रोसेसिंग परतें बनाएं और उन्हें एक ही छवि पर बार-बार लागू करें।

data_augmentation = tf.keras.Sequential([
  layers.experimental.preprocessing.RandomFlip("horizontal_and_vertical"),
  layers.experimental.preprocessing.RandomRotation(0.2),
])
# Add the image to a batch
image = tf.expand_dims(image, 0)
plt.figure(figsize=(10, 10))
for i in range(9):
  augmented_image = data_augmentation(image)
  ax = plt.subplot(3, 3, i + 1)
  plt.imshow(augmented_image[0])
  plt.axis("off")

पींग

वहाँ preprocessing की एक किस्म है परतों आप सहित डेटा वृद्धि के लिए उपयोग कर सकते हैं layers.RandomContrast , layers.RandomCrop , layers.RandomZoom , व अन्य।

प्रीप्रोसेसिंग परतों का उपयोग करने के लिए दो विकल्प

ऐसे दो तरीके हैं जिनसे आप इन प्रीप्रोसेसिंग परतों का उपयोग कर सकते हैं, महत्वपूर्ण ट्रेडऑफ़ के साथ।

विकल्प 1: प्रीप्रोसेसिंग परतों को अपने मॉडल का हिस्सा बनाएं

model = tf.keras.Sequential([
  resize_and_rescale,
  data_augmentation,
  layers.Conv2D(16, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  # Rest of your model
])
है

इस मामले में जागरूक होने के लिए दो महत्वपूर्ण बिंदु हैं:

  • डेटा संवर्द्धन आपके शेष भागों के साथ, और GPU त्वरण से लाभ के साथ, डिवाइस पर चलेगा।

  • जब आप model.save का उपयोग करके अपने मॉडल का निर्यात करते हैं, तो आपके बाकी मॉडल के साथ प्रीप्रोसेसिंग परतें बच जाएंगी। यदि आप बाद में इस मॉडल को तैनात करते हैं, तो यह स्वचालित रूप से छवियों को मानकीकृत करेगा (आपकी परतों के कॉन्फ़िगरेशन के अनुसार)। यह आपको उस लॉजिक सर्वर-साइड को फिर से लागू करने के प्रयास से बचा सकता है।

विकल्प 2: प्रीप्रोसेसिंग परतों को अपने डेटासेट में लागू करें

aug_ds = train_ds.map(
  lambda x, y: (resize_and_rescale(x, training=True), y))

इस दृष्टिकोण के साथ, आप का उपयोग Dataset.map एक डाटासेट बनाने के लिए है कि संवर्धित छवियों की पैदावार बैचों। इस मामले में:

  • डेटा वृद्धि CPU पर अतुल्यकालिक रूप से होगी, और गैर-अवरुद्ध है। आप डेटा पर प्रीप्रोसेसिंग के साथ GPU पर अपने मॉडल के प्रशिक्षण को ओवरलैप कर सकते हैं, नीचे दिखाए गए Dataset.prefetch का उपयोग करके।
  • इस मामले में prepreprocessing परतों मॉडल जब आप कॉल के साथ निर्यात नहीं की जाएंगी model.save । इसे सहेजने या सर्वर-साइड पर लागू करने से पहले आपको उन्हें अपने मॉडल में संलग्न करना होगा। प्रशिक्षण के बाद, आप निर्यात से पहले प्रीप्रोसेसिंग परतों को संलग्न कर सकते हैं।

आप छवि वर्गीकरण ट्यूटोरियल में पहले विकल्प का एक उदाहरण पा सकते हैं। आइए यहां दूसरा विकल्प प्रदर्शित करें।

प्रीप्रोसेसिंग परतों को डेटासेट पर लागू करें

आपके द्वारा ऊपर बनाई गई प्रीप्रोसेसिंग परतों के साथ ट्रेन, सत्यापन और परीक्षण डेटासेट को कॉन्फ़िगर करें। आप प्रदर्शन के लिए डेटासेट्स को भी कॉन्फ़िगर करेंगे, समानांतर रीड्स और बफ़र प्रीफ़ेटिंग का उपयोग करके डिस्क से बैचों को उपजाने के लिए I / I अवरुद्ध हो जाएगा। आप tf.data API गाइड के साथ बेहतर प्रदर्शन में अधिक डेटासेट प्रदर्शन सीख सकते हैं।

batch_size = 32
AUTOTUNE = tf.data.AUTOTUNE

def prepare(ds, shuffle=False, augment=False):
  # Resize and rescale all datasets
  ds = ds.map(lambda x, y: (resize_and_rescale(x), y), 
              num_parallel_calls=AUTOTUNE)

  if shuffle:
    ds = ds.shuffle(1000)

  # Batch all datasets
  ds = ds.batch(batch_size)

  # Use data augmentation only on the training set
  if augment:
    ds = ds.map(lambda x, y: (data_augmentation(x, training=True), y), 
                num_parallel_calls=AUTOTUNE)

  # Use buffered prefecting on all datasets
  return ds.prefetch(buffer_size=AUTOTUNE)
train_ds = prepare(train_ds, shuffle=True, augment=True)
val_ds = prepare(val_ds)
test_ds = prepare(test_ds)

एक मॉडल को प्रशिक्षित करें

पूर्णता के लिए, अब आप इन डेटासेट का उपयोग करके एक मॉडल को प्रशिक्षित करेंगे। इस मॉडल को सटीकता के लिए ट्यून नहीं किया गया है (लक्ष्य आपको यांत्रिकी दिखाना है)।

model = tf.keras.Sequential([
  layers.Conv2D(16, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(32, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(64, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Flatten(),
  layers.Dense(128, activation='relu'),
  layers.Dense(num_classes)
])
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])
epochs=5
history = model.fit(
  train_ds,
  validation_data=val_ds,
  epochs=epochs
)
Epoch 1/5
92/92 [==============================] - 18s 73ms/step - loss: 1.5561 - accuracy: 0.3378 - val_loss: 1.1237 - val_accuracy: 0.5313
Epoch 2/5
92/92 [==============================] - 3s 26ms/step - loss: 1.0865 - accuracy: 0.5535 - val_loss: 1.0506 - val_accuracy: 0.5749
Epoch 3/5
92/92 [==============================] - 3s 25ms/step - loss: 1.0076 - accuracy: 0.5965 - val_loss: 1.0201 - val_accuracy: 0.6022
Epoch 4/5
92/92 [==============================] - 3s 25ms/step - loss: 0.9165 - accuracy: 0.6283 - val_loss: 0.8957 - val_accuracy: 0.6540
Epoch 5/5
92/92 [==============================] - 3s 26ms/step - loss: 0.8720 - accuracy: 0.6601 - val_loss: 0.8639 - val_accuracy: 0.6567
loss, acc = model.evaluate(test_ds)
print("Accuracy", acc)
12/12 [==============================] - 1s 12ms/step - loss: 0.8312 - accuracy: 0.6431
Accuracy 0.6430517435073853

कस्टम डेटा वृद्धि

आप कस्टम डेटा वृद्धि की परतें भी बना सकते हैं। यह ट्यूटोरियल ऐसा करने के दो तरीके दिखाता है। सबसे पहले, आप एक लेयर layers.Lambdalayers.Lambda लेयर। संक्षिप्त कोड लिखने का यह एक अच्छा तरीका है। इसके बाद, आप सबक्लासिंग के माध्यम से एक नई लेयर लिखेंगे, जो आपको अधिक नियंत्रण प्रदान करती है। दोनों परतें कुछ संभावना के अनुसार, एक छवि में रंगों को बेतरतीब ढंग से उलट देंगी।

def random_invert_img(x, p=0.5):
  if  tf.random.uniform([]) < p:
    x = (255-x)
  else:
    x
  return x
def random_invert(factor=0.5):
  return layers.Lambda(lambda x: random_invert_img(x, factor))

random_invert = random_invert()
plt.figure(figsize=(10, 10))
for i in range(9):
  augmented_image = random_invert(image)
  ax = plt.subplot(3, 3, i + 1)
  plt.imshow(augmented_image[0].numpy().astype("uint8"))
  plt.axis("off")

पीएनजी

अगला, उप-वर्ग द्वारा एक कस्टम लेयर लागू करें।

class RandomInvert(layers.Layer):
  def __init__(self, factor=0.5, **kwargs):
    super().__init__(**kwargs)
    self.factor = factor

  def call(self, x):
    return random_invert_img(x)
_ = plt.imshow(RandomInvert()(image)[0])

पीएनजी

इन दोनों परतों का उपयोग उपरोक्त विकल्पों 1 और 2 में वर्णित किया जा सकता है।

Tf.image का उपयोग करना

उपरोक्त layers.preprocessinglayers.preprocessing उपयोगिताओं सुविधाजनक हैं। बेहतर नियंत्रण के लिए, आप tf.data और tf.image का उपयोग करके अपनी खुद की डेटा वृद्धि पाइपलाइन या परतें लिख सकते हैं। तुम भी TensorFlow Addons छवि की जाँच करना चाहते हो सकता है : संचालन और TensorFlow I / O: रंग अंतरिक्ष रूपांतरण

चूंकि फूल डेटासेट पहले से डेटा वृद्धि के साथ कॉन्फ़िगर किया गया था, आइए इसे नए सिरे से शुरू करने के लिए फिर से शुरू करें।

(train_ds, val_ds, test_ds), metadata = tfds.load(
    'tf_flowers',
    split=['train[:80%]', 'train[80%:90%]', 'train[90%:]'],
    with_info=True,
    as_supervised=True,
)

साथ काम करने के लिए एक छवि प्राप्त करें।

image, label = next(iter(train_ds))
_ = plt.imshow(image)
_ = plt.title(get_label_name(label))

पींग

आइए, मूल और संवर्धित छवियों की कल्पना करने और उनकी तुलना करने के लिए निम्नलिखित फ़ंक्शन का उपयोग करें।

def visualize(original, augmented):
  fig = plt.figure()
  plt.subplot(1,2,1)
  plt.title('Original image')
  plt.imshow(original)

  plt.subplot(1,2,2)
  plt.title('Augmented image')
  plt.imshow(augmented)

डेटा वृद्धि

छवि को फ़्लिप करना

छवि को लंबवत या क्षैतिज रूप से पलटें।

flipped = tf.image.flip_left_right(image)
visualize(image, flipped)

पींग

छवि को ग्रेस्केल करें

ग्रेस्केल एक छवि।

grayscaled = tf.image.rgb_to_grayscale(image)
visualize(image, tf.squeeze(grayscaled))
_ = plt.colorbar()

पींग

छवि को संतृप्त करें

संतृप्ति कारक प्रदान करके एक छवि को संतृप्त करें।

05d8989650

पींग

छवि चमक बदलें

चमक कारक प्रदान करके छवि की चमक बदलें।

bright = tf.image.adjust_brightness(image, 0.4)
visualize(image, bright)

पीएनजी

केंद्र छवि को क्रॉप करता है

अपनी इच्छा के अनुसार छवि से केंद्र तक छवि को काटें।

cropped = tf.image.central_crop(image, central_fraction=0.5)
visualize(image,cropped)

पींग

छवि घुमाएँ

छवि को 90 डिग्री घुमाएँ।

rotated = tf.image.rot90(image)
visualize(image, rotated)

पींग

यादृच्छिक परिवर्तन

छवियों में यादृच्छिक परिवर्तन लागू करने से डेटासेट को सामान्य बनाने और विस्तार करने में मदद मिल सकती है। वर्तमान tf.image API 8 ऐसे यादृच्छिक छवि संचालन (ऑप्स) प्रदान करता है:

ये यादृच्छिक छवि ऑप्स पूरी तरह से कार्यात्मक हैं: ouput केवल इनपुट पर निर्भर करता है। यह उन्हें उच्च प्रदर्शन, नियतात्मक इनपुट पाइपलाइनों में उपयोग करने के लिए सरल बनाता है। उन्हें प्रत्येक चरण में एक seed मूल्य इनपुट की आवश्यकता होती है। एक ही seed को देखते हुए, वे कितनी बार बुलाए जाने से स्वतंत्र होकर वही परिणाम लौटाते हैं।

निम्नलिखित अनुभागों में, हम करेंगे:

  1. एक छवि को बदलने के लिए यादृच्छिक छवि संचालन का उपयोग करने के उदाहरणों पर जाएं, और
  2. एक प्रशिक्षण डाटासेट के लिए यादृच्छिक परिवर्तनों को लागू करने का तरीका प्रदर्शित करें।

बेतरतीब ढंग से छवि चमक बदलें

बेतरतीब ढंग से चमक कारक और seed प्रदान करके image की चमक को बदलें। चमक कारक को [-max_delta, max_delta) श्रेणी में यादृच्छिक रूप से चुना जाता है और दिए गए seed से जुड़ा होता है।

for i in range(3):
  seed = (i, 0)  # tuple of size (2,)
  stateless_random_brightness = tf.image.stateless_random_brightness(
      image, max_delta=0.95, seed=seed)
  visualize(image, stateless_random_brightness)

पींग

पींग

पींग

बेतरतीब ढंग से छवि विपरीत बदलें

कंट्रास्ट रेंज और seed प्रदान करके image के कंट्रास्ट को बेतरतीब ढंग से बदलें। कंट्रास्ट रेंज को अंतराल [lower, upper] में यादृच्छिक रूप से चुना जाता है और दिए गए seed से जुड़ा होता है।

for i in range(3):
  seed = (i, 0)  # tuple of size (2,)
  stateless_random_contrast = tf.image.stateless_random_contrast(
      image, lower=0.1, upper=0.9, seed=seed)
  visualize(image, stateless_random_contrast)

पीएनजी

पीएनजी

पीएनजी

बेतरतीब ढंग से एक छवि फसल

लक्ष्य size और seed प्रदान करके बेतरतीब ढंग से फसल की image । जो हिस्सा image से बाहर हो जाता है, वह बेतरतीब ढंग से चुनी गई अलमारी में होता है और दिए गए seed से जुड़ा होता है।

for i in range(3):
  seed = (i, 0)  # tuple of size (2,)
  stateless_random_crop = tf.image.stateless_random_crop(
      image, size=[210, 300, 3], seed=seed)
  visualize(image, stateless_random_crop)

पींग

पीएनजी

पीएनजी

डेटासेट में वृद्धि लागू करें

आइए पहले छवि डेटासेट को फिर से डाउनलोड करें यदि वे पिछले अनुभागों में संशोधित हैं।

(train_datasets, val_ds, test_ds), metadata = tfds.load(
    'tf_flowers',
    split=['train[:80%]', 'train[80%:90%]', 'train[90%:]'],
    with_info=True,
    as_supervised=True,
)

आइए छवियों को आकार और आकार बदलने के लिए एक उपयोगिता फ़ंक्शन को परिभाषित करें। इस फ़ंक्शन का उपयोग डेटासेट में छवियों के आकार और पैमाने को एकीकृत करने में किया जाएगा:

def resize_and_rescale(image, label):
  image = tf.cast(image, tf.float32)
  image = tf.image.resize(image, [IMG_SIZE, IMG_SIZE])
  image = (image / 255.0)
  return image, label

आइए augment फ़ंक्शन को भी परिभाषित करें जो छवियों में यादृच्छिक परिवर्तनों को लागू कर सकता है। इस फ़ंक्शन का उपयोग अगले चरण में डेटासेट पर किया जाएगा।

def augment(image_label, seed):
  image, label = image_label
  image, label = resize_and_rescale(image, label)
  image = tf.image.resize_with_crop_or_pad(image, IMG_SIZE + 6, IMG_SIZE + 6)
  # Make a new seed
  new_seed = tf.random.experimental.stateless_split(seed, num=1)[0, :]
  # Random crop back to the original size
  image = tf.image.stateless_random_crop(
      image, size=[IMG_SIZE, IMG_SIZE, 3], seed=seed)
  # Random brightness
  image = tf.image.stateless_random_brightness(
      image, max_delta=0.5, seed=new_seed)
  image = tf.clip_by_value(image, 0, 1)
  return image, label

विकल्प 1: tf.data.experimental.Counter() का उपयोग करना

एक tf.data.experimental.Counter() ऑब्जेक्ट बनाएं (चलिए इसे counter कहते counter ) और डेटासेट को (counter, counter) साथ zip करें। यह सुनिश्चित करेगा कि डेटासेट में प्रत्येक छवि counter आधार पर एक अद्वितीय मूल्य (आकार (2,) ) से जुड़ी हो (2,) जो बाद में यादृच्छिक परिवर्तनों के लिए seed मूल्य के रूप में augment समारोह में पारित हो सकती है।

# Create counter and zip together with train dataset
counter = tf.data.experimental.Counter()
train_ds = tf.data.Dataset.zip((train_datasets, (counter, counter)))

प्रशिक्षण डाटासेट के लिए augment समारोह का नक्शा।

train_ds = (
    train_ds
    .shuffle(1000)
    .map(augment, num_parallel_calls=AUTOTUNE)
    .batch(batch_size)
    .prefetch(AUTOTUNE)
)
val_ds = (
    val_ds
    .map(resize_and_rescale, num_parallel_calls=AUTOTUNE)
    .batch(batch_size)
    .prefetch(AUTOTUNE)
)
test_ds = (
    test_ds
    .map(resize_and_rescale, num_parallel_calls=AUTOTUNE)
    .batch(batch_size)
    .prefetch(AUTOTUNE)
)

विकल्प 2: tf.random.Generator का उपयोग करना

एक intial seed मूल्य के साथ एक tf.random.Generator ऑब्जेक्ट बनाएँ। एक ही जनरेटर ऑब्जेक्ट पर make_seeds फ़ंक्शन को कॉल make_seeds हमेशा एक नया, अद्वितीय seed मान देता है। एक आवरण फ़ंक्शन को परिभाषित करें जो 1) कॉल make_seeds फ़ंक्शन और वह 2) यादृच्छिक परिवर्तनों के लिए augment समारोह में नए उत्पन्न seed मान को पारित करता है।

# Create a generator
rng = tf.random.Generator.from_seed(123, alg='philox')
# A wrapper function for updating seeds
def f(x, y):
  seed = rng.make_seeds(2)[0]
  image, label = augment((x, y), seed)
  return image, label

मानचित्र आवरण समारोह f प्रशिक्षण डाटासेट करने के लिए।

train_ds = (
    train_datasets
    .shuffle(1000)
    .map(f, num_parallel_calls=AUTOTUNE)
    .batch(batch_size)
    .prefetch(AUTOTUNE)
)
val_ds = (
    val_ds
    .map(resize_and_rescale, num_parallel_calls=AUTOTUNE)
    .batch(batch_size)
    .prefetch(AUTOTUNE)
)
test_ds = (
    test_ds
    .map(resize_and_rescale, num_parallel_calls=AUTOTUNE)
    .batch(batch_size)
    .prefetch(AUTOTUNE)
)

इन डेटासेट का उपयोग किसी मॉडल को प्रशिक्षित करने के लिए किया जा सकता है जैसा कि पहले दिखाया गया है।

अगला कदम

इस ट्यूटोरियल ने tf.image प्रीप्रोसेसिंग लेयर्स और tf.image का उपयोग करके डेटा वृद्धि का प्रदर्शन किया। अपने मॉडल के अंदर प्रीप्रोसेसिंग परतों को शामिल करने का तरीका जानने के लिए, छवि वर्गीकरण ट्यूटोरियल देखें। आपको यह जानने में भी दिलचस्पी हो सकती है कि प्रीप्रोसेसिंग परतें आपको पाठ को वर्गीकृत करने में कैसे मदद कर सकती हैं, जैसा कि मूल पाठ वर्गीकरण ट्यूटोरियल में दिखाया गया है । आप इस गाइड में tf.data बारे में अधिक जान सकते हैं, और आप यहां प्रदर्शन के लिए अपनी इनपुट पाइपलाइनों को कॉन्फ़िगर करना सीख सकते हैं।