Deep Learning con Python: Introducción a TensorFlow (Parte III)

Thursday, July 26, 2018

Deep Learning con Python: Introducción a TensorFlow (Parte III)

Escrito por Enrique Blanco (Investigador en CDO) y Fran Ramírez (Investigador de seguridad  informática en Eleven Paths)

Hemos llegado al tercer y último artículo de nuestra serie de introducción al Deep Learning con Python haciendo uso del framework TensorFlow. Recordemos que en el artículo anterior, Deep Learning con Python: Introducción a TensorFlow (Parte II), una vez asimilados los conceptos básicos de sesión, grafo, variable y placeholder explicados en el primer artículo Deep Learning con Python: Introducción a TensorFlow (Parte I), realizamos algunos ejemplos de regresión lineal con datasets de datos cocinados por nosotros.

Como adelantamos en el anterior post, en este artículo os mostraremos cómo definir una red convolucional para abordar la clasificación de uno de los datasets más conocidos: CIFAR-10. Para la definición del modelo de red profunda, haremos uso de Keras, una librería Python de Deep Learning que proporciona una interfaz de alto nivel con las librerías Theano y TensorFlow.
Instalar Keras es muy sencillo. Se pueden encontrar instrucciones para ello en el siguiente enlace. Además, se indica cómo abordar la instalación tanto de TensorFlow como de Theano, además de CNTK, en el caso de que se desee cambiar el backend de la librería Keras.
TensorFlow viene como el backend por defecto para Keras. Este hecho se puede comprobar en el fichero ~/.keras/keras.json:

{
    "image_dim_ordering": "tf",
    "epsilon": 1e-07,
    "floatx": "float32",
    "backend": "tensorflow"
}

Para cambiar el backend a Theano, sólo es necesario cambiar el contenido del fichero anterior por lo siguiente:

{
    "image_dim_ordering": "th",
    "epsilon": 1e-07,
    "floatx": "float32",
    "backend": "theano"
}

El data-set que vamos a usar en el siguiente Jupyter Notebook es el CIFAR-10, habitual en el entrenamiento de modelos dedicados a reconocimiento de imágenes. Está formado en 60,000 imágenes a color de 32x32 con 10 clases asignadas, por lo que obtenemos unas 6000 imágenes por clase. Las etiquetas en este dataset son: ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'].

Figura 1: Ejemplo de imágenes del CIFAR-10 dataset ordenadas por clases. 
Fuente: Computer Science University of Toronto 

En este post veremos cómo una red neuronal profunda es capaz de tener un buen comportamiento a la hora de clasificar imágenes. Incluso si el entrenamiento no se extiende demasiado, las precisiones en la clasificación pueden ser superiores al 70%.

Como ya vimos en la serie de Deep Learning vs Atari: entrena tu IA para dominar videojuegos clásicos (Parte I, Parte II y Parte III) las redes profundas tienen la capacidad de aprender funciones de abstracción a lo largo de sus niveles de abstracción. Os animamos a leer los artículos para ver distintas aplicaciones de este tipo de arquitecturas, así como para introducirse en la teoría detrás de este tipo de redes.
Por ejemplo, al entrenar una CNN profunda para clasificar imágenes, encontraremos que la primera capa se entrenará para reconocer cosas muy básicas como los bordes, la siguiente capa se entrenará para reconocer colecciones de formas, la siguiente capa se adiestrará en el reconocimiento de colecciones de formas (como ruedas, piernas, colas, caras como es nuestro caso) y la siguiente capa aprenderá incluso características de orden superior como objetos (camión, barco, perro, rana, etc.). La capacidad de generalización de este tipo de modelos es excelente, ya que se aprenden todas las características intermedias entre la entrada en bruto y la clasificación de alto nivel, que es la que obtenemos a la salida de la arquitectura.

La arquitectura que hemos usado sigue el esquema habitual para este tipo de redes:
  1. Capa(s) convolucional(es) 
  2. Capa de Pooling
  3. Capa de Flattening 
  4. Arquitectura Densa 
  5. Capa de Output
Nuestra red está compuesta por dos conjuntos de dos capas convolucionales seguidas de una capa de pooling. De la última capa de pooling se concatenan una serie de capas densas totalmente conectadas (fully-connected) que van disminuyendo su dimensionalidad hasta el número de clases que compone nuestro dataset y que queremos predecir. A continuación, incluimos un resumen de las capas del modelo, dimensionalidades y número de parámetros implicados en el entrenamiento:

Figura 2: resumen del modelo de red convolucional entrenado para la clasificación de imágenes de CIFAR-10.

Como vemos en el resumen del modelo superior, tendremos que entrenar algo más de 1,2 millones de parámetros en nuestro modelo. Con la arquitectura indicada y haciendo uso de una máquina virtual en Oracle VirtualBox con Sistema Operativo Ubuntu 16.04.4 LTS a la que se le asignaron los siguientes parámetros:

Procesador: 2x Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz,
Memoria: 8776MB (4894MB used),

tardamos 1h 9min en entrenar el modelo durante 10 épocas para conseguir una precisión del 79.05% sobre las 10,000 imágenes que constituyen el test dataset.
A continuación mostramos el .ipynb donde mostramos todos los pasos necesarios a dar para poder reproducir el ejercicio de entrenamiento de una red convolucional con CIFAR-10:



Si disponéis de tiempo para entrenar durante más de 10 épocas y de una máquina más potente que la usada para plasmar los resultados que se pueden encontrar Jupyter Notebook anterior, os animamos a jugar con la arquitectura, funciones de pérdida y optimizadores para conseguir más precisión a la hora de clasificar imágenes. Dado el tamaño del dataset y del tiempo de entrenamiento dedicado, ser capaz de clasificar correctamente aproximadamente 8 de cada 10 imágenes se puede considerar un buen registro.
Se debe tener en cuenta que cada vez que se modifique la arquitectura del modelo el checkpoint que hayáis almacenado del modelo anterior será inservible, no siendo posible retomar el entrenamiento desde el punto anterior.

Para todos aquellos que en nuestra encuesta de Twitter votasteis por la clasificación de números escritos a mano del dataset MNIST, a continuación os dejamos otro Jupyter Notebook donde, haciendo uso de un modelo lineal más sencillo al usado en CIFAR-10, somos capaces de estimar con alta tasa de acierto ante qué número nos enfrentamos.



En este último caso el modelo se ha construido haciendo única y exclusivamente uso de TensorFlow, por lo que podréis ver con mayor detalle la definición de variables en TensorFlow, la elección y definición del modelo a optimizar, la posterior construcción de la función de coste para la optimización y el método de optimización elegido. Además, se incluyen algunos ejemplos sencillos de rutinas de monitorización del entrenamiento que pueden resultar útiles.


No comments:

Post a Comment