1 Introducción

Las herramientas computaciones han venido avanzando a pasos agigantados en la última década, lo cual ha permitido que los diferentes dispositivos electrónicos a los que tenemos acceso permitan tener a disposición una mayor cantidad de recursos ocupando a la vez una menor cantidad de espacio y a un costo significativamente menor en comparación con los primeros dispositivos que salieron al mercado, dando la posibilidad a las masas y a pequeñas empresas de acceder a varios de estos instrumentos tecnológicos, y así, permitiendo la elaboración de proyectos más complejos con ayuda de estos implementos.

Con esto, aprovechando las herramientas tecnológicas que se tienen a la mano, se va a abordar el problema de analizar un conjunto de imágenes para determinar si las personas que están retratadas en estas están empleando gafas, y para conseguir esto se van a apelar a una técnica de aprendizaje estadístico muy usada hoy en día para el trabajo con imágenes y videos: las redes neuronales convolucionales, las cuales, en particular, son muy útiles para llevar a cabo tareas de clasificación de imágenes.

2 Documentación

Para poder llevar a cabo la clasificación de imágenes de personas según si están luciendo gafas o no, es necesario contar con varios centenares de fotos de personas que permitan alimentar el algoritmo. Además, se debe tener en cuenta que van a existir dos conjuntos de imágenes diferentes: uno de entrenamiento, que contiene dos mil ciento dieciocho imágenes y con el cual se podrá generar el algoritmo que realice la clasificación; un conjunto de validación con 495 imágenes; y otro de prueba, compuesto por seiscientas cuarenta imágenes, y con el cual se puede verificar si el algoritmo entrenado con el conjunto anterior hace la tarea para la cual fue creado adecuadamente.

Así, es necesario crear estas dos bases de datos, y para conseguirlo, se emplearon las siguientes tres fuentes de imágenes:

3 Herramientas y materiales

3.1 Materiales principales

