[Keras] Mejora de datos --- ImageDataGenerator

cada blog, cada lema: puedes hacer más de lo que crees.

0. Prefacio

Registrar problemas relacionados encontrados en la mejora de datos usando keras

1. Texto

1.1 Introducción básica

Podemos usar keras.preprocessing.image.ImageDataGenerator para mejorar los datos "en línea" o "fuera de línea"

1.1.1 Generar objeto

Como se muestra en el siguiente código:
podemos generar un objeto iterable y especificar el método específico de mejora de datos (como: rotación, volteo, etc.)

from keras.preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator(
        rotation_range=40,
        width_shift_range=0.2,
        height_shift_range=0.2,
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True,
        fill_mode='nearest')

parámetro:

  • Rotación_rango es un número de grados de 0 a 180, que se utiliza para especificar el ángulo de las imágenes seleccionadas al azar.
  • Width_shift y height_shift se utilizan para especificar el grado de movimiento aleatorio en las direcciones horizontal y vertical. Esta es la relación entre los dos 0 ~ 1.
  • El valor de cambio de escala se multiplicará por la imagen completa antes de realizar otro procesamiento. Nuestra imagen es un número entero de 0 a 255 en los canales RGB . Tal operación puede hacer que el valor de la imagen sea demasiado alto o demasiado bajo, por lo que establecemos este valor a 0 1 El número entre.
  • shear_range es el grado de transformación de corte, refiérase a la transformación de corte. zoom_range se utiliza para acercar la imagen de forma aleatoria.
  • horizontal_flip voltea aleatoriamente la imagen horizontalmente. Este parámetro es adecuado para cuando el giro horizontal no afecta la semántica de la imagen.
  • fill_mode se usa para especificar cómo llenar nuevos píxeles cuando se requiere el llenado de píxeles, como rotación, desplazamiento horizontal y vertical.

Los siguientes son dos métodos del generador, a los que se puede acceder mediante next, o atravesado por un bucle for. A continuación, tomemos next como ejemplo.


1.1.2 flujo

Transforme la matriz después de leer la imagen, es decir, el parámetro es una matriz,
ya que es un generador, podemos usar next para obtener el siguiente valor del generador.

import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
from keras.preprocessing.image import ImageDataGenerator
import cv2 as cv
import numpy as np

# 读取图片
img = cv.imread('./input/u=1819216937,2118754409&fm=26&gp=0.jpg')
img = np.expand_dims(img, axis=0)
# 实例化对象
agu = ImageDataGenerator(rotation_range=40)  # 随机旋转0-40度之间
# print(type(agu))
# 变换并保存
next(agu.flow(img, save_to_dir='./output', save_format='jpg'))

Nota: Lo que acepta el flujo es una matriz de 4 dimensiones, que contiene dimensiones de btach, como: (lote, altura, ancho, canal), se agrega una dimensión al código anterior. Lo mismo a continuación.
Inserte la descripción de la imagen aquí

1.1.3 flow_from_directory

"Transforma la carpeta donde se encuentra la imagen", es decir, el parámetro es una carpeta.
Nota: ¡El parámetro es una carpeta, que debe contener subcarpetas! ! !
Inserte la descripción de la imagen aquí

import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
from keras.preprocessing.image import ImageDataGenerator
import cv2 as cv
import numpy as np

# 输入文件夹
path = r'./input'
# 实例化对象
agu = ImageDataGenerator(rotation_range=40)  # 随机旋转0-40度之间
# print(type(agu))
# 变换并保存
next(agu.flow_from_directory(path,batch_size=1, save_to_dir='./output', save_format='jpg'))

1.2 El problema

El código básico es el mismo que 1.1.2, excepto que el objeto instanciado es diferente, por lo que solo se publica la parte del objeto instanciado

1.2.1 Pregunta 1

El error es el siguiente:

