کمک به حفاظت از دیواره بزرگ مرجانی با TensorFlow در Kaggle اضافه کردن چالش

افزایش داده ها

مشاهده در TensorFlow.org در Google Colab اجرا شود مشاهده منبع در GitHub دانلود دفترچه یادداشت

بررسی اجمالی

این آموزش تقویت داده ها را نشان می دهد: تکنیکی برای افزایش تنوع مجموعه آموزشی شما با اعمال تبدیل های تصادفی (اما واقعی)، مانند چرخش تصویر.

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

برپایی

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 مجموعه داده . اگر شما می خواهم در مورد راه های دیگر از وارد کردن داده ها را یاد بگیرند، چک کردن تصاویر بار آموزش.

(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))
2021-10-22 01:22:18.891161: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.

png

از لایه های پیش پردازش Keras استفاده کنید

تغییر اندازه و تغییر مقیاس

شما می توانید Keras پیش پردازش لایه برای تغییر اندازه تصاویر خود را به یک شکل سازگار (با استفاده از tf.keras.layers.Resizing ) به مقدار پیکسل تغییر اندازه (با و tf.keras.layers.Rescaling ).

IMG_SIZE = 180

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

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

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

png

بررسی کنید که پیکسل در می [0, 1] وسیعی:

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

افزایش داده ها

شما می توانید Keras پیش پردازش لایه های برای تقویت داده و همچنین، از جمله استفاده از tf.keras.layers.RandomFlip و tf.keras.layers.RandomRotation .

بیایید چند لایه پیش پردازش ایجاد کنیم و آنها را به طور مکرر روی همان تصویر اعمال کنیم.

