Resumen

Cuando trabajes con datasets encontrarás bases de datos ya generadas y listas para consumo, pero eventualmente te toparás con la necesidad de crear tus propios datos, por lo que deberás encontrar una manera de cargarlos.

En el momento que cargas datos a memoria, lo haces directamente a la memoria RAM del sistema, por lo que si cargas un dataset pesado de golpe, es probable que termines colapsando tu entorno de trabajo por saturación de recursos.

Para evitar este problema, se crean los generadores, una estructura de datos que generará datos solo si es recorrida, optimizando memoria.

Descargando el dataset de lenguaje de señas

Descargaremos el repositorio desde GCP.

{code-block} bash !wget --no-check-certificate https://storage.googleapis.com/platzi-tf2/sign-language-img.zip \ -O /tmp/sign-language-img.zip

Descomprimiremos el archivo, para esto usaremos los módulos de os y zipfile.

```{code-block} python import os import zipfile

local_zip = "/tmp/sign-language-img.zip" zip_ref = zipfile.ZipFile(local_zip, "r") zip_ref.extractall("/tmp/sign-language-img") zip_ref.close() ```

La estructura del dataset constará en 2 directorios principales: Test y Train, donde para cada clase (letra en señas) tendremos un directorio con sus respectivos ejemplos.

bash sign-language-image/ ├── Test/ │ └── A-Z/ │ └── examples.jpg └── Train/ └── A-Z/ └── examples.jpg

Cargando el dataset con Keras dataset generator

Para llevar a cabo el proceso de carga, haremos uso de varias librerías como TensorFlow, matplotlib y numpy.

{code-block} python import numpy as np %matplotlib inline import matplotlib.pyplot as plt import matplotlib.image as mpimg import string import tensorflow as tf from tensorflow.keras.preprocessing.image import ImageDataGenerator

Cargaremos las rutas donde se encuentran nuestros dataset.

python train_dir = "/tmp/sign-language-img/Train" test_dir = "/tmp/sign-language-img/Test"

Generaremos los data generators, para esta ocasión reescalaremos los datos al rango de 0 a 1 para mejorar la convergencia del modelo, además, dividiremos el 20% de los datos de prueba a validación para monitorear el rendimiento del modelo en vivo.

{code-block} python train_datagen = ImageDataGenerator(rescale = 1/255) test_datagen = ImageDataGenerator(rescale = 1/255, validation_split = 0.2)

Para cargar las imágenes, haremos uso del método flow_from_directory del generador, determinaremos el directorio fuente, el tamaño que tendrán las imágenes (el generador las redimensionará de ser necesario), los lotes de procesamiento, el tipo de clases, el tipo de escala de colores y el subset al que pertenecen.

{code-block} python train_generator = train_datagen.flow_from_directory( train_dir, target_size = (28,28), batch_size = 128, class_mode = "categorical", color_mode = "grayscale", subset = "training" )

Para los subsets de validación y prueba será el mismo proceso, donde cambiarán los nombres de las variables y las fuentes.

```{code-block} python validation_generator = test_datagen.flow_from_directory( test_dir, target_size = (28,28), batch_size = 128, class_mode = "categorical", color_mode = "grayscale", subset = "validation" )

test_generator = train_datagen.flow_from_directory( test_dir, target_size = (28,28), batch_size = 128, class_mode = "categorical", color_mode = "grayscale", ) ```

Para generar las clases haremos una pequeña list comprehension recorriendo los caracteres ASCII omitiendo las letras J y Z.

{code-block} python classes = [char for char in string.ascii_uppercase if char != "J" if char != "Z"]

Para graficar imágenes crearemos la función plotImages que recibirá un array de imágenes y las mostrará en pantalla en grupos de 5.

{code-block} python def plotImages(images_arr): fig, axes = plt.subplots(1, 5, figsize = (10, 10)) axes = axes.flatten() for img, ax in zip(images_arr, axes): ax.imshow(img[:,:,0]) ax.axis("off") plt.tight_layout() plt.show()

Para hacer uso de esta función generaremos un conjunto de imágenes, esto nos retornará un array de imágenes que daremos como parámetro.

{code-block} python sample_training_images, _ = next(train_generator) plotImages(sample_training_images[:5])

Con esto hemos cargado imágenes en memoria sin necesidad de saturar la memoria del sistema, cada vez que requieras iterar sobre tu dataset el generador solo generará las imágenes necesarias.

Contribución creada por Sebastián Franco Gómez.