Изменение масштаба ImageDataGenerator до [-1,1] вместо [0,1] - PullRequest
0 голосов
/ 10 июля 2020

Я использую Keras Tensorflow ImageDataGenerator, и обычно он используется с коэффициентом масштабирования 1./255, чтобы вместо этого масштабировать исходные значения с 0 до 255, от 0 до 1. Однако я хотел бы масштабировать его до диапазона -1,1.

Итак, вместо:

train_image_generator = ImageDataGenerator(
    rescale=1./255,
)

я пробовал:

train_image_generator = ImageDataGenerator(
    rescale=((1./127.5)-1)
)

Далее это будет применяется к каталогу:

train_datagen = train_image_generator.flow_from_directory(
  directory=training_dir,
  target_size=(x, y),
  shuffle=True,
  batch_size=x,
  class_mode='binary'
)

Проверка некоторых значений может быть выполнена следующим образом:

train_datagen[1]

Но согласно документации это фактор, который мы используем для умножьте данные на предоставленное значение. Таким образом, это может быть только коэффициент, который используется для умножения, поэтому нет смысла вычитать 1 здесь, потому что данные масштабируются с использованием значения -0.99215686275 и отступа, когда я проверяю фактические значения, я вижу отрицательные значения, такие как -130. хх. Так что это не работает. Поскольку мне нужно масштабировать его до -1,1, а не 0,1, поскольку я хочу позже использовать предварительно обученный Mobil eNet V2, мой вопрос: как я могу это сделать?

Я не говоря о способе избежать использования ImageDataGenerator :

def format_example(image, label):
  image = tf.cast(image, tf.float32)
  image = (image/127.5) - 1
  image = tf.image.resize(image, (IMG_SIZE, IMG_SIZE))
  return image, label

и т. д.

Поэтому я хотел бы использовать ImageDataGenerator. Итак, я могу изменить масштаб на 1.0 / 127.5, но все же мне нужно вычесть 1. Есть ли способ позже вычесть 1 из значений в train_datagen? Что-то вроде

train_datagen.actualvalues-1

(я знаю, что это не работает.)

Кроме того: мне нужно решение, которое работает вместе с увеличением изображения, поэтому обычно я иметь:

train_image_generator = ImageDataGenerator(
    horizontal_flip=True,
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    fill_mode="nearest",
    zoom_range=0.2,
    rescale=((1./127.5)-1) #1./255,
)

Теперь моя единственная проблема в том, что rescale=((1./127.5)-1) не работает. Как я могу решить эту проблему, как изменить масштаб до [-1,1] вместо [0,1]?

Ответы [ 2 ]

5 голосов
/ 10 июля 2020

Используйте параметр preprocessing_function .

def prep_fn(img):
    img = img.astype(np.float32) / 255.0
    img = (img - 0.5) * 2
    return img

gen = ImageDataGenerator(
    preprocessing_function=prep_fn
)
0 голосов
/ 10 июля 2020

Попробуйте следующее:

def norm(image, label):
    image = tf.cast(image, tf.float32)
    norm_min, norm_max = -1, +1
    nom = (image - image.min()) * (norm_max - norm_min)
    denom = image.max() - image.min()
    image = norm_min + nom / denom
    image = tf.image.resize(image, (IMG_SIZE, IMG_SIZE))
    return image, label

Вы можете изменить значения norm_max и norm_min, чтобы попытаться нормализовать до [-1,1] или [0,1].

Обратите внимание на строку

image = (image/127.5) - 1

делает это, но в контексте изображений с известным минимумом и максимумом [0,255] до нормализации.

Редактировать: Получил неправильную идею ...

Не зная, какая нормализация была раньше, но желая нормализации [0,1], вы можете использовать

norm_min, norm_max = 0, 1
image = norm_min + (image - image.min()) * (norm_max - norm_min) / (image.max() - image.min())
...