UserWarning: This ImageDataGenerator specifies `zca_whitening`, which overrides setting of `featurewise_center`.
  warnings.warn('This ImageDataGenerator specifies '

Parte del código:

# 实例化对象
agu = ImageDataGenerator(rotation_range=40,zca_whitening=True)

Solo se agregó el parámetro zca_whitening y apareció la advertencia anterior.
Explicación: Cuando zca_whitening = True, feature_center se establecerá en True, aunque no lo hayamos establecido, aparecerán todas las advertencias.
Código fuente:
Inserte la descripción de la imagen aquí
solución, solo agregue feature_center = True.

# 实例化对象
agu = ImageDataGenerator(rotation_range=40,zca_whitening=True,featurewise_center=True)

1.2.2 Pregunta 2

Problemas relacionados encontrados en el blanqueamiento de imágenes:

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

Crear una instancia del código de objeto

# 实例化对象
agu = ImageDataGenerator(rotation_range=40,zca_whitening=True,featurewise_center=True)

Razón: Usamos feature_center = True en el parámetro, pero no usamos el método de ajuste .
Explicación oficial:
Inserte la descripción de la imagen aquí
Solución: llame al código del método de ajuste antes de usar el método flow o flow_from_directory
:
Inserte la descripción de la imagen aquí
También: cuando se usa el método de ajuste, información estadística (media varianza) se calculará, este proceso es muy lento. Si la imagen es grande, se producirá el siguiente error

1.2.3 Pregunta 3

El error es el siguiente:

MemoryError: Unable to allocate 857. GiB for an array with shape (479700, 479700) and data type float32

Motivo: Para calcular la información estadística relevante, se calculará la SVD, cuyo valor es relativamente grande, por lo que se produjo el error anterior.
Un intento:
reemplace el método de ajuste con el siguiente y calcúlelo manualmente:

agu.mean = np.mean(img,axis=0)

Código completo:
Inserte la descripción de la imagen aquí
pero el resultado no es necesariamente correcto:
Inserte la descripción de la imagen aquí
esto es solo un intento, el resultado no es necesariamente correcto

1.2.4 Pregunta 4

Solo se agrega el parámetro de rotación y el color de la imagen guardada cambia.
Inserte la descripción de la imagen aquí
Código:
Inserte la descripción de la imagen aquí
Razón: usamos cv para leer la imagen, y la lectura es BRG. Al escribir, es exactamente lo contrario del RGB original, por lo que un error ocurre.
Método 1: ajustar la secuencia de BGR

Inserte la descripción de la imagen aquí
Resultado:
Inserte la descripción de la imagen aquí
Método dos: Método de conversión
Inserte la descripción de la imagen aquí
tres: Lectura de PIL

Inserte la descripción de la imagen aquí

1.2.5 Pregunta 5

Nota: Para ser precisos, esto no es un problema, pero es curioso, como sigue: Cuando
configure varios parámetros, use solo uno a la vez, o utilícelos al mismo tiempo.

Prueba, usa los dos parámetros de rotación y volteo vertical al mismo tiempo.
Código:
Inserte la descripción de la imagen aquí
Probado dos veces, y los resultados son los siguientes:
Inserte la descripción de la imagen aquí
Conclusión: Descubrimos que los dos parámetros funcionan al azar, a veces solo girando, no volteando; a veces ambos funcionan, etc.
Se ha realizado una prueba con los siguientes resultados:
Inserte la descripción de la imagen aquí
encontramos, respectivamente, hacia la izquierda y hacia la derecha que se han girado, lo que también volcó lo dijimos antes, la nota interior o comentarios: "La rotación hacia 0-40 grados (valor fijado) para rotar" , pero debería estar entre -40-40 grados En el código fuente, encontramos que este es el caso.
El comentario en el código anterior es incorrecto, no está girado entre 0-40 grados, no volveré a modificarlo, ¡preste atención! ! !
Inserte la descripción de la imagen aquí

1.3 Dos formas de uso

1.3.1 Uso ordinario

Este es un ejemplo oficial, a través del bucle, obtenga datos continuamente

(x_train, y_train), (x_test, y_test) = cifar10.load_data()
y_train = np_utils.to_categorical(y_train, num_classes)
y_test = np_utils.to_categorical(y_test, num_classes)

datagen = ImageDataGenerator(
    featurewise_center=True,
    featurewise_std_normalization=True,
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    horizontal_flip=True)

# compute quantities required for featurewise normalization
# (std, mean, and principal components if ZCA whitening is applied)
datagen.fit(x_train)

# fits the model on batches with real-time data augmentation:
model.fit_generator(datagen.flow(x_train, y_train, batch_size=32),
                    steps_per_epoch=len(x_train), epochs=epochs)

# here's a more "manual" example
for e in range(epochs):
    print 'Epoch', e
    batches = 0
    for x_batch, y_batch in datagen.flow(x_train, y_train, batch_size=32):
        loss = model.train(x_batch, y_batch)
        batches += 1
        if batches >= len(x_train) / 32:
            # we need to break the loop by hand because
            # the generator loops indefinitely
            break

1.3.2 Combinar con keras.utils.Sequence

El uso de keras.utils.Sequence hace referencia al artículo anterior, que se adjunta.
Nota:
también es muy fácil de usar,

  • Durante la inicialización, se genera un objeto de mejora de datos
  • __getitem __ Regresa a continuación, solo sigue llamando y generando.
import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
from keras.preprocessing.image import ImageDataGenerator, load_img
import cv2 as cv
import numpy as np


class Date(tf.keras.utils.Sequence):

    def __init__(self):
        self.input = r'./data'
        self.file = os.listdir(self.input)
        print(self.file)
        self.batch = 2
        self.agu = ImageDataGenerator(
            # 增强的项目。翻转,缩放,平移,旋转,颜色等。
            rotation_range=40,
            width_shift_range=0.2,
            height_shift_range=0.2,
            shear_range=0.2,  # 比例平移
            zoom_range=0.2,
            fill_mode='nearest',
            horizontal_flip=True,
            vertical_flip=True,
            zca_whitening=True,
            featurewise_center=True,
            rescale=1. / 255
        )

    def __len__(self):
        """
        此方法要实现,否则会报错
        正常程序中返回1个epoch迭代的次数
        :return:
        """
        return len(self.file)

    def generate_batch(self):
        x_batch = np.zeros((3, 256, 256, 3))
        for i, file in enumerate(self.file):
            path = os.path.join(self.input, file)
            # print(path)
            img = cv.imread(path)
            x_batch[i,] = img
        x_batch = np.array(x_batch)

        return x_batch

    def __getitem__(self, index):
        """生成一个batch的数据"""

        x_batch = self.generate_batch()
        # self.agu.fit(x_batch)
        return next(self.agu.flow(x_batch,batch_size=1,save_to_dir='./output',save_format='jpg'))
        # return next((self.agu.flow_from_directory(self.input,save_to_dir='./output',save_format='jpg')))
        # return x_batch


# 实例化数据
date = Date()

for batch_number, x in enumerate(date):
    print('正在进行第{} batch'.format(batch_number))

referencias

[1] https://blog.csdn.net/weixin_39190382/article/details/109195031
[2] https://blog.csdn.net/xijuezhu8128/article/details/79895856
[3] https: //blog.csdn .net / wang263334857 / article / details / 88749379
[4] https://blog.csdn.net/qq_36537768/article/details/103066394
[5] https://www.cnblogs.com/hutao722/p/10075150.html
[6] https://blog.csdn.net/jacke121/article/details/79245732
[7] https://blog.csdn.net/qq_27825451/article/details/90172030
[8] https: //blog.csdn .net / dugudaibo / article / details / 87719078
[9] https://tensorflow.google.cn/versions/r2.0/api_docs/python/tf/keras/preprocessing/image/ImageDataGenerator
[10] https://keras-cn.readthedocs.io/en/latest/preprocessing/image/#imagedatagenerator

Supongo que te gusta

Origin blog.csdn.net/weixin_39190382/article/details/113281345
Recomendado
Clasificación