data_augmentation = tf.keras.Sequential([
  layers.RandomFlip("horizontal_and_vertical"),
  layers.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")

png

انواع مختلفی از لایه های از پیش پردازش شما می توانید برای تقویت داده ها از جمله استفاده از وجود دارد tf.keras.layers.RandomContrast ، tf.keras.layers.RandomCrop ، tf.keras.layers.RandomZoom ، و دیگران.

دو گزینه برای استفاده از لایه های پیش پردازش Keras

دو راه برای استفاده از این لایه‌های پیش‌پردازش، با معاوضه‌های مهم وجود دارد.

گزینه 1: لایه های پیش پردازش را بخشی از مدل خود کنید

model = tf.keras.Sequential([
  # Add the preprocessing layers you created earlier.
  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 زیر نشان داده شده.
  • در این مورد لایه های از پیش پردازش خواهد شد با مدل که با شما تماس صادر نمی Model.save . باید آنها را قبل از ذخیره کردن آن به مدل خود وصل کنید یا در سمت سرور مجدداً اجرا کنید. پس از آموزش، می توانید لایه های پیش پردازش را قبل از صادرات وصل کنید.

شما می توانید یک نمونه از این گزینه برای اولین بار در پیدا طبقه بندی تصویر آموزش. بیایید گزینه دوم را در اینجا نشان دهیم.

لایه های پیش پردازش را روی مجموعه داده ها اعمال کنید

مجموعه داده‌های آموزش، اعتبارسنجی و آزمایش را با لایه‌های پیش‌پردازش Keras که قبلاً ایجاد کرده‌اید، پیکربندی کنید. همچنین مجموعه داده‌ها را برای عملکرد پیکربندی می‌کنید، با استفاده از خواندن موازی و واکشی اولیه بافر برای تولید دسته‌هایی از دیسک بدون اینکه ورودی/خروجی مسدود شود. (بدانید عملکرد مجموعه داده در عملکرد بهتر با API tf.data راهنمای.)

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

یک مدل تربیت کنید

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

متوالی مدل شامل سه بلوک پیچیدگی ( tf.keras.layers.Conv2D ) با یک لایه ادغام حداکثر ( tf.keras.layers.MaxPooling2D ) در هر یک از آنها. یک لایه به طور کامل متصل (وجود دارد tf.keras.layers.Dense ) با 128 واحد در بالای آن است که توسط یک تابع فعال ReLU (فعال 'relu' ). این مدل برای دقت تنظیم نشده است (هدف این است که مکانیک را به شما نشان دهیم).

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

را انتخاب کنید tf.keras.optimizers.Adam بهینه ساز و tf.keras.losses.SparseCategoricalCrossentropy تابع از دست دادن. برای مشاهده آموزش و دقت اعتبار سنجی برای هر دوره آموزشی، تصویب metrics استدلال به Model.compile .

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 [==============================] - 30s 190ms/step - loss: 1.3237 - accuracy: 0.4183 - val_loss: 1.0881 - val_accuracy: 0.5668
Epoch 2/5
92/92 [==============================] - 3s 26ms/step - loss: 1.0428 - accuracy: 0.5841 - val_loss: 1.0630 - val_accuracy: 0.5886
Epoch 3/5
92/92 [==============================] - 3s 26ms/step - loss: 0.9704 - accuracy: 0.6202 - val_loss: 1.0317 - val_accuracy: 0.6076
Epoch 4/5
92/92 [==============================] - 3s 26ms/step - loss: 0.9190 - accuracy: 0.6356 - val_loss: 0.8869 - val_accuracy: 0.6621
Epoch 5/5
92/92 [==============================] - 3s 26ms/step - loss: 0.8766 - accuracy: 0.6594 - val_loss: 0.8312 - val_accuracy: 0.6730
loss, acc = model.evaluate(test_ds)
print("Accuracy", acc)
12/12 [==============================] - 3s 32ms/step - loss: 0.8001 - accuracy: 0.7030
Accuracy 0.7029972672462463

افزایش داده های سفارشی

شما همچنین می توانید لایه های افزایش داده های سفارشی ایجاد کنید.

این بخش از آموزش دو روش برای انجام این کار را نشان می دهد:

  • نخست، شما یک ایجاد tf.keras.layers.Lambda لایه. این یک راه خوب برای نوشتن کد مختصر است.
  • بعد، شما یک لایه جدید از طریق ارسال subclassing ، که به شما می دهد کنترل بیشتر است.

هر دو لایه به طور تصادفی رنگ های یک تصویر را بر اساس برخی احتمالات معکوس می کنند.

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

png

بعد، اجرای یک لایه سفارشی توسط subclassing :

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

png

هر دوی این لایه ها را می توان همانطور که در گزینه های 1 و 2 در بالا توضیح داده شد استفاده کرد.

با استفاده از tf.image

ابزارهای پیش پردازش Keras فوق راحت هستند. اما، برای کنترل بهتر، شما می توانید خود خطوط لوله تقویت داده و یا لایه با استفاده از خود را ارسال tf.data و tf.image . (شما همچنین ممکن است بخواهید برای بررسی از TensorFlow اضافه تصویر: عملیات و 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))
2021-10-22 01:23:14.609482: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.

png

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

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)

افزایش داده ها

یک تصویر را ورق بزنید

تلنگر یک تصویر صورت عمودی یا افقی با tf.image.flip_left_right :

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

png

یک تصویر در مقیاس خاکستری

شما می توانید یک تصویر را با سیاه و سفید tf.image.rgb_to_grayscale :

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

png

یک تصویر را اشباع کنید

اشباع یک تصویر با tf.image.adjust_saturation با ارائه یک فاکتور اشباع:

saturated = tf.image.adjust_saturation(image, 3)
visualize(image, saturated)

png

تغییر روشنایی تصویر

تغییر روشنایی تصویر با tf.image.adjust_brightness با ارائه یک عامل روشنایی:

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

png

یک تصویر را در مرکز برش دهید

برش تصویر از مرکز تا قسمت تصویر مورد نظر شما با استفاده از tf.image.central_crop :

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

png

یک تصویر را بچرخانید

چرخش تصویر به اندازه 90 درجه با tf.image.rot90 :

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

png

تبدیل های تصادفی

اعمال تبدیل‌های تصادفی به تصاویر می‌تواند به تعمیم و گسترش مجموعه داده کمک کند. در حال حاضر tf.image API فراهم می کند هشت عملیات از جمله تصویر تصادفی (OPS):

این عملیات تصویر تصادفی کاملاً کاربردی هستند: خروجی فقط به ورودی بستگی دارد. این امر استفاده از آنها را در خطوط لوله ورودی با کارایی بالا و قطعی ساده می کند. آنها نیاز به یک seed ارزش تواند ورودی هر مرحله. با توجه به همان seed ، آنها بازگشت به نتایج مشابهی را مستقل از چند بار آنها را به نام.

در بخش های زیر خواهید دید:

  1. نمونه هایی از استفاده از عملیات تصویر تصادفی برای تبدیل یک تصویر را مرور کنید. و
  2. نحوه اعمال تبدیل های تصادفی به مجموعه داده آموزشی را نشان دهید.

تغییر تصادفی روشنایی تصویر

به صورت تصادفی روشنایی تغییر image با استفاده از tf.image.stateless_random_brightness با ارائه یک عامل روشنایی و seed . عامل روشنایی است به طور تصادفی در محدوده انتخاب [-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)

png

png

png

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

به صورت تصادفی کنتراست تغییر image با استفاده از tf.image.stateless_random_contrast با ارائه طیف کنتراست و seed . محدوده کنتراست به طور تصادفی در فاصله زمانی انتخاب شده [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)

png

png

png

برش تصادفی یک تصویر

به صورت تصادفی برش image با استفاده از tf.image.stateless_random_crop با ارائه هدف size و seed . بخش می شود که از نابود و لگدمال 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)

png

png

png

اعمال افزایش به یک مجموعه داده

بیایید ابتدا مجموعه داده های تصویر را دوباره دانلود کنیم، در صورتی که در بخش های قبلی اصلاح شده اند.

(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 ) و Dataset.zip مجموعه داده با (counter, counter) . این اطمینان خواهد داد که هر تصویر در مجموعه داده می شود با ارزش منحصر به فرد (شکل مرتبط (2,) ) بر اساس counter که بعدها می تواند از به تصویب augment تابع به عنوان seed ارزش برای تحولات تصادفی.

# Create a `Counter` object and `Dataset.zip` it together with the trainining set.
counter = tf.data.experimental.Counter()
train_ds = tf.data.Dataset.zip((train_datasets, (counter, counter)))
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/data/experimental/ops/counter.py:66: scan (from tensorflow.python.data.experimental.ops.scan_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.data.Dataset.scan(...) instead
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/data/experimental/ops/counter.py:66: scan (from tensorflow.python.data.experimental.ops.scan_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.data.Dataset.scan(...) instead

نقشه 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

  • درست tf.random.Generator شی با اولیه seed ارزش. فراخوانی make_seeds تابع در همان شی ژنراتور همیشه جدید، منحصر به فرد باز می گردد seed ارزش.
  • تعریف تابع لفاف بسته بندی است که: 1) خواستار make_seeds عمل کند؛ و 2) به تازگی تولید می گذرد seed ارزش به augment عملکرد برای تحولات تصادفی.
# Create a generator.
rng = tf.random.Generator.from_seed(123, alg='philox')
# Create 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 به مجموعه داده آموزش، و resize_and_rescale تابع به اعتبار سنجی و آزمون مجموعه:

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

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

مراحل بعدی

این آموزش نشان تقویت داده ها با استفاده از پیش پردازش Keras لایه ها و tf.image .

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