Случайные числа Tensorflow в функции карты Data Augmentation - PullRequest
2 голосов
/ 08 апреля 2020

Я хочу использовать функцию crop_central со случайным значением с плавающей точкой в ​​диапазоне 0,50-1,00 для увеличения данных. Тем не менее, при использовании numpy.random.uniform(0.50, 1.00) и построении изображений обрезка постоянна. Я отладил это, используя 4 изображения и построив 8 строк, изображения идентичны.

В общем вопрос можно сформулировать следующим образом: Как использовать случайные числа в функциях карты набора данных?

def data_augment(image, label=None, seed=2020):
    # I want a random number here for every individual image
    image = tf.image.central_crop(image, np.random.uniform(0.50, 1.00)) # random crop central
    image = tf.image.resize(image, INPUT_SHAPE) # the original image size

    return image

train_dataset = (
    tf.data.Dataset
        .from_tensor_slices((train_paths, train_labels))
        .map(decode_image, num_parallel_calls=AUTO)
        .map(data_augment, num_parallel_calls=AUTO)
        .repeat()
        .batch(4)
        .prefetch(AUTO)
    )

# Code to view the images
for idx, (imgs, _) in enumerate(train_dataset):
    show_imgs(imgs, 'image', imgs_per_row=4)
    if idx is 8:
        del imgs
        gc.collect()
        break

1 Ответ

0 голосов
/ 07 мая 2020

Ранее я неправильно прочитал вопрос. Вот ответ, который вы искали.

Мне удалось воссоздать вашу проблему, используя приведенный ниже код -

Код для воспроизведения проблемы - Выходные данные для обрезки изображения были все идентичны.

%tensorflow_version 2.x
import tensorflow as tf
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array, array_to_img
from matplotlib import pyplot as plt
import numpy as np
AUTOTUNE = tf.data.experimental.AUTOTUNE

# Set the sub plot parameters
f, axarr = plt.subplots(5,4,figsize=(15, 15))

# Load just 4 images of Cifar10
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
images = x_train[:4]

for i in range(4):
  axarr[0,i].title.set_text('Original Image')
  axarr[0,i].imshow(x_train[i])

def data_augment(images):
    image = tf.image.central_crop(images, np.random.uniform(0.50, 1.00)) # random crop central
    image = tf.image.resize(image, (32,32)) # the original image size
    return image

dataset = tf.data.Dataset.from_tensor_slices((images)).map(lambda x: data_augment(x)).repeat(4) 

print(dataset)

ix = 0
i = 1
count = 0

for f in dataset:
  crop_img = array_to_img(f)
  axarr[i,ix].title.set_text('Crop Image')
  axarr[i,ix].imshow(crop_img)
  ix=ix+1
  count = count + 1
  if count == 4:
    i = i + 1
    count = 0
    ix = 0

Вывод - 1-я строка - исходное изображение. Остальные строки представляют собой кадрированные изображения.

enter image description here

Что ж, это было очень сложно и предоставило два решения ниже -

Решение 1: Использование np.random.uniform и tf.py_function.

  1. Используется np.random.uniform(0.50, 1.00).
  2. Используется tf.py_function для украшения вызова функции - tf.py_function(data_augment, [x], [tf.float32]).

Код для решения проблемы - Изображения на выходе обрезки теперь разные и не идентичны.

%tensorflow_version 2.x
import tensorflow as tf
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array, array_to_img
from matplotlib import pyplot as plt
import numpy as np
AUTOTUNE = tf.data.experimental.AUTOTUNE

# Set the sub plot parameters
f, axarr = plt.subplots(5,4,figsize=(15, 15))

# Load just 4 images of Cifar10
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
images = x_train[:4]

for i in range(4):
  axarr[0,i].title.set_text('Original Image')
  axarr[0,i].imshow(x_train[i])

def data_augment(images):
    image = tf.image.central_crop(images, np.random.uniform(0.50, 1.00)) # random crop central
    image = tf.image.resize(image, (32,32)) # the original image size
    return image

dataset = tf.data.Dataset.from_tensor_slices((images)).map(lambda x: tf.py_function(data_augment, [x], [tf.float32])).repeat(4)

ix = 0
i = 1
count = 0

for f in dataset:
  for l in f:
    crop_img = array_to_img(l)
    axarr[i,ix].title.set_text('Crop Image')
    axarr[i,ix].imshow(crop_img)
    ix=ix+1
    count = count + 1
    if count == 4:
      i = i + 1
      count = 0
      ix = 0

Вывод - 1-я строка является исходным изображением. Остальные строки представляют собой кадрированные изображения.

enter image description here

Решение 2: Использование tf.random.uniform и tf.py_function.

  1. Используется tf.random.uniform(shape=(), minval=0.50, maxval=1).numpy().
  2. Просто с помощью вышеуказанной опции код не работает, так как выдает ошибку AttributeError: 'Tensor' object has no attribute 'numpy'. Чтобы решить эту проблему, вам нужно украсить свою функцию с помощью tf.py_function(data_augment, [x], [tf.float32]).

Код для решения проблемы - Изображения на выходе обрезки теперь разные и не идентичны .

%tensorflow_version 2.x
import tensorflow as tf
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array, array_to_img
from matplotlib import pyplot as plt
import numpy as np
AUTOTUNE = tf.data.experimental.AUTOTUNE

# Set the sub plot parameters
f, axarr = plt.subplots(5,4,figsize=(15, 15))

# Load just 4 images of Cifar10
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
images = x_train[:4]

for i in range(4):
  axarr[0,i].title.set_text('Original Image')
  axarr[0,i].imshow(x_train[i])

def data_augment(images):
    image = tf.image.central_crop(images, tf.random.uniform(shape=(), minval=0.50, maxval=1).numpy()) # random crop central
    image = tf.image.resize(image, (32,32)) # the original image size
    return image

dataset = tf.data.Dataset.from_tensor_slices((images)).map(lambda x: tf.py_function(data_augment, [x], [tf.float32])).repeat(4)

ix = 0
i = 1
count = 0

for f in dataset:
  for l in f:
    crop_img = array_to_img(l)
    axarr[i,ix].title.set_text('Crop Image')
    axarr[i,ix].imshow(crop_img)
    ix=ix+1
    count = count + 1
    if count == 4:
      i = i + 1
      count = 0
      ix = 0

Вывод - 1-я строка является исходным изображением. Остальные строки представляют собой кадрированные изображения.

enter image description here

Надеюсь, что это ответ на ваш вопрос. Счастливого обучения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...