Notice: La función wp_enqueue_script ha sido llamada de forma incorrecta. Los scripts y estilos no se deberían registrar o poner en cola hasta que se carguen los ganchos wp_enqueue_scripts, admin_enqueue_scripts y login_enqueue_scripts. Este aviso ha sido activado por la gestión de nfd_wpnavbar_setting. Por favor, ve depuración en WordPress para más información. (Este mensaje fue añadido en la versión 3.3.0). in /home1/spotsail/public_html/martra/wp-includes/functions.php on line 6078
Crear un modelo ‘Multiple Outputs’ con el API funcional de Keras. – Pere Martra
No se han encontrado widgets en la barra lateral
Modelo Keras Multi OutputModelo API Keras

Lo más normal es que cuando empezamos a trabajar con Tensorflow utilicemos el formato secuencial para crear Modelos usando la librería Keras. Con los modelos secuenciales podemos solucionar multitud de problemas en todos los campos del deep Learning, tanto sean de reconocimiento o clasificación de imágenes, Natural Language Processing, Forecasting de series…. son unos modelos lo suficientemente potentes como para ser usados en la mayoría de los problemas.

Pero hay veces que necesitamos ir un poco mas lejos en el uso de Keras con TensorFlow y podemos usar el API para la creación de modelos, que nos abre un mundo muy amplio, con muchas más posibilidades, que no teníamos al usar modelos secuenciales.

En este artículo vamos a ver la creación de un Modelo capaz de predecir dos variables diferentes usando los mismos datos, y el mismo proceso de aprendizaje, compartiendo gran parte de las capas del modelo.

Es decir, vamos a crear un modelo Multi Salida con dos ramas de capas. Tal como podemos ver en la imagen:

Modelo Keras Multi Output
Modelo API Keras

El modelo está formado por una capa de entrada, seguida por dos capas densas que son compartidas. Estas tres capas son la parte común del modelo. A partir de aquí, el modelo, se divide en dos ramas diferentes. En una de las ramas encontramos la capa de salida de la variable de clasificación. La otra rama está compuesta por una capa Densa y la capa de salida que predice la variable re regresión.

El código completo se puede encontrar en Kaggle: https://www.kaggle.com/code/peremartramanonellas/guide-multiple-outputs-with-keras-functional-api. En un Notebook qué se puede ejecutar y que utiliza un Dataset para predecir el tipo de vino como variable de clasificación y la calidad del vino como variable de regresión.

En este artículo vamos a ver tan solo como generar y ejecutar el modelo. El tratamiento de datos y la posterior evaluación del modelo, así como ideas de cómo mejorarlo, se pueden encontrar en el notebook de Kaggle.

El problema a solucionar.

He usado un Dataset de Kaggle que contiene información sobre vinos. Son datos en formato tabular, con 11 columnas que se pueden considerar features y dos que serán nuestras labels.

Como primer label he seleccionado la calidad del vino (quality), que va de 0 a 9 y he decidido tratarla como si fuera una variable de regresión y no una de clasificación, ya que es una variable en la que el incremento es importante y significa que el vino es mejor.

El segundo label es el tipo de vino (type), que indica si el vino es blanco o negro. Esta es claramente una variable de clasificación. Así que tenemos dos variables de diferente tipo a predecir en un solo modelo.


type
fixed acidityvolatile aciditycitric acidresidual sugarchloridesfree sulfur dioxidetotal sulfur dioxidedensitypHsulphatesalcoholquality
007.00.2700.3620.70.04545.0170.01.001003.000.458.86
106.30.3000.341.60.04914.0132.00.994003.300.499.56
208.10.2800.406.90.05030.097.00.995103.260.4410.16
307.20.2300.328.50.05847.0186.00.995603.190.409.96
407.20.2300.328.50.05847.0186.00.995603.190.409.96
649216.20.6000.082.00.09032.044.00.994903.450.5810.55
649315.90.5500.102.20.06239.051.00.995123.52NaN11.26
649416.30.5100.132.30.07629.040.00.995743.420.7511.06
649515.90.6450.122.00.07532.044.00.995473.570.7110.25
649616.00.3100.473.60.06718.042.00.995493.390.6611.06
Dataset, después de ser tratado.

Visto el Dataset pasamos a la construcción del modelo.

#Empezamos con una capa de entrada de tipo Input. 
inputs = tf.keras.layers.Input(shape=(11,))

#Añadimos dos capas densas, que serán comunes para todo el modelo. 
#La primera capa a la derecha recibe la capa (inputs). Mientras que la segunda
#recibe el conjunto de capas (x). 
x = Dense(units=32, activation='relu')(inputs)
x = Dense(units=32, activation='relu')(x)

#Añadimos la capa de salida para la variable de clasificación. 
#Como podéis ver recibe el conjunto de capas (x). Que contiene 
#la capa de entrada y las capas densas. 
y_t_layer = Dense(units = 1, activation='sigmoid', name='y_t_layer')(x)

#Aquí el modelo empieza la segunda rama. Con una capa densa que recibe el conjunto de capas (x)
#Con esto ya tenemos que a partir de la última capa que forma el conjunto de capas (x)
#se ha añadido una capa de salida y ahora esta capa densa. 
quality_layer=Dense(units=64, name='quality_layer', activation='relu')(x)

#La capa de salida para la variable que predice la calidad del vino. Se añade déspues del grupo 
#de capas(quality_layer) que contiene todas las capas de (x) mas la densa especifica de esta rama.  
y_q_layer = Dense(units=1, name='y_q_layer')(quality_layer)

#TPOara crear el modelo tenemos que indicar las entradas y salidas. 
#En este modelo tenemos tan solo una entrada, pero con el API podemos definir modelos multientrada. 
#El nombre de los outputs es el mismo que el de las variables y los nombres internos de las capas. 
model = Model(inputs=inputs, outputs=[y_q_layer, y_t_layer])

#He probado con dos optimizadores. Sin jugar demasiado me ha funcionado mejor Adam. 
optimizer = tf.keras.optimizers.RMSprop(learning_rate=0.0001)
#optimizer = tf.keras.optimizers.Adam()

#Al compilar el modelo se le tiene que pasar dos diccionarios que contenga
#las funciones de loss y métricas de las variables a predecir. El nombre 
# de las variables del diccionario debe coincidir con el nombre interno de las capas. 
#To compile the model we use two dictionaries, to indicate the loss functions and metrics 
#for each output layer. Note that the name of the layer must be the same than the 
#internal name of the layer. 
model.compile(optimizer=optimizer, 
              loss = {'y_t_layer' : 'binary_crossentropy', 
                      'y_q_layer' : 'mse'
                     },
              metrics = {'y_t_layer' : 'accuracy', 
                         'y_q_layer': tf.keras.metrics.RootMeanSquaredError()
                       }
             )

Como se puede ver, crear un modelo de este tipo no es nada complicado y nos abre un mundo de posibilidades nuevas si lo comparamos con los modelos secuenciales.

Se pueden encontrar todas las explicaciones en los comentarios del código. Pero me gustaría remarcar un par de cosas.

Suelo emplear el mismo nombre para el nombre interno de las capas y las variables que lo contienen. No tan solo para que código quede más claro. Cuando indicamos la función de loss y las métricas debemos utilizar el nombre interno de la capa para relacionaros. Al indicar los outputs debemos indicar el nombre de las variables que contienen las capas. Prefiero tener siempre el mismo y me ahorro confusiones.

Podemos usar diferentes funciones de perdida y métricas para cada una de los outputs del modelo. Se indican en dos listas, una para las funciones de perdida, y otra para las métricas, que se le pasan a la función compile del modelo.

model.compile(optimizer=optimizer, 
              loss = {'y_t_layer' : 'binary_crossentropy', 
                      'y_q_layer' : 'mse'
                     },
              metrics = {'y_t_layer' : 'accuracy', 
                         'y_q_layer': tf.keras.metrics.RootMeanSquaredError()
                       }
             )

¿Para qué podemos usar los modelos Multi Output?

No pretendo dar una respuesta completa, ya que se trata tan solo de mi visión, y Data Scientists con más experiencia pueden encontrarles más utilidades.

Este tipo de modelo es muy útil en entornos donde se deba realizar entrenos periódicos con gran volumen de datos para predecir más de una variable. El tiempo ahorrado si lo comparamos con entrenar dos o tres modelos diferentes puede ser muy significativo, no tan solo en tiempo, sino en coste.

También pueden ahorrar mucho tiempo y proceso en entornos donde se deban ejecutar una gran cantidad de predicciones de forma repetitiva y el resultado de estas sea de más de una variable.

Como contrapartida cuestan más de tunear, ya que por ejemplo es más complicado dar con un learning rate que pueda ser óptimo para todas las variables.

Conclusión.

Un tipo de modelo que es sencillo de crear y puede ahorrar mucho tiempo de proceso.

Espero ir publicando, a partir de ahora, muchas más técnicas un poco más avanzadas de Tensorflow, así que si os interesa el tema podéis suscribiros al blog, o seguirme en mi perfil de Kaggle.

Pere Martra | Tensorflow Certified Developer

Fine-Tuning eficiente con LoRA. Entrena de forma óptima los Grandes Modelos de Lenguaje.

LoRA es una de las técnicas más eficientes y efectivas de Fine-Tuning aplicable a Grandes Modelos de Lenguaje que existe Read more

Kurond. Una criatura ineficiente.

Kurond ha sido mi primera criatura creada para moverse con ML Agents. Es ineficiente por que su cuerpo esta MAL Read more

Creación de un sistema de comentarios con LangChain y OpenAI.

Como disclaimer me gustaría indicar que este artículo es tan solo un ejemplo creado para ver como funciona la herramienta Read more

Curso practico de IA sin Prerrequisitos.
Curso IA sin prerrequisitos

Introducción al apasionante mundo de la I.A. mediante Machine Learning, sin necesidad de tener conocimientos previos de Python o Algrebra. Read more

Por Martra

Un comentario en «Crear un modelo ‘Multiple Outputs’ con el API funcional de Keras.»

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *