Datasets generators
Clase 8 de 28 • Curso Profesional de Redes Neuronales con TensorFlow
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.