Para la realización de este informe técnico, así como el planteamiento de la mayoría de los modelos predictivos que se presentarán más adelante se empleó la versión 4.0.5 de \(\color{#00008b}{\textsf{R}}\), el cual es un software de programación especializado en estadística y ciencia de datos. Además, para la escritura del código de este lenguaje se empleó la versión 2021.09.1 del entorno de desarrollo integrado \(\color{#1ac5ff}{\textsf{R}}\)\(\color{#696969}{\textsf{Studio}}\). Por otro lado, para el procesamiento de las imágenes, de manera que tuvieran un formato adecuado para poder entrenar al algoritmo de clasificación y también la creación del mismo modelo, se usó a \(\color{cyan}{\textsf{Python}}\), que es un lenguaje de programación muy popular y con uso en diversas áreas como la ciencia de datos. Para ello, se usaron dos entornos: el primero es \(\color{#1ac5ff}{\textsf{R}}\)\(\color{#696969}{\textsf{Studio}}\) (para el procesamiento de las imágenes) y el segundo es \(\color{orange}{\textsf{Colaboratory}}\). Asimismo, se debe destacar que se usó al repositorio en línea \(\textsf{GitHub}\) para poder guardar y compartir el código entre los autores de este trabajo, así como \(\textsf{Google Drive}\) para el almacenamiento de las diferentes imágenes.

4 Guía de Git-Hub y Google Drive

4.1 Introducción

¡Bienvenido! En este repositorio usted podrá encontrar lo relacionado con la realización de un modelo de clasificación para determinar si una persona retratada en una fotografía porta gafas o no, el cual fue desarrollado a partir de redes neuronales convolucionales. A continuación se describen algunos archivos de este repositorio, de manera que usted pueda ubicar fácilmente los documentos que aquí reposan.

4.2 Guía de GitHub

A continuación se muestran los documentos que pueden ser encontrados en el repositorio de Git-Hub, el cual puede ser accedido haciendo clic aquí.

  1. Gafas. Carpeta en la que almacen documentos importantes para la creación del informe técnico de este proyecto 1.1. Entre_Procesado.jpg. Imagen de ejemplo del conjunto de entrenamiento después de procesar, es decir, haciendo escalado y llevándolo a escala de grises. 1.2. Entre_SinProcesar.jpg. Imagen de ejemplo del conjunto de entrenamiento sin procesar, es decir, tal y como fue obtenida de la red. 1.3. Gajas.Rproj. Archivo del lenguaje de programación R que permite la existencia de un proyecto que abarque todos estos documentos dentro de R Studio para poder generar el reporte técnico. 1.4. Informe_Tecnico.Rmd. Documento de R Markdown en el que se escribe el informe técnico que va a ser entregado. 1.5. Infore_Tecnico.html. Documento HTML legible para poder observar el informe técnico. Este documento puede ser visualizado y leído por cualquier persona al ser publicado en R Pubs. 1.6. MatrizC.png. Fotografía con la matriz de confusión obtenida en el conjunto de validación empleada para poder adjuntarla en el informe técnico. 1.7. ModelAccuracy.png. Imagen que muestra la exactitud del modelo en los conjuntos de entrenamiento y de validación. 1.8. ModelLoss.png. Imagen empleada para determinar la pérdida del modelo en los conjuntos de entrenamiento y validación para ser adjuntada en el informe técnico. 1.9. ProcesamientoDos.py. Programa de Python que toma las imágenes del conjunto de entrenamiento obtenidas de Kaggle para pasarlas a escala de grises y reescalarlas a unas dimensiones estándar. 1.10. ProcesamientoDos.py. Programa de Python que toma las imágenes del CMU de la Universidad de California en Irvine (UCI) para reescalarlas a unas dimensiones estándar. 1.11. ProcesamientoUno.py. Programa de Python que toma las imágenes del conjunto de entrenamiento obtenidas de Google Images para pasarlas a escala de grises y reescalarlas a unas dimensiones estándar. 1.12. Resultado_Ind.PNG. Ejemplo del resultado del modelo predictivo con una de las imágenes del conjunto de validación. 1.13. Samples-of-CMU-faces-images-dataset.png. Imagen que agrupa varias imágenes del conjunto de validación para mostrar las diferentes expresiones faciales que pueden existir en este conjunto, en el que se observa como las personas pueden tener o no gafas y diferentes expresiones y orientes del rostro. Se generó para poder ser adjuntada en el informe técnico. 1.14. image159.pgm. Imagen del conjunto de validación empleada para mostrar lo que se realizó con su procesamiento en el archivo ProcesamientoTres.py. 1.15. image60.pgm. Imagen del conjunto de validación empleada para mostrar lo que se realizó con su procesamiento en el archivo ProcesamientoTres.py.

  2. Modelo_Python. En esta carpeta se encuentran tres archivos de Python con los que se desarrolla el modelo de clasificación empleando redes neuronales convolucionales. Dichos archivos son: 2.1. Modelo_Preddiciones.ipynb. Este archivo es un notebook en el que se aborda el testeo del modelo que ha sido entrenado con las imágenes del dataset CMU de la base de datos para trabajos con aprendizaje automático de la Universidad de California en Irvine (UCI) y se muestra la matriz de confusión asociada. 2.2. Modelo_TAE_Trabajo3.ipynn. Este archivo es un notebook de Python en los que se explica y se desarrolla el modelo creado para la clasificación de fotografías en función de si las personas retratadas en estas lucen gafas o no. 2.3. modelo.h5. Es un documento que almacena información relacionada con la creación del modelo.

4.3 Guía de Google Drive

Dado que GitHub no permite que se suban archivos o carpetas que superen un máximo de tamaño, fue necesario crear una carpeta de Drive en la que se subieran todas las fotos que fueron empleadas para este proyecto en sus dos versiones: sin procesar y procesada, de manera que a continuación se explican las carpetas existentes que faciliten la orientación en dicha carpeta general de Google Drive que puede ser accesada haciendo clic aquí:

  1. Train. Esta carpeta toma todas las fotografías que fueron empleadas para entrenar el modelo y las divide en dos subcarpetas según las personas retratadas en estas portan gafas o no, de tal manera que el algoritmo pueda identificar los aspectos importantes de cada conjunto de cara a aprender cómo realizar buenas predicciones.
  2. Procesadas_Fotos. Carpeta con todas las fotografías que fueron obtenidas en Google Images en escala de grises y reescaladas.
  3. Procesafas_Faces. Carpeta con las fotografías de la UCI que fueron empleadas para validar el modelo con reescalamiento de sus dimensiones.
  4. Predicción. Imágenes del conjunto de entrenamiento clasificadas en función de si las personas que aparecen en estas llevan puestas gafas o no.
  5. Kaggle_NoGafas. Imágenes obtenidas de Kaggle procesadas y conteniendo únicamente personas sin gafas.
  6. KaggleGafas. Imágenes obtenidas de Kaggle procesadas y conteniendo únicamente personas sin gafas.
  7. Kaggle. Imágenes obtenidas de Kaggle de personas con y sin gafas y sin procesar, es decir, en sus condiciones originales tal y como fueron descargadas de la plataforma.
  8. Fotos. Imágenes obtenidas de Google Images de personas con y sin gafas y sin procesar, en sus condiciones originales tal y como fueron descargadas.
  9. Adiciones_NoGafas. Imágenes adicionales que se descargaron de Google Images de personas que no usan gafas y que se obtuvieron luego de un primer modelo para poder mejorar las métricas asociadas a este.
  10. Adiciones_Gafas. Imágenes adicionales que se descargaron de Google Images de personas que usan gafas y que se obtuvieron luego de un primer modelo para poder mejorar las métricas asociadas a este.

4.4 Materiales secundarios

Vale la pena mencionar los paquetes de \(\color{#00008b}{\textsf{R}}\) que más se emplearon en el marco de este trabajo para conseguir el desarrollo del modelo predictivo del número de vehículos registrados en el RUNT en el 2018:

  • \(\color{purple}{\texttt{caret}}\). Versión 6.0-90 de octubre de 2021. Este paquete de \(\color{#00008b}{\textsf{R}}\) resalta como el más importante de todos, puesto que con él fue posible desarrollar algunos de los modelos que se presentarán más adelante. Este paquete es útil para la creación de modelos de clasificación y regresión, así como para la generación de gráficos que permitan estudiar los resultados que se obtienen con sus funciones. Este un paquete desarrollado por el R Core Team (el equipo base que ayuda a desarrollar y mantener al lenguaje R), Max Kuhn, Jed Wing, Steve Weston, Andre Williams, Chris Keefer, Allan Engelhardt, Tony Cooper y Breton Kenkel, entre otros.

  • \(\color{purple}{\texttt{DT}}\). Versión 0.20 Este paquete de \(\color{#00008b}{\textsf{R}}\) permite formatear tablas creadas con código de \(\color{#00008b}{\textsf{R}}\) para luego ser presentadas con un estilo sobrio, elegante y sencillo, de forma que los lectores puedan entender amigablemente las tablas presentadas.

  • \(\color{purple}{\texttt{tidyverse}}\). Versión 1.3.1. Este es un paquete de \(\color{#00008b}{\textsf{R}}\) desarrollado por Hadley Wickham que incluye otros paquetes como \(\texttt{dplyr}\) y \(\texttt{ggplot2}\), que fueron usados con frecuencia en este trabajo y que facilitan el manejo, análisis, transformación de bases de datos, así como la creación de gráficos elegantes y llamativos.

  • \(\color{purple}{\texttt{cv2}}\). Versión 4.5.5.62.. También conocido como \(\texttt{OpenCV}\), es un modulo de \(\color{cyan}{\textsf{Python}}\) enfocado a trabajas relacionados como visión artificial y que fue empleado en este trabajo para poder realizar el procesamiento inicial de las fotografías de la base de datos.

  • \(\color{purple}{\texttt{glob}}\). Es un modulo de \(\color{cyan}{\textsf{Python}}\) que resulta útil para el trabajo con direcciones de archivos y carpetas en un computador y que en este caso fue importante durante la etapa de preprocesamiento de imágenes para poderlas listas a varias de ellas y no tener que hacer el trabajo de forma manual con cada imágen.

  • \(\color{purple}{\texttt{os}}\). Es un modulo de \(\color{cyan}{\textsf{Python}}\) que resulta útil para el trabajo con direcciones de archivos y carpetas en un computador y que en este caso fue importante durante la etapa de preprocesamiento de imágenes para poderlas ubicar en las carpetas en las que estabas ubicadas y situarlas en un nuevo fólder después de ser procesadas.

  • \(\color{purple}{\texttt{Numpy}}\). Es un módulo de \(\color{cyan}{\textsf{Python}}\) de procesamiento de matrices de propósito general. Proporciona un objeto de matriz multidimensional de alto rendimiento y herramientas para trabajar con estas matrices. Es el paquete fundamental para la computación científica con \(\color{cyan}{\textsf{Python}}\).

  • \(\color{purple}{\texttt{TensorFlow}}\). Es una plataforma de \(\color{cyan}{\textsf{Python}}\) de código abierto de extremo a extremo para el aprendizaje automático. Cuenta con un ecosistema integral y flexible de herramientas, bibliotecas y recursos de la comunidad que permite que los investigadores innoven con el aprendizaje automático y los desarrolladores creen e implementen aplicaciones con tecnología de aprendizaje automático fácilmente.

  • \(\color{purple}{\texttt{PyTorch}}\). Es un paquete de \(\color{cyan}{\textsf{Python}}\) que proporciona dos características de alto nivel: Cálculo de tensor (como NumPy) con fuerte aceleración de GPU, y Redes neuronales profundas construidas en un sistema de autograduación basado en cinta.

  • \(\color{purple}{\texttt{Matplotlib}}\) es una biblioteca completa para crear visualizaciones estáticas, animadas e interactivas en \(\color{cyan}{\textsf{Python}}\).

  • \(\color{purple}{\texttt{Keras}}\) es una biblioteca de Redes Neuronales de Código Abierto escrita en \(\color{cyan}{\textsf{Python}}\). Es capaz de ejecutarse sobre TensorFlow, Microsoft Cognitive Toolkit o Theano. Está especialmente diseñada para posibilitar la experimentación en más o menos poco tiempo con redes de Aprendizaje Profundo.

5 Desarrollo

Debido a que las imágenes con las que se a abordar este trabajo poseen características muy diferentes entre sí, se las va a llevar a cada una de ellas a una escala particular, que en este corresponde a \(171 \times 213\), esto es, 171 pixeles de ancho 213 pixeles de alto, y luego se las deja en una escala de grises. A continuación se muestra el ejemplo con una imagen particular.

En la figura uno se puede ver una de las imágenes empleadas, la cual tiene las dimensiones y el color con el que fue obtenido de Internet vía \(\textsf{Google Images}\)

Nótese que el eje vertical apunta hacia cantidad positivas hacia abajo, mientras que el eje horizontal apunta hacia cantidad positivas hacia la derecha. A continuación, con el programa escrito en \(\color{cyan}{\textsf{Python}}\) se realiza su procesamiento para escalarlo y dejarlo en escala de grises, obteniendo el resultado que se observa en la figura dos:

Para el conjunto de validación aplicamos el mismo reescalamiento de la dimensión de las imágenes que a corresponde a \(171 \times 213\). Para este formato de imágenes cargamos una librería pixmap puesto que su formato (.pgm) es diferente a el de las imágenes de entrenamiento, se creó una carpeta en Drive donde se ubicaron todas las imágenes re-escaladas en el archivo descargado se encontraban 3 versiones de cada imagen, se eligió solo la imagen con mayor tamaño y mejor definición de píxeles. A está carpeta se le asigna el nombre de Procesadas_Faces y se toman dos imágenes como ejemplo una con gafas y otra sin gafas.

En este gráfico notamos el respectivo reescalamiento y el color de la imagen, como ya estaba en escala de grises no tuvimos que cambiar el formato de color del conjunto de validación.

5.1 Estadísticos descriptivos

5.1.1 Carga de las imágenes Procesadas fotos

Se utilizarán algunas funciones de la librería imager para la carga y la transformación de las imágenes.

A continuación se carga la librería imager y se indica el directorio donde se encuentran las imágenes:

El objeto filenames es una lista que contiene las imágenes. Para cargar una imagen con la funcón load.image() se debe indicar la ruta completa. Para completar el nombre de la ruta se usa la función paste0():

La dimensión de la imagen es:

171, 213, 1 and 1

Esto quiere decir que el objeto im es una sola imagen de \(171 \times 213\) pixeles.

5.1.1.1 Leer y transformar todas las imágenes

La librería imager contiene una serie de funciones para leer las imágenes de un directorio y convertirlas luego en un dataframe. Para ilustrar este proceso con un poco más de detalles se usará una función, leer_y_trs_img(), construida para mostrar cada paso de la transformación:

A continuación se muestra la función para cargar una sola imagen:

Ahora se procede a cargar todas las imágenes que se indican en filenames usando lapply():

El objeto lista_imagenes es una lista de imágenes. Cada componente es una imagen y se puede utilizar así:

Ahora se vectorizan las imágenes. Es decir, que vista la imagen como una matriz, sus columnas se ponen una debajo de la otra hasta obtener un vector. Estos vectores luego serán las filas de una matriz de datos donde cada pixel representa una variable y cada imagen representa una observación. El resultado de hacer esto para todas las imágenes es una matriz que tiene tantas filas como imágenes y tantas columnas como pixeles tengan las imágenes. La función as.numeric() aplicada sobre cada imagen devuelve un vector. Se aplica entonces la función as.numeric() sobre cada entrada del objeto lista_imagenes con la función lapply().

El resultado, imagenes_vectorizadas, es una lista de vectores que se concatenan llamando rbind() con do.call(). El resultado tiene esta dimensión:

438 and 4047

5.1.1.2 Estadísticos descriptivos - Procesadas fotos

Al tener una matriz de datos se pueden hacer todo lo que se hace con una matriz de datos. Sin embargo, el gran número de variables hace que utilizar la función summary() o la función pairs() sea poco práctico. Una aproximación puede ser generar estadísticas de resumen para cada pixel y luego ver estas estadísticas en forma de imágenes.

Veamos por ejemplo la imagen media:

De igual manera se puede calcular la imagen que representa las desviaciones estándar para cada pixel:

5.1.1.3 Descartando información poco relevante

La imagen de desviaciones estándares nos muestra varias zonas negras, donde el valor es cero. Estas zonas de baja variabilidad corresponden a pixeles poco informativos en esta muestra de imágenes. El fondo de la imagen, común para todos los individuos es, por ejemplo, una zona de baja variabilidad. Usemos el histograma de la imagen de desviaciones estándares para detectar estas zonas de baja variabilidad:

Consideraremos que pixeles con una variabilidad inferior a 0.26 no serán relevantes en los siguientes análisis. La función threshold() asigna un 0 a cada pixel cuya intensidad está por debajo de cierto valor y 1 al resto de pixeles y nos devuelve una imagen. A continuación se usa esta función especificando un valor de umbral de 0.26:

La imagen imagen_sd_tr es una máscara. Las zonas en blanco representan los pixeles que se incluirán en los análisis y las zonas en negro los pixeles que se descartarán por su baja variabilidad.

Veamos cuantos pixeles se descartan:

FALSE TRUE
395 3652

Calculemos el porcentaje de información descartada:

FALSE
9.76

Esto quiere decir que aproximadamente el 10% de los datos están en zonas de baja variabilidad.

5.1.2 Carga de las imágenes Kaggle no gafas

Se repite el mismo procedimiento para la carpeta “Kaggle_NoGafas”.

La dimensión de la imagen es:

171, 213, 1 and 1

Esto quiere decir que el objeto im es una sola imagen de \(171 \times 213\) pixeles.

5.1.2.1 Leer y transformar todas las imágenes

A continuación se muestra usa la función para cargar una sola imagen:

Ahora se procede a cargar todas las imágenes que se indican en filenames usando lapply():

El objeto lista_imagenes es una lista de imágenes. Cada componente es una imagen y se puede utilizar así:

Ahora se vectorizan las imágenes. Es decir, que vista la imagen como una matriz, sus columnas se ponen una debajo de la otra hasta obtener un vector. Estos vectores luego serán las filas de una matriz de datos donde cada pixel representa una variable y cada imagen representa una observación. El resultado de hacer esto para todas las imágenes es una matriz que tiene tantas filas como imágenes y tantas columnas como pixeles tengan las imágenes. La función as.numeric() aplicada sobre cada imagen devuelve un vector. Se aplica entonces la función as.numeric() sobre cada entrada del objeto lista_imagenes con la función lapply().

El resultado, imagenes_vectorizadas, es una lista de vectores que se concatenan llamando rbind() con do.call(). El resultado tiene esta dimensión:

662 and 4047

5.1.2.2 Estadísticos descriptivos - Kaggle Gafas

Al tener una matriz de datos se pueden hacer todo lo que se hace con una matriz de datos. Sin embargo, el gran número de variables hace que utilizar la función summary() o la función pairs() sea poco práctico. Una aproximación puede ser generar estadísticas de resumen para cada pixel y luego ver estas estadísticas en forma de imágenes.

Veamos por ejemplo la imagen media:

De igual manera se puede calcular la imagen que representa las desviaciones estándar para cada pixel:

5.1.2.3 Descartando información poco relevante

La imagen de desviaciones estándares nos muestra varias zonas negras, donde el valor es cero. Estas zonas de baja variabilidad corresponden a pixeles poco informativos en esta muestra de imágenes. El fondo de la imagen, común para todos los individuos es, por ejemplo, una zona de baja variabilidad. Usemos el histograma de la imagen de desviaciones estándares para detectar estas zonas de baja variabilidad:

Consideraremos que pixeles con una variabilidad inferior a 0.1 no serán relevantes en los siguientes análisis. La función threshold() asigna un 0 a cada pixel cuya intensidad está por debajo de cierto valor y 1 al resto de pixeles y nos devuelve una imagen. A continuación se usa esta función especificando un valor de umbral de 0.1:

La imagen imagen_sd_tr es una máscara. Las zonas en blanco representan los pixeles que se incluirán en los análisis y las zonas en negro los pixeles que se descartarán por su baja variabilidad.

Veamos cuantos pixeles se descartan:

FALSE TRUE
230 3817

Calculemos el porcentaje de información descartada:

FALSE
5.683

Esto quiere decir que aproximadamente el 6% de los datos están en zonas de baja variabilidad.

5.1.3 Carga de las imágenes Kaggle gafas

Se repite el mismo procedimiento para la carpeta “Kaggle_Gafas”.

La dimensión de la imagen es:

171, 213, 1 and 1

Esto quiere decir que el objeto im es una sola imagen de \(171 \times 213\) pixeles.

5.1.3.1 Leer y transformar todas las imágenes

A continuación se muestra usa la función para cargar una sola imagen:

Ahora se procede a cargar todas las imágenes que se indican en filenames usando lapply():

El objeto lista_imagenes es una lista de imágenes. Cada componente es una imagen y se puede utilizar así:

El resultado, imagenes_vectorizadas, es una lista de vectores que se concatenan llamando rbind() con do.call(). El resultado tiene esta dimensión:

838 and 4047

5.1.3.2 Estadísticos descriptivos Kaggle gafas

Al tener una matriz de datos se pueden hacer todo lo que se hace con una matriz de datos. Sin embargo, el gran número de variables hace que utilizar la función summary() o la función pairs() sea poco práctico. Una aproximación puede ser generar estadísticas de resumen para cada pixel y luego ver estas estadísticas en forma de imágenes.

Veamos por ejemplo la imagen media:

De igual manera se puede calcular la imagen que representa las desviaciones estándar para cada pixel:

5.1.3.3 Descartando información poco relevante

La imagen de desviaciones estándares nos muestra varias zonas negras, donde el valor es cero. Estas zonas de baja variabilidad corresponden a pixeles poco informativos en esta muestra de imágenes. El fondo de la imagen, común para todos los individuos es, por ejemplo, una zona de baja variabilidad. Usemos el histograma de la imagen de desviaciones estándares para detectar estas zonas de baja variabilidad:

Consideraremos que pixeles con una variabilidad inferior a 0.1 no serán relevantes en los siguientes análisis. La función threshold() asigna un 0 a cada pixel cuya intensidad está por debajo de cierto valor y 1 al resto de pixeles y nos devuelve una imagen. A continuación se usa esta función especificando un valor de umbral de 0.1:

La imagen imagen_sd_tr es una máscara. Las zonas en blanco representan los pixeles que se incluirán en los análisis y las zonas en negro los pixeles que se descartarán por su baja variabilidad.

Veamos cuantos pixeles se descartan:

FALSE TRUE
207 3840

Calculemos el porcentaje de información descartada:

FALSE
5.115

Esto quiere decir que aproximadamente el 5% de los datos están en zonas de baja variabilidad.

5.1.4 Carga de las imágenes Adiciones no gafas

Se repite el mismo procedimiento para la carpeta “Adiciones_NoGafas”.

La dimensión de la imagen es:

591, 612, 1 and 3

Esto quiere decir que el objeto im es una sola imagen de \(171 \times 213\) pixeles.

5.1.4.1 Leer y transformar todas las imágenes

A continuación se muestra usa la función para cargar una sola imagen:

Ahora se procede a cargar todas las imágenes que se indican en filenames usando lapply():

El objeto lista_imagenes es una lista de imágenes. Cada componente es una imagen y se puede utilizar así:

El resultado, imagenes_vectorizadas, es una lista de vectores que se concatenan llamando rbind() con do.call(). El resultado tiene esta dimensión:

59 and 4047

5.1.4.2 Estadísticos descriptivos - Adiciones no gafas

Al tener una matriz de datos se pueden hacer todo lo que se hace con una matriz de datos. Sin embargo, el gran número de variables hace que utilizar la función summary() o la función pairs() sea poco práctico. Una aproximación puede ser generar estadísticas de resumen para cada pixel y luego ver estas estadísticas en forma de imágenes.

Veamos por ejemplo la imagen media:

De igual manera se puede calcular la imagen que representa las desviaciones estándar para cada pixel:

5.1.4.3 Descartando información poco relevante

La imagen de desviaciones estándares nos muestra varias zonas negras, donde el valor es cero. Estas zonas de baja variabilidad corresponden a pixeles poco informativos en esta muestra de imágenes. El fondo de la imagen, común para todos los individuos es, por ejemplo, una zona de baja variabilidad. Usemos el histograma de la imagen de desviaciones estándares para detectar estas zonas de baja variabilidad:

Consideraremos que pixeles con una variabilidad inferior a 0.27 no serán relevantes en los siguientes análisis. La función threshold() asigna un 0 a cada pixel cuya intensidad está por debajo de cierto valor y 1 al resto de pixeles y nos devuelve una imagen. A continuación se usa esta función especificando un valor de umbral de 0.27:

La imagen imagen_sd_tr es una máscara. Las zonas en blanco representan los pixeles que se incluirán en los análisis y las zonas en negro los pixeles que se descartarán por su baja variabilidad.

Veamos cuantos pixeles se descartan:

FALSE TRUE
130 3917

Calculemos el porcentaje de información descartada:

FALSE
3.212

Esto quiere decir que aproximadamente el 3% de los datos están en zonas de baja variabilidad.

5.1.5 Carga de las imágenes Adiciones gafas

Se repite el mismo procedimiento para la carpeta “Adiciones_Gafas”.

El objeto filenames es una lista que contiene las imágenes. Para cargar una imagen con la funcón load.image() se debe indicar la ruta completa. Para completar el nombre de la ruta se usa la función paste0():

La dimensión de la imagen es:

728, 482, 1 and 3

Esto quiere decir que el objeto im es una sola imagen de \(171 \times 213\) pixeles.

5.1.5.1 Leer y transformar todas las imágenes

A continuación se muestra usa la función para cargar una sola imagen:

Ahora se procede a cargar todas las imágenes que se indican en filenames usando lapply():

El objeto lista_imagenes es una lista de imágenes. Cada componente es una imagen y se puede utilizar así:

El resultado, imagenes_vectorizadas, es una lista de vectores que se concatenan llamando rbind() con do.call(). El resultado tiene esta dimensión:

58 and 4047

5.1.5.2 Estadísticos descriptivos - Adiciones gafas

Al tener una matriz de datos se pueden hacer todo lo que se hace con una matriz de datos. Sin embargo, el gran número de variables hace que utilizar la función summary() o la función pairs() sea poco práctico. Una aproximación puede ser generar estadísticas de resumen para cada pixel y luego ver estas estadísticas en forma de imágenes.

Veamos por ejemplo la imagen media:

De igual manera se puede calcular la imagen que representa las desviaciones estándar para cada pixel:

5.1.5.3 Descartando información poco relevante

La imagen de desviaciones estándares nos muestra varias zonas negras, donde el valor es cero. Estas zonas de baja variabilidad corresponden a pixeles poco informativos en esta muestra de imágenes. El fondo de la imagen, común para todos los individuos es, por ejemplo, una zona de baja variabilidad. Usemos el histograma de la imagen de desviaciones estándares para detectar estas zonas de baja variabilidad:

Consideraremos que pixeles con una variabilidad inferior a 0.25 no serán relevantes en los siguientes análisis. La función threshold() asigna un 0 a cada pixel cuya intensidad está por debajo de cierto valor y 1 al resto de pixeles y nos devuelve una imagen. A continuación se usa esta función especificando un valor de umbral de 0.25:

La imagen imagen_sd_tr es una máscara. Las zonas en blanco representan los pixeles que se incluirán en los análisis y las zonas en negro los pixeles que se descartarán por su baja variabilidad.

Veamos cuantos pixeles se descartan:

FALSE TRUE
74 3973

Calculemos el porcentaje de información descartada:

FALSE
1.829

Esto quiere decir que aproximadamente el 2% de los datos están en zonas de baja variabilidad.

5.2 Modelo

La clasificación de imágenes es el proceso de categorizar y etiquetar grupos de píxeles o vectores dentro de una imagen según reglas específicas. La ley de categorización se puede diseñar utilizando una o más características espectrales o texturales.

Uno de los algoritmos más utilizados actualmente para esta tarea son las redes neuronales convolucionales. Una red neuronal convolucional (ConvNet o CNN) es un algoritmo de aprendizaje profundo que puede tomar una imagen de entrada, asignar importancia (pesos y sesgos aprendibles) a varios aspectos u objetos de la imagen y poder diferenciar uno del otro. El procesamiento previo requerido en una ConvNet es mucho menor en comparación con otros algoritmos de clasificación. Mientras que en los métodos primitivos los filtros se diseñan a mano, con suficiente entrenamiento, ConvNets tiene la capacidad de aprender estos filtros o características.

Para este modelo, se plantea una red convolucional secuencial (por capas), con diecinueve capas, funciones de activación Relu y Lineal, kernel de tamaño 3x3 y capas con 32, 64 y 128 neuronas. Cómo última función de activación, se tiene a una sigmoide, ya que esta es mejor para problemas de clasificación binaria.

Se compila el modelo con algoritmo de optimización en la tasa de aprendizaje, adam, función de pérdida binary crossentropy y exactitud como métrica. Obteniendo los siguientes resultados:

Por lo que se concluye que el modelo ajusta bien tanto el conjunto de entrenamiento como el de validación.

Nota: el modelo se encuentra en el archivo Modelo_TAE_Trabajo3 en la carpeta Modelo_Python en github.

5.3 Resultados

A continuación se muestra una imagen cualquiera del conjunto de prueba, la clasificación real a la que pertenece y la clasificación según el modelo:

Además, la matriz de confusión:

Donde se obtiene que el modelo clasificó 267 de 320 fotos sin gafas correctamente, y 164 de 320 imágenes con gafas correctamente.

Nota: los resultados detallados se encuentran en el archivo Modelo_Predicciones en la carpeta Modelo_Python en github.

5.4 Preguntas

5.4.1 1. ¿Qué afecta la capacidad del modelo en el conjunto de validación?

Afecta en qué tan bien se representó en el conjunto de entrenamiento la información a ser evaluada en el conjunto de validación, a la información que realmente debió ser aprendida. Para este caso, el conjunto de validación disponía de imágenes de personas tomadas con diferentes poses (recta, izquierda, derecha, arriba), mientras que en el dataset de entrenamiento no disponía exactamente de personas en las mismas poses, especialmente hacia arriba, pues estas fueron más difíciles de hallar.

5.4.2 2. ¿Hay alguna característica de las imágenes que mejore la capacidad de respuesta?

Para el modelo debe ser más fácil detectar que tiene gafas cuando el individuo de la imagen usa gafas oscuras, ya que es un objeto más fácil de identificar a diferencia de las gafas transparentes; la calidad y el tamaño de la imagen también mejora la capacidad del modelo: si las imágenes están en el mismo tamaño y tienen buena calidad claramente el modelo se desempeñará mejor; y por supuesto, qué tan cerca esté la cara hace que sea más sencillo reconocer patrones en el rostro del individuo, cosa que pudo ser un poco más complicado con el conjunto de CMU, ya que gran parte de los rostros del conjunto de entrenamiento y validación estaban mucho más cerca de la cámara a diferencia de las de CMU.

6 Referencias