Как использовать featurewise_center=True вместе с flow_from_directory в ImageDataGenerator?

#keras #deep-learning

#keras #глубокое обучение

Вопрос:

Я устанавливаю featurewise_center = True , а затем использую flow_from_directory для настройки своих обучающих и проверочных данных в keras. Однако я получил сообщение об ошибке

 UserWarning: This ImageDataGenerator specifies `featurewise_center`, 
but it hasn't been fit on any training data. Fit it first by calling `.fit(n
numpy_data)`
 

Есть ли какие-либо средства, которые я могу использовать flow_from_directory , а затем подгонять данные по мере необходимости?

Ответ №1:

featurewise_center преобразует изображения в среднее значение 0. Это делается с помощью формул

X = X — среднее значение (X)

Но для ImageDataGenerator выполнения этого преобразования ему необходимо знать среднее значение набора данных, и fit метод ImageDataGenerator выполняет именно эту операцию вычисления этих статистических данных.

Как объясняют документы keras

Подгоняет генератор данных к некоторым образцам данных. Это вычисляет внутреннюю статистику данных, связанную с зависящими от данных преобразованиями, на основе массива выборочных данных.

Если набор данных может быть полностью загружен в память, мы можем сделать это, загрузив все изображения в массив numpy и запустив fit на нем.

Пример кода (изображения RGB размером 256×256) :

 from keras.layers import Input, Dense, Flatten, Conv2D
from keras.models import Sequential
from keras.preprocessing.image import ImageDataGenerator
import numpy as np
from pathlib import Path
from PIL import Image

height = width = 256 

def read_pil_image(img_path, height, width):
        with open(img_path, 'rb') as f:
            return np.array(Image.open(f).convert('RGB').resize((width, height)))

def load_all_images(dataset_path, height, width, img_ext='png'):
    return np.array([read_pil_image(str(p), height, width) for p in 
                                    Path(dataset_path).rglob("*." img_ext)]) 

train_datagen = ImageDataGenerator(featurewise_center=True)
train_datagen.fit(load_all_images('./images/', height, width))

train_generator = train_datagen.flow_from_directory(
        './images/',
        target_size=(height, width),
        batch_size=32,
        class_mode='binary',
        color_mode='rgb')

model = Sequential()
model.add(Conv2D(1,(3,3), input_shape=(height,width,3)))
model.add(Flatten())
model.add(Dense(1))
model.compile('adam', 'binary_crossentropy')

model.fit_generator(train_generator)
 

Но что делать , если данные не могут быть полностью загружены в память ? Один из подходов заключается в случайной выборке изображений из набора данных.

Обычно мы используем mean обучающие данные только для выполнения средней нормализации и используем то же среднее значение для проверки / тестирования данных нормализации. Будет немного сложно сделать то же самое с помощью datagenerator .

Комментарии:

1. Спасибо. Я следовал вашему коду, но я получил «ValueError: установка элемента массива с последовательностью» для кода ‘train_datagen.fit(load_all_images (train_dir)), где в train_dir у меня есть четыре подкаталога, содержащие 4 разных класса изображений. Я не могу понять, в чем проблема. Буду признателен за дальнейшую помощь.

2. @Mlui похоже, что у вас есть изображения с разным разрешением. Измените масштаб всех изображений до одинакового размера. Используется return np.array(Image.open(f).convert('RGB').resize((100,100))) для масштабирования изображений до (100,100).