Работа ImageDataGenerator рассматривается на примере набора EMNIST-Letters [1], содержащего рукописные буквы английского алфавита.
ImageDataGenerator на основе известных изображений создает похожие изображения (рис. 1).
Рис. 1. Примеры рукописной буквы А (а)
ImageDataGenerator может быть использован, например, для расширения обучающего или тестового наборов данных, или для создания набора данных на основе имеющихся изображений.
Берется из документации библиотеки Keras [2].
keras.preprocessing.image.ImageDataGenerator(featurewise_center=False, samplewise_center=False, featurewise_std_normalization=False, samplewise_std_normalization=False, zca_whitening=False, zca_epsilon=1e-06, rotation_range=0, width_shift_range=0.0, height_shift_range=0.0, brightness_range=None, shear_range=0.0, zoom_range=0.0, channel_shift_range=0.0, fill_mode='nearest', cval=0.0, horizontal_flip=False, vertical_flip=False, rescale=None, preprocessing_function=None, data_format=None, validation_split=0.0, dtype=None)
Примеры сгенерированных букв с различными значениями параметров показаны на рис. 2.
Рис. 2. Примеры буквы А (а) с различными значениями параметров ImageDataGenerator
Генерацию и отображение изображений обеспечивает следующий код:
import numpy as np
import matplotlib.pyplot as plt
from keras.preprocessing.image import ImageDataGenerator
import sys # Для sys.exit()
#
pathToData = 'G:/AM/НС/emnist/'
num_classes = 26
img_cols = img_rows = 28
# Флаг вывода изображений букв после загрузки данных
showPics = False # True False
# Флаг вывода изображений букв из тестового или обучающего набора (вывод после загрузки данных)
showFromTest = True
X_train_shape_0 = 124800
X_test_shape_0 = 20800
#
# Загрузка EMNIST
def load_data():
# Загрузка данных
imagesTrain, labelsTrain, imagesTest, labelsTest = loadBinData(pathToData)
#
X_train = np.asarray(imagesTrain)
y_train = np.asarray(labelsTrain)
X_test = np.asarray(imagesTest)
y_test = np.asarray(labelsTest)
y_train -= 1
y_test -= 1
y_test_0 = y_test # Для predict в checkModel (43)
X_train = X_train.reshape(X_train_shape_0, img_rows, img_cols, 1).transpose(0,2,1,3)
X_test = X_test.reshape(X_test_shape_0, img_rows, img_cols, 1).transpose(0,2,1,3)
if showPics:
if showFromTest:
print('Показываем примеры тестовых данных')
else:
print('Показываем примеры обучающих данных')
# Выводим 16 изображений обучающего или тестового набора
names = makeNames()
for i in range(16):
plt.subplot(2, 8, i + 1)
ind = y_test[i] if showFromTest else y_train[i]
img = X_test[i][0:img_rows, 0:img_rows, 0] if showFromTest else X_train[i][0:img_rows, 0:img_rows, 0]
plt.imshow(img, cmap = plt.get_cmap('gray'))
plt.title(names[ind])
plt.axis('off')
plt.subplots_adjust(hspace = 0.1) # wspace
plt.show()
sys.exit()
return X_train, y_train, X_test, y_test
#
def loadBinData(pathToData):
print('Загрузка данных из двоичных файлов')
with open(pathToData + 'imagesTrain.bin', 'rb') as read_binary:
data = np.fromfile(read_binary, dtype = np.uint8)
with open(pathToData + 'labelsTrain.bin', 'rb') as read_binary:
labels = np.fromfile(read_binary, dtype = np.uint8)
with open(pathToData + 'imagesTest.bin', 'rb') as read_binary:
data2 = np.fromfile(read_binary, dtype = np.uint8)
with open(pathToData + 'labelsTest.bin', 'rb') as read_binary:
labels2 = np.fromfile(read_binary, dtype = np.uint8)
return data, labels, data2, labels2
#
def makeNames():
names = []
for i in range(26): names.append(chr(65 + i)) # ['A', 'B', 'C', ..., 'Z']
return names
#
# Главная программа
if __name__ == '__main__':
# Загрузка данных и формирование обучающих и тестовых выборок
X_train, y_train, X_test, y_test = load_data()
# Все параметры имеют заданные по умолчанию значения
datagen = ImageDataGenerator()
print('Настройка генератора...')
datagen.fit(X_train)
print('Получаем сгенерированные образы и показываем 15 первых экземпляров заданной буквы, например, A (a)...')
X_y = datagen.flow(X_test, y_test, batch_size = 1) # batch_size = 32
names = makeNames()
print(type(X_y)) # class 'keras_preprocessing.image.NumpyArrayIterator'
print(len(X_y)) # 20800
print(names[X_y[0][1][0]])
letToShow = 'A'
k = -1
for i in range(len(X_y)):
ind = X_y[i][1][0]
let = names[ind]
if let == letToShow:
k += 1
plt.subplot(2, 8, k + 1)
img = X_y[i][0].astype('uint8')
img = img.reshape(img_rows, img_cols)
if k == 0: print(img)
plt.imshow(img, cmap = plt.get_cmap('gray'))
plt.title(let)
plt.axis('off')
if k == 15: break
plt.subplots_adjust(hspace = 0.1) # wspace
plt.show()