mayo 28, 2021 10:00 am

Jesús

El desempeño de un modelo de machine learning, bien sea de la vertiente tradicional, como un árbol de decisión o regresión logística, o una red neuronal profunda (deep learning), está íntimamente atado a la correcta selección de hiperparámetros.

Afortunadamente, para el caso de modelos de machine learning, contamos con una cornucopia de herramientas para optimizar la búsqueda de los mejores hiperparámetros de un modelo dado.

¿De qué herramientas hablamos? Pues, de GridSearchCV y RandomSearchCV en scikit-learn, así como alternativas equivalentes en OpenCV.

¿Pero qué hay de las redes neuronales? ¿Hay alguna herramienta similar que podamos usar en TensorFlow?

¡Sí! Se llama Keras Tuner y en este artículo la estudiaremos a fondo.

Al finalizar este artículo habrás aprendido:

  • Cuál es la diferencia entre los parámetros e hiperparámetros de un modelo.
  • Cuáles son los dos principales tipos de hiperparámetros en machine learning.
  • Cómo usar Keras Tuner y TensorFlow para optimizar la búsqueda de hiperparámetros de un clasificador de imágenes de Fashion-MNIST.

¿Preparado? ¡Vamos a allá!

¡ATENTO!

Este post está basado en este tutorial oficial de TensorFlow. Échale un ojo, vale la pena.

No sé si te pase como a mí, pero con frecuencia me vuelvo un ocho cuando hablo de parámetros e hiperparámetros, y a veces uso los términos intercambiablemente, lo cual está mal, pues no son sinónimos.

Sin embargo, he aquí una serie de distinciones que me han sido de utilidad y, con suerte, te harán la vida más fácil a ti también:

  • Los parámetros son inherentes al modelo (por ejemplo, los pesos de una red neuronal, los “splits” o divisiones de un árbol de decisiones, o A, y b en la ecuación de la regresión lineal: Ax + b = y).
  • Los hiperparámetros controlan el proceso para hallar los parámetros. Por ejemplo: El número de iteraciones de entrenamiento, el learning rate o el número de neuronas en una capa.
  • No podemos controlar directamente los parámetros.
  • Sí podemos controlar directamente los hiperparámetros.

En pocas palabras, los parámetros son los elementos internos de un determinado modelo que, mediante el entrenamiento, queremos ajustar de manera tal que el modelo sea lo más preciso posible.

Por su parte, los hiperparámetros son los botones, palancas e interruptores que podemos prender, apagar, ajustar para dirigir al modelo en la dirección deseada.

Si un modelo es un carro, los parámetros vendrían siendo las llantas, el motor, los frenos y demás componentes mecánicos, mientras que los hiperparámetros serían el volante y los pedales. 

¿Se entiende?

Tipos de Hiperparámetros

Cuando hablamos de hiperparámetros, tenemos dos sabores:

  1. 1
    Hiperparámetros del modelo: Son aquellos que influencian la estructura misma del modelo, como el número de neuronas o la cantidad de capas en una red neuronal.
  2. 2
    Hiperparámetros del algoritmo: Son aquellos que afectan el proceso mediante el cual entrenamos un modelo. Ejemplos claros son el learning rate en Stochastic Gradient Descent (SGD) o el número de iteraciones que entrenaremos un modelo.

Suficiente teoría. Hora de arremangarse y ponerse manos a la obra.

Creación del Ambiente de Desarrollo con Anaconda

Nuestro proyecto es bastante sencillo, pues la implementación vive en un archivo llamado tune.py, dentro de la carpeta datasmarts, como ya es costumbre:

C:\USERS\JESUS\DATASMARTS\TF2-KERAS-TUNER\DATASMARTS
    tune.py

Para crear el ambiente, necesitarás tener Anaconda instalado en tu máquina. A continuación vemos el archivo de definición del ambiente en formato YAML:

Para crear un ambiente a partir de esta configuración, ejecuta:

conda env create -f env.yml

Y actívalo así:

conda activate tf2-keras-tuner

Perfecto. Continuemos.

Optimización de Hiperparámetros con Keras Tuner

Abre el archivo datasmarts/tune.py e inserta estas líneas, las cuales importan las dependencias del programa:

Para efectos ilustrativos, usaremos el ya bien conocido conjunto de datos, Fashion-MNIST, que podemos descargar con una simple instrucción, como vemos a continuación:

Evidentemente, para evitar problemas de estabilidad numérica, normalizamos los píxeles de las imágenes para que caigan en el rango [0, 1]:

La magia de Keras Tuner viene a continuación. Hay dos conceptos que tenemos que tener en cuenta:

  • HyperModel: Un hipermodelo es, básicamente, lo mismo que un modelo de Keras de toda la vida: una serie de capas unidas entre sí que dan vida a cierta arquitectura, solo que además de cumplir con esta labor, también nos permite definir el espacio de búsqueda de ciertos parámetros, lo que nos lleva al siguiente concepto.
  • HyperParameter: Un HyperParameter es una clase de Keras Tuner que nos permite especificar el espacio de búsqueda de un hiperparámetro. Para ello, identificamos el hiperparámetro a optimizar por su nombre, y luego especificamos las características del espacio de búsqueda del mismo.

La función model_builder(), expuesta en el siguiente extracto, define un hipermodelo en el que optimizaremos dos hiperparámetros:

  • El número de unidades de la primera capa densa, para lo cual probaremos valores de 32 en 32, en el rango [32, 512] (es decir, 32, 64, 96, …, 512).
  • El learning rate del optimizador (en este caso, Adam), cuyo espacio de búsqueda no es un rango, sino las siguientes opciones: 0.01, 0.001, 0.0001, 0.00001.

Ahora tenemos que definir el algoritmo de optimización como tal. En Keras Tuner contamos con varias opciones (que exploraremos en otros artículos futuros), siendo una de ellas Hyperband

¿Cómo funciona? Similar a un torneo de eliminación, (como los octavos, cuartos, etc, de la Champions League o la Copa Mundial de la FIFA). En este caso, los parámetros que tenemos que pasar a kt.Hyperband(), son:

  • La función para construir hipermodelos.
  • La métrica objetivo que buscamos optimizar (en este caso, val_accuracy).
  • El número máximo de iteraciones que entrenaremos cada modelo candidato.
  • El factor que nos ayuda a controlar cuántos modelos pasan a la siguiente ronda de optimización.
  • Un directorio donde guardaremos los logs y demás resultados de cada experimento.
  • El nombre del proyecto.
  • Un flag para sobrescribir o no los resultados de los experimentos.

Hyperband es a Keras Tuner lo que GridSearchCV es a scikit-learn.

Pararemos la optimización si no vemos mejoría por más de 5 iteraciones consecutivas. Para ello instanciamos un callback EarlyStopping, así:

Ahora, iniciaremos la búsqueda invocando el método .search():

¡ATENTO!

Los 15 epochs definidos en kt.Hyperband aplican para cada posible modelo candidato, mientras que los 50 epochs pasados al método .search() significa que correremos 50 iteraciones del algoritmo de búsqueda.

Extraemos los mejores hiperparámetros arrojados por la búsqueda:

Imprimimos un mensaje con los valores óptimos de dichos hiperparámetros:

Ahora, construimos un modelo con los mejores hiperparámetros y lo entrenamos por 50 epochs:

De este modelo recién entrenado extraeremos el número de epochs óptimo, con base al valor de val_accuracy:

Teniendo los mejores hiperparámetros como resultado de la búsqueda con Hyperband, y el número de epochs óptimo, entrenemos el mejor modelo posible:

Finalmente, evaluemos el mejor modelo en los datos de prueba:

Corre el programa así (ubicado en la raíz del proyecto):

python datasmarts/tune.py

¡ATENTO!

Lo mejor es que uses una GPU, de ser posible, para correr el programa, puesto que de lo contrario, demorará horas. En mi GPU se tomó unos 15 minutos en finalizar.

Veremos en la terminal el siguiente mensaje:

La búsqueda de hiperparámetros se ha completado. El número óptimo de neuronas en la primera capa de la red es 352 y el learning rate ideal para el optimizador es 0.001

También notaremos que el número ideal de epochs es 30:

Número óptimo de epochs: 30

Finalmente, los resultados de la evaluación en el conjunto de pruebas es:

Pérdida de prueba: 0.44900094513595107
Exactitud de prueba: 88.26%

Nada mal, ¿eh? Especialmente si consideramos lo chiquita que es la red. 

Resumen

Hoy aprendimos que, al igual que en machine learning, y en librerías seminales como scikit-learn y OpenCV, podemos optimizar los hiperparámetros de una red neuronal directamente en TensorFlow, todo gracias a Keras Tuner.

Sin embargo, como todo en el mundo de deep learning, establecer las bases o la estructura de dicha estructura no es tan directo como quisiéramos, aunque, la verdad sea dicha, tampoco es tan traumático.

¿Qué necesitamos hacer? Principalmente dos cosas:

  • Definir un hipermodelo, que no es más que una estructura o modelo de red neuronal que además de diseñar la arquitectura de una red, también especifica el espacio de búsqueda de sus hiperparámetros.
  • Definir un algoritmo de optimización o búsqueda de hiperparámetros. En este caso usamos Hyperband, que implementa, a grosso modo, una especie de torneo de eliminación por rondas, donde solo los mejores candidatos sobreviven.

Al final nuestra búsqueda nos condujo a una red 88.26% precisa, lo cual no está mal, considerando su reducido tamaño.

Ahora bien, ¿por qué no te animas a modificar el código para optimizar un hipermodelo de una red convolucional? Después de todo, las CNNs son las más adecuadas para trabajar con imágenes. Aquí te dejo el código:

¡Nos vemos!

Sobre el Autor

Jesús Martínez es el creador de DataSmarts, un lugar para los apasionados por computer vision y machine learning. Cuando no se encuentra bloggeando, jugando con algún algoritmo o trabajando en un proyecto (muy) cool, disfruta escuchar a The Beatles, leer o viajar por carretera.

Paso 2/2: Celebra tu NUEVO EMPLEO en Machine Learning ?

A %d blogueros les gusta esto: