En el desarrollo de este post, te exponemos el desarrollo de un ejemplo de carga de dataset externo en Deep Learning.
Ejemplo carga de dataset externo en Deep Learning
Vamos a ver un ejemplo de carga de dataset externo en Deep Learning que consiste en cómo podríamos cargar un dataset de imágenes junto con sus etiquetas.
Para este ejemplo vamos a utilizar imágenes provenientes de escáneres de pulmón para tratar de predecir el Covid-19. Los datos son públicos y están disponibles en esta página.
Este dataset consta de imágenes de pacientes patológicos y sanos. Para hacer el ejemplo más sencillo, vamos a tratar con las imágenes correspondientes a Covid19 únicamente.
# Para ello, lo primero es decargarnos el dataset !wget -O CT_Covid.zip https://github.com/UCSD-AI4H/COVID-CT/blob/master/Images-processed/CT_COVID.zip?raw=true
--2022-05-17 09:59:04-- https://github.com/UCSD-AI4H/COVID-CT/blob/master/Images-processed/CT_COVID.zip?raw=true Resolving github.com (github.com)... 192.30.255.113 Connecting to github.com (github.com)|192.30.255.113|:443... connected. HTTP request sent, awaiting response... 302 Found Location: https://github.com/UCSD-AI4H/COVID-CT/raw/master/Images-processed/CT_COVID.zip [following] --2022-05-17 09:59:04-- https://github.com/UCSD-AI4H/COVID-CT/raw/master/Images-processed/CT_COVID.zip Reusing existing connection to github.com:443. HTTP request sent, awaiting response... 302 Found Location: https://raw.githubusercontent.com/UCSD-AI4H/COVID-CT/master/Images-processed/CT_COVID.zip [following] --2022-05-17 09:59:04-- https://raw.githubusercontent.com/UCSD-AI4H/COVID-CT/master/Images-processed/CT_COVID.zip Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.111.133, 185.199.109.133, ... Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 47929914 (46M) [application/zip] Saving to: ‘CT_Covid.zip’ CT_Covid.zip 100%[===================>] 45.71M 266MB/s in 0.2s 2022-05-17 09:59:06 (266 MB/s) - ‘CT_Covid.zip’ saved [47929914/47929914]
# comprobamos que tenemos el dataset descargado !ls -lah
# lo descomprimimos !unzip CT_Covid.zip
# Ahora que ya lo tenemos descomprimido, tenemos que listar la carpeta donde se # encuentran todas las imágenes para después poder cargarlas. Existen varias # formas de hacer esto, y algunas son más eficientes que otras. Por ejemplo: # images = [] # for img in list_imgs: # images.append(load_image(img)) # Esté método es el más lento que podemos utilizar, ya que cada vez que añadamos # una nueva imagen, Python creará una nueva lista y copiará el contenido de la # anterior. No es el método más adecuado. # El siguiente es mucho mejor, ya que no se crean nuevas listas, # simplemente se accede a posiciones determinadas y se insertan los datos: # n_images = len(list_imgs) # images = np.zeros((n_images, height, width, channels), dtype=np.uint8) # for i, img in enumerate(list_imgs): # images[i] = load_image(img) # Sin embargo, este segundo método tiene un inconveniente. Necesitamos que # todas las imágenes tengan el mismo tamaño, algo que no siempre pasa en # los datasets reales: tendremos que redimensionarlas. # Vamos a cargarlas siguiendo los dos métodos para que veáis las diferencias. # Para ver el tiempo que tarda cada una, utilizaremos la librería TQDM, que # crea una barra de progreso y nos informa de los tiempos.
# listamos el directorio import glob list_imgs = glob.glob('./CT_COVID/*.png') n_images = len(list_imgs) print(n_images, 'images were loaded!')
349 images were loaded!
# Tenemos las 349 CTs que hay disponibles en el dataset. # Ahora, vamos a cargarlas, pero primero necesitamos saber las dimensiones # de las imágenes. Para ello, vamos a utilizar OpenCV. import cv2 for img_path in list_imgs: img = cv2.imread(img_path) print(img.shape)
# Las imágenes tienen tamaños diferentes. Ahora, en esta carga de dataset externo en Deep Learning tenemos dos opciones: # - Redimensionar las imágenes al mismo tamaño, sin mantener el ASPECT RATIO. # Es el método más sencillo, pero distorsionará las imágenes, por lo que puede # hacer que nuestro modelo no sea todo lo bueno que podría ser. # - Redimensionar las imágenes al mismo tamaño, manteniendo el ASPECT RATIO. # Para ello, podemos redimensionar las imágenes al tamaño deseado y luego # rellenar "los huecos" con algún valor constante, normalmente, 0. # En este caso, por simplicidad, vamos a hacer la primera opción.
from tqdm import tqdm # creamos la estructura de datos donde almacenaremos las imágenes cargadas images = [] # implementamos el bucle que recorrerá la lista e irá cargando las imágenes, # redimensionándolas y añadiéndolas a nuestra estructura de datos for i, img_path in enumerate(tqdm(list_imgs)): img = cv2.imread(img_path) # opencv carga por defecto las imágenes en modo BGR # esto lo tenemos que tener en cuenta, ya que si entrenamos # el modelo con imágenes BGR, luego tendremos que alimentarlo # con imágenes del mismo tipo para que el modelo funcione # correctamente. img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # la redimensionamos a 96x96 (este tamaño es arbitrario porque es un ejemplo, # en un caso real, estudiaríamos el tamaño que menos distorsiona la mayoría # de las imágenes) img = cv2.resize(img, dsize=(96, 96)) # aquí incluiríamos los pasos de preprocesamiento que quisiésemos, por ejemplo: # img = img / 255. # normalizamos la imagen entre 0 y 1 # img = mi_funcion_random_crop(img) # cortamos un trozo aleatoriamente # añadimos la imagen a nuestra estructura de datos images.append(img) print('Loading completed!')
type(images)
list
type(images[0])
numpy.ndarray
images[0].shape
(96, 96, 3)
# En el caso de cargar las imágenes así, tenemos que convertirlas a un TENSOR 4D # de N_Imágenes x Alto x Ancho x Canales. Ahora mismo es una lista de TENSORES 3D, # para convertirlo a Tensor 4D simplemente tenemos que utilizar la función # np.stack: import numpy as np images = np.stack(images)
type(images)
numpy.ndarray
images.shape
(349, 96, 96, 3)
import numpy as np # creamos la estructura de datos donde almacenaremos las imágenes cargadas images = np.zeros((n_images, 96, 96, 3)) # implementamos el bucle que recorrerá la lista e irá cargando las imágenes, # redimensionándolas y añadiéndolas a nuestra estructura de datos for i, img_path in enumerate(tqdm(list_imgs)): img = cv2.imread(img_path) # opencv carga por defecto las imágenes en modo BGR # esto lo tenemos que tener en cuenta, ya que si entrenamos # el modelo con imágenes BGR, luego tendremos que alimentarlo # con imágenes del mismo tipo para que el modelo funcione # correctamente. img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # la redimensionamos a 96x96 (este tamaño es arbitrario porque es un ejemplo, # en un caso real, estudiaríamos el tamaño que menos distorsiona la mayoría # de las imágenes) img = cv2.resize(img, dsize=(96, 96)) # añadimos la imagen a nuestra estructura de datios images[i] = img print('Loading completed!')
# En este caso no se nota la diferencia porque son pocas imágenes, pero cuando # trabajes con grandes cantidades de datos podrás ver la diferencia. # Ahora que ya los tenemos cargados, vamos a estudiar un poco la estructura de datos images.shape
(349, 96, 96, 3)
images.min()
0.0
images.max()
255.0
images.dtype
dtype(‘float64’)
# Los datos son de tipo float64, y van de 0 a 255. # Al trabajar con imágenes de carga de dataset externo en Deep Learning, solemos trabajar con datos de # tipo uint8 que van de 0 a 255, o float que van de 0 a 1. # Vamos a convertir nuestra imagen a de 0 a 1. images = images / 255.
images.min()
0.0
images.max()
1.0
Así es como podemos preparar los datos para alimentar nuestra red neuronal y entrenarla.
En este post, te hemos compartido un ejemplo de la carga de dataset externo en Deep Learning, pero, ¡aún queda mucho más por aprender! Conoce nuestro Bootcamp Full Stack Big Data, Inteligencia Artificial & Machine Learning, con el que te convertirás en un experto en poco tiempo. ¡Empieza ya!