Wednesday, March 30, 2022

Load and preprocess images in Tensorflow Keras

В этом посте показано, как загрузить и предварительно обработать набор данных изображения тремя способами: Во-первых, вы будете использовать высокоуровневые утилиты предварительной обработки Keras (такие как tf.keras.utils.image_dataset_from_directory) и слои (такие как tf.keras.layers.Rescaling) для чтения каталога изображений на диске. Далее вы напишете свой собственный конвейер ввода с нуля, используя tf.data. Наконец, вы загрузите набор данных из большого каталога, доступного в наборах данных TensorFlow.

Code 1

(.env) [boris@fedora34server FLOWERS]$ cat tulipTensor2.py

import numpy as np

import os

import PIL

import PIL.Image

import tensorflow as tf

import tensorflow_datasets as tfds

# print(tf.__version__)

import pathlib

dataset_url = "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz"

data_dir = tf.keras.utils.get_file(origin=dataset_url,fname='flower_photos', untar=True)

data_dir = pathlib.Path(data_dir)

image_count = len(list(data_dir.glob('*/*.jpg')))

print(image_count)

batch_size = 32

img_height = 180

img_width = 180

train_ds = tf.keras.utils.image_dataset_from_directory(

  data_dir,

  validation_split=0.2,

  subset="training",

  seed=123,

  image_size=(img_height, img_width),

  batch_size=batch_size)

print(train_ds)

val_ds = tf.keras.utils.image_dataset_from_directory(

  data_dir,

  validation_split=0.2,

  subset="validation",

  seed=123,

  image_size=(img_height, img_width),

  batch_size=batch_size)

print(val_ds)

class_names = train_ds.class_names

print(class_names)

import matplotlib.pyplot as plt

plt.figure(figsize=(10, 10))

for images, labels in train_ds.take(1):

  for i in range(9):

    ax = plt.subplot(3, 3, i + 1)

    plt.imshow(images[i].numpy().astype("uint8"))

    plt.title(class_names[labels[i]])

    plt.axis("off")

# Стандартизируйте данные

# Значения канала RGB находятся в диапазоне [0, 255]. Это не идеально для нейронной сети; 

# в общем, вы должны стремиться к тому, чтобы ваши входные значения были небольшими.

# Здесь вы стандартизируете значения в диапазоне [0, 1] с помощью tf.keras.layers.Rescaling:

normalization_layer = tf.keras.layers.Rescaling(1./255)

normalized_ds = train_ds.map(lambda x, y: (normalization_layer(x), y))

image_batch, labels_batch = next(iter(normalized_ds))

first_image = image_batch[0]

# Notice the pixel values are now in `[0,1]`.

print(np.min(first_image), np.max(first_image))

# Dataset.cache хранит изображения в памяти после их загрузки с диска в течение первой эпохи. 

# Это гарантирует, что набор данных не станет узким местом при обучении вашей модели. 

# Если ваш набор данных слишком велик, чтобы поместиться в память, вы также можете 

# использовать 

# этот метод для создания производительного кэша на диске.

# Dataset.prefetch перекрывает предварительную обработку данных и выполнение 

# модели во время обучения.

AUTOTUNE = tf.data.AUTOTUNE

train_ds = train_ds.cache().prefetch(buffer_size=AUTOTUNE)

val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)

num_classes = 5

model = tf.keras.Sequential([

  tf.keras.layers.Rescaling(1./255),

  tf.keras.layers.Conv2D(32, 3, activation='relu'),

  tf.keras.layers.MaxPooling2D(),

  tf.keras.layers.Conv2D(32, 3, activation='relu'),

  tf.keras.layers.MaxPooling2D(),

  tf.keras.layers.Conv2D(32, 3, activation='relu'),

  tf.keras.layers.MaxPooling2D(),

  tf.keras.layers.Flatten(),

  tf.keras.layers.Dense(128, activation='relu'),

  tf.keras.layers.Dense(num_classes)

])

# Выберите оптимизатор tf.keras.optimizers.Adam и функцию потерь 

# tf.keras.losses.SparseCategoricalCrossentropy. Чтобы просмотреть 

# точность обучения и проверки для каждой эпохи обучения, 

# передайте аргумент метрики в Model.compile

model.compile(

  optimizer='adam',

  loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),

  metrics=['accuracy'])

model.fit(train_ds,validation_data=val_ds, epochs=3)

# Использование tf.data для более тонкого контроля

# Для более точного управления вы можете написать свой 

# собственный входной конвейер,

# используя tf.data. В этом разделе показано, как это сделать, 

# начиная с путей к файлам из загруженного ранее файла TGZ.

list_ds = tf.data.Dataset.list_files(str(data_dir/'*/*'), shuffle=False)

list_ds = list_ds.shuffle(image_count, reshuffle_each_iteration=False)

for f in list_ds.take(5):

  print(f.numpy())

class_names = np.array(sorted([item.name for item in data_dir.glob('*') if item.name != "LICENSE.txt"]))

print(class_names)

val_size = int(image_count * 0.2)

train_ds = list_ds.skip(val_size)

val_ds = list_ds.take(val_size)

print(tf.data.experimental.cardinality(train_ds).numpy())

print(tf.data.experimental.cardinality(val_ds).numpy())

def get_label(file_path):

  # Convert the path to a list of path components

  parts = tf.strings.split(file_path, os.path.sep)

  # The second to last is the class-directory

  one_hot = parts[-2] == class_names

  # Integer encode the label

  return tf.argmax(one_hot)

def decode_img(img):

  # Convert the compressed string to a 3D uint8 tensor

  img = tf.io.decode_jpeg(img, channels=3)

  # Resize the image to the desired size

  return tf.image.resize(img, [img_height, img_width])

def process_path(file_path):

  label = get_label(file_path)

  # Load the raw data from the file as a string

  img = tf.io.read_file(file_path)

  img = decode_img(img)

  return img, label

# Используйте Dataset.map для создания набора данных пар изображений и меток

# Set `num_parallel_calls` so multiple images are loaded/processed in parallel.

train_ds = train_ds.map(process_path, num_parallel_calls=AUTOTUNE)

val_ds = val_ds.map(process_path, num_parallel_calls=AUTOTUNE)

for image, label in train_ds.take(1):

  print("Image shape: ", image.numpy().shape)

  print("Label: ", label.numpy())

# Чтобы обучить модель с этим набором данных, вам понадобятся данные:

# Чтобы хорошо перетасовать.Для пакетирования.

# Партии должны быть доступны как можно скорее.

# Эти функции можно добавить с помощью API tf.data.

def configure_for_performance(ds):

  ds = ds.cache()

  ds = ds.shuffle(buffer_size=1000)

  ds = ds.batch(batch_size)

  ds = ds.prefetch(buffer_size=AUTOTUNE)

  return ds

train_ds = configure_for_performance(train_ds)

val_ds = configure_for_performance(val_ds)

image_batch, label_batch = next(iter(train_ds))

plt.figure(figsize=(10, 10))

for i in range(9):

  ax = plt.subplot(3, 3, i + 1)

  plt.imshow(image_batch[i].numpy().astype("uint8"))

  label = label_batch[i]

  plt.title(class_names[label])

  plt.axis("off")

  # plt.show()

# Теперь вы вручную создали набор tf.data.Dataset, аналогичный тому, который 

# был создан с помощью tf.keras.utils.image_dataset_from_directory выше. 

# С ним вы можете продолжить обучение модели. Как и прежде, вы будете 

# тренироваться всего несколько эпох, чтобы сократить время бега.

model.fit(

  train_ds,

  validation_data=val_ds,

  epochs=3

)

# Поскольку ранее вы загрузили набор данных Flowers с диска, 

# давайте теперь импортируем его с помощью наборов данных TensorFlow.

# Загрузите набор данных 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)

# Получить изображение из набора данных.

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

image, label = next(iter(train_ds))

_ = plt.imshow(image)

_ = plt.title(get_label_name(label))

plt.show()














References

https://www.tensorflow.org/tutorials/load_data/images


No comments:

Post a Comment