GANs N’ Roses: escuchando el arte visual
Una Inteligencia Artificial que te permite sentir el arte visual a través del sentido del oído
Contexto
Este artículo describe el resultado del esfuerzo conjunto de cinco personas con diferentes experiencias profesionales que se unieron para desarrollar el proyecto final del curso de Deep Learning de 2021 ofrecido por Saturdays.AI, una organización sin ánimo de lucro que trata de enseñar Inteligencia Artificial a cualquiera que acepte el reto.
Antes de entrar en otros detalles, creemos que es importante responder a las siguientes preguntas: ¿quiénes somos? y ¿de dónde venimos?
- Guillermo García, estudiante de Doble Grado de Matemáticas e Informática.
- Miguel Ángel Reina, Data Analyst, Broker Operator Specialist.
- Diego Martín, Ingeniero Aeroespacial y Data Scientist.
- Sara Señorís, Física y Data Scientist.
- Borja Menéndez, Doctor en Investigación Operativa.
Dado este pequeño y merecido contexto, ya podemos contar el proyecto en sí mismo, cuyo código e implementación se puede ver en este repositorio de GitHub. ¡Allá vamos! 🚀
Motivación
Una vez hemos establecido el contexto, vamos a explicar la motivación principal de este proyecto. Para ello, te vamos a pedir que cierres los ojos y, sin abrirlos y, por tanto, sin mirar el siguiente cuadro de la Figura 1, pienses sobre qué sentimientos te evocan esta obra de arte.
Puede que te preguntes “Cómo voy a sentir el cuadro si no puedo verlo?”. Frustrante, ¿verdad? Pues acabas de vivir una situación similar a la que viven las personas con discapacidad visual en un museo. Así nació nuestra idea 💥 Y el resumen sería que este proyecto pretende que las personas puedan sentir el arte visual a través de otros sentidos, en este caso el sentido del oído.
¿Cómo podemos alcanzar este objetivo? Y, lo que es igualmente importante, ¿podemos automatizar el proceso? Nuestra hipótesis era que la Inteligencia Artificial podría dar una respuesta afirmativa a ambas preguntas y, por ello, hemos construido un proceso extremo a extremo que pretende ayudar en la situación anteriormente descrita.
De un cuadro a una melodía — El pipeline del proyecto
Una vez explicada la situación en la que nos gustaría ayudar, a continuación mostramos una imagen general del camino que sigue un cuadro para convertirse en una melodía, lo que también debería ayudar a dar una idea sobre cómo abordamos este problema para lograr un objetivo tan desafiante.
Como se puede ver en la Figura 2, hay tres pasos bien diferenciados por los que pasan los datos del cuadro antes de transformarse en una melodía.
Aunque estos pasos se van a explicar en profundidad en las siguientes secciones, vamos a hacer aquí una descripción breve y de alto nivel de todo el proceso. En primer lugar, la imagen se introduce en una Red Neuronal Convolucional (CNN, del inglés Convolutional Neural Network) que predice qué emociones son más probables que sienta un espectador al verla. Después, no podemos alimentar directamente a nuestro director de orquesta (un Transformer preentrenado) con estas emociones detectadas, ya que, al igual que a un humano normal, le resultaría muy difícil componer algo con un 50% de felicidad, un 30% de amor y un 20% de optimismo, ¿o no? La inspiración que el modelo necesita para componer la melodía final la produce la caja negra, el componente donde se produce la verdadera transformación. Pero como los buenos magos, no vamos a desvelar el truco tan fácilmente (…¡todavía! En unos párrafos lo haremos).
De cuadros a emociones
Como se ha explicado en la sección anterior, el primer paso es detectar las emociones en el cuadro de entrada. Para cumplir este primer objetivo, hemos combinado Transfer Learning con un extenso conjunto de datos anotados por humanos sobre más de 4000 pinturas, lo que ha dado lugar a una CNN que produce resultados razonables. Veamos con más detalle cada una de las partes implicadas.
En cuanto al conjunto de datos que se ha utilizado, procede de The Wikiart Emotions Dataset, un amplio conjunto de datos de pinturas anotadas teniendo en cuenta las emociones que evocan. El conjunto de datos se construyó de la siguiente manera: se presentaron varias obras de arte (más de 4000, como se ha mencionado anteriormente) de diferentes estilos occidentales a diferentes observadores, que las anotaron basándose en un conjunto de 20 emociones disponibles, además de otra información no considerada para este proyecto. Los observadores podían seleccionar más de una emoción para el mismo cuadro. Así, los datos brutos disponibles son el porcentaje de personas que anotaron cada obra de arte por emoción, de modo que podríamos tener un 0,65 de felicidad y un 0,5 de amor al mismo tiempo para un cuadro concreto. Los autores presentan varios conjuntos de datos, pero nosotros sólo consideramos los datos brutos para extraer toda la información que necesitábamos. Con esta información, construimos nuestro conjunto de datos que constaba de dos partes: todas las imágenes de los cuadros con el nombre original en el conjunto de datos y un archivo csv con información sobre el nombre original del cuadro y el porcentaje de cada emoción que evoca. Las emociones disponibles para los observadores pueden verse en la Figura 3:
Algunos de los problemas que encontramos en este dataset fueron:
- La suma de los porcentajes de emociones por cuadro no sumaba el 100%. Esto se debe a que la gente podía decir que sentía más de una emoción al ver un cuadro, por lo que al promediar las emociones entre todas las observaciones por cuadro, las puntuaciones podían sumar más de 1. Como se desea tener algo parecido a una distribución probabilística, estas puntuaciones se han transformado para que sumaran 1 por cada cuadro. Este efecto se puede conseguir utilizando una función muy conocida por los científicos de datos: softmax. Sin embargo, como esta función utiliza exponenciales, nunca asignará una probabilidad 0, aunque la puntuación inicial sea 0. ¿Es esto deseable? A primera vista, no parece razonable asignar una puntuación a una emoción si estamos seguros de que un cuadro no contiene nada relacionado con ella. Además, si se observa la Figura 4 (antes de la softmax) y la Figura 5 (después de la softmax normal), no sólo se da una puntuación positiva a las emociones con puntuación 0, sino que además esta puntuación se acerca a la asignada a otras emociones que antes tenían valores distintos de cero, como ocurre con asco y miedo (disgust y fear en inglés, respectivamente). Además, la distancia entre todas las puntuaciones se reduce, ya que queda menos valor por asignar. Por ello, se ha tratado de excluir los 0 en el cálculo de la softmax, lo que da como resultado la Figura 6.
Al tratarse de una tarea muy subjetiva, había que hacer un esfuerzo extra para equilibrar las emociones finales detectadas. Como se puede ver en la Figura 7, el conjunto de datos estaba claramente desequilibrado hacia las emociones positivas y durante las primeras versiones del modelo observamos una clara tendencia a predecir mayoritariamente emociones positivas.
En cuanto al modelo construido, utilizamos una ResNet50 como modelo base, aprovechando así su potencia para la extracción de características en imágenes. Después, y dado que nuestro problema requería un mayor aprendizaje del modelo para identificar mejor las emociones, añadimos algunas capas densas.
Por último, hay que definir el objetivo hacia el que se ha entrenado el modelo. El primer intento fue tratar este problema como uno de clasificación, intentando predecir la emoción más “popular” en un cuadro, y luego utilizar softmax como función de activación en la última capa para obtener una distribución probabilística que pudiera utilizarse en los siguientes pasos. Sin embargo, aunque fue un buen primer intento para conseguir un modelo que funcionara, nos dimos cuenta de que había dos aspectos que se podían mejorar:
- No estábamos aprovechando la valiosa información que nos proporcionaba el conjunto de datos sobre el porcentaje de cada emoción.
- Si al final queríamos una distribución probabilística, ¿por qué no predecirla directamente con los datos disponibles?
Tras considerar estos puntos, el clasificador se convirtió en un regresor que predecía directamente la puntuación asociada a cada emoción. Pero descubrimos dos problemas al ponerlo a funcionar:
- Debido a la naturaleza del conjunto de datos (muchos evaluadores con criterios diferentes y subjetivos), el modelo tenía dificultades para predecir los porcentajes con precisión. Además, ¿nos interesa que el modelo prediga exactamente los porcentajes o es suficiente con que pueda determinar las principales “direcciones” de las emociones (positividad, actividad, …)? Es más, poner el foco en la predicción de la distribución exacta estaba haciendo que no predijera estas direcciones.
- Una vez obtenida la distribución probabilística de las emociones, ¿cómo íbamos a hacer frente al hecho de la falta de un espacio estándar de emociones? Por ejemplo, los conjuntos de datos utilizados en los siguientes pasos se anotaron utilizando una lista diferente de emociones.
Basándonos en estos dos factores, ideamos una forma de unir diferentes espacios de emociones a la vez que la transformación mantuviera las “direcciones” básicas de las emociones. Esta transformación clave se explica a continuación.
Valence-Arousal — La transformación clave
Una vez descrita la necesidad surgida, expliquemos nuestra propuesta y la solución que adoptamos: el modelo de emociones valence-arousal.
La idea surgió en primer lugar del artículo que describía uno de los conjuntos de datos que utilizamos para anotar la música: el proyecto vgmidi. La base de este modelo es describir las emociones con dos dimensiones: valence (o positividad) y arousal (o intensidad), tal y como describe James Russel en su artículo de 1980 “A circumplex model of affect”. Para simplificar aún más, los vectores de la escala de valence y arousal tienen norma menor o igual a 1 (es decir, caen dentro de la circunferencia de radio 1). Para una mejor comprensión, mostramos un ejemplo de esta nueva representación en la Figura 8.
Teniendo clara la nueva representación de las emociones, ahora es el momento de explicar por qué nos resulta tan útil. Recordemos que inicialmente tenemos un vector con proporciones de n emociones. Con esto, pretendemos:
- Reducir la dimensionalidad para que las “direcciones” básicas de las emociones sean predichas correctamente por el modelo, y no las proporciones exactas en sí.
- Mapear fácilmente el espacio de n emociones a un espacio de m emociones que podría no tener relación con el espacio original.
El primer paso para cumplir estos objetivos es definir en qué lugar de la circunferencia se encuentra cada emoción del espacio original. Como se muestra en la Figura 9, que corresponde a las emociones encontradas en el conjunto de datos utilizado para entrenar la CNN, a cada sentimiento se le asigna una ubicación en el borde de la circunferencia de acuerdo con su valor de valence-arousal. Matemáticamente, esto equivale a asignar un ángulo a cada emoción.
Para entender mejor el resto de las transformaciones necesarias, definamos un conjunto más sencillo de emociones: felicidad, amor, miedo y tristeza. Como hicimos con el conjunto anterior, asignemos cada sentimiento a un lugar de la circunferencia:
Ahora que el lugar de cada emoción del espacio original está claro, ¿cómo definimos las coordenadas del vector n-dimensional de entrada? Consideremos el siguiente ejemplo:
En primer lugar, como se ve en la Figura 12, cada emoción (o cada coordenada del vector original) se asocia a un vector en el nuevo espacio.
Para ello se utiliza la puntuación/proporción de cada emoción como módulo del vector, y el ángulo predefinido de la emoción como ángulo del vector. Estas son las coordenadas polares del vector, por lo que para obtener las coordenadas cartesianas se utilizan cosenos y senos, como se recuerda en la Figura 13.
Después de obtener un vector por emoción, ¿cómo obtenemos la representación final del vector original? Decidimos simplemente sumar todos los vectores calculados anteriormente. Al hacer esto, las emociones con mayores proporciones tendrán un mayor impacto en las coordenadas finales, terminando con una buena representación resumida de la entrada original, como se ve en la Figura 14.
Como habrás observado, todas las transformaciones realizadas dan como resultado un procedimiento razonable y comprensible para el ser humano, de manera que podamos mapear cualquier conjunto de emociones a un espacio común de dos dimensiones; que resume correctamente las principales “direcciones” de las emociones y facilita el trabajo con diferentes espacios. Así, el modelo de la CNN se entrena para predecir las coordenadas de valence-arousal de un cuadro, que luego se utiliza en el siguiente paso como selector de cómo otro modelo de IA generaría la melodía final.
De emociones a una inspiración inicial
Las secciones anteriores muestran que somos capaces de determinar las coordenadas de valence-arousal de un cuadro de entrada. Una vez recuperada la información de la parte de la imagen, es el momento de pasarla a otra dimensión: la música. Como se ha mencionado al principio, nuestro director de orquesta necesita una inspiración inicial para componer la melodía final, y aquí es donde obtendremos la inspiración. Esta inicialización es una pieza musical de 5 segundos que se cree que evoca emociones muy similares a las detectadas en el cuadro de entrada. Después, la creatividad del modelo genera el resto de la melodía.
Podemos identificar rápidamente dos tareas principales para encontrar la inicialización más adecuada:
- Obtener una lista de canciones anotadas por las emociones que evocan. Se puede llevar a cabo gracias a la existencia de múltiples conjuntos de datos. El primero es el proyecto vgmidi, donde los MIDIs ya están anotados utilizando la escala de valence-arousal. Otro que se ha utilizado es emotify, que contiene música anotada en base a un nuevo conjunto de emociones traducido por nosotros a valence-arousal siguiendo exactamente el mismo proceso que con las anotaciones de los cuadros. A estas alturas ya te habrás dado cuenta de lo versátil que es la escala de valence-arousal 😉
- Definir lo que significa “adecuado” en este contexto. Para resolver esto, se puede imaginar que, si tenemos la representación vectorial en valence-arousal de la imagen así como de la pieza de música, una forma natural de definir la cercanía es por la distancia euclidiana. Así, basta con calcular las distancias del vector del cuadro a todos los vectores de las piezas y obtener la más cercana. Para encontrar la pieza más adecuada (la más cercana) de forma muy eficiente y sencilla, hemos utilizado un algoritmo de k vecinos más próximos (o k-NN, del inglés k-Nearest Neighbors) con k=1.
En la Figura 15 se puede ver una representación gráfica del proceso, donde se representa el vector del cuadro en azul y su correspondiente vector de la canción inicial en verde:
De la inspiración inicial a la melodía final a través de Transformers — El Director de Orquesta
Los Transformers emplean un método de entrenamiento que consiste en enmascarar los datos pertenecientes a una secuencia para predecirla. Estos modelos construyen las características de cada palabra utilizando un mecanismo de atención para averiguar la importancia de todas las demás palabras de la frase con respecto a dicha palabra. Sabiendo esto, las características actualizadas de las palabras son simplemente la suma de las transformaciones lineales de las características de todas las palabras, ponderadas por su importancia.
El mecanismo de atención consiste en uno o varios bloques de operaciones matemáticas que nos darán el peso de importancia de cada dato de la secuencia. En este bloque, la red analiza la secuencia simultáneamente. Este bloque se encarga de encontrar relaciones entre las diferentes partes de la secuencia. Los tokens originales se representan de tres formas diferentes: QUERYS, CLAVES y VALORES. Las QUERYS de cada token se comparan con las KEYS existentes (multiplicación de vectores cuyo resultado mide el grado de relación entre las palabras), el resultado se normaliza y se aplica una función softmax para convertirlo en probabilidades, con esta puntuación (probabilidad) se ponderan los vectores VALUES y se determina la importancia de cada parte de la secuencia a la hora de codificar los tokens. Esta estrategia permite aprender de forma más eficiente qué partes de la secuencia son más importantes que otras y, por tanto, cuáles la definen mejor.
En este proyecto el uso de Transformers ha venido dado por magenta: una librería Python de código abierto, potenciada por TensorFlow. Esta librería incluye utilidades para manipular datos de origen (principalmente música e imágenes), utilizar estos datos para entrenar modelos de aprendizaje automático y, finalmente, generar nuevos contenidos a partir de estos modelos. El uso de esta herramienta nos ha permitido predecir nuevas canciones con Inteligencia Artificial a partir de un midi inicial, que tiene las características de valence-arousal que coinciden con la imagen que queremos musicalizar.
Despliegue
Si hubiera una manera de compartir este trabajo con el resto del mundo… ¡Espera! Hay una manera 😃 Y es muy fácil usando Streamlit y contenedores Docker.
Lo primero que ve el usuario es una aplicación web de Streamlit que le pide que cargue una imagen. Esta imagen sería sobre un cuadro que sería procesado por el resto del pipeline anteriormente descrito. A continuación, ocurre toda la magia entre bastidores.
Dado que el pipe de análisis de sentimientos de imágenes y el MusicTransformer tienen dependencias conflictivas y este último consume mucha más memoria, consideramos que la mejor solución eran dos contenedores separados. Tanto en términos de simplicidad como de escalabilidad horizontal. Este tándem funciona mediante peticiones HTTP, como se indica en la Figura 16.
Cuando se introduce un cuadro en el pipeline, nuestro modelo de análisis de sentimientos de la imagen estima los valores de valence-arousal y elige la semilla inicial que mejor se ajusta. A continuación, envía una solicitud GET al contenedor MusicTransformer, proporcionando el nombre del archivo semilla, los segundos que se deben tomar de este archivo y si se debe generar un acompañamiento para la melodía (que es más costoso en términos de computación y tiempo) o no.
Tras varios segundos de cálculo, el MusicTransformer vuelve al pipe con el archivo MIDI recién generado. El proceso llega a su fin cuando el contenedor del pipe transforma la canción resultante a formato WAV y la muestra al usuario. ¡Veamos un par de ejemplos! 🎬
Conclusiones y líneas futuras
Como hemos visto a lo largo de todo este artículo, la pieza fundamental del proyecto GANs N’ Roses es el modelo de emociones valence-arousal. Esta es la herramienta que nos permite construir un ejemplo práctico de traducción entre sentidos a través de las emociones, así como el adaptador que conecta varios modelos de Inteligencia Artificial para que hablen el mismo lenguaje.
Hemos construido un proyecto de Inteligencia Artificial de extremo a extremo que se apoya en tres modelos bien conocidos, desde una de las arquitecturas CNN más utilizadas (ResNet50) para extraer información relevante sobre los cuadros hasta Transformers para generar música, pasando por un método k-NN para encontrar la canción inicial más parecida al cuadro teniendo en cuenta la emoción que evoca.
Por último, en cuanto a la infraestructura utilizada, construimos una interfaz web con Streamlit y envolvimos todo el pipeline con una arquitectura basada en Docker que es escalable gracias a la separación de los procedimientos más exigentes en dos máquinas diferentes, haciendo realidad el uso de este proyecto.
Para finalizar esta publicación, y dado que este proyecto está abierto a nuevas ideas y trabajos en torno a diferentes áreas, hemos visto varias mejoras y trabajos relacionados que se pueden realizar, como por ejemplo:
- Entrenamiento del modelo CNN de clasificación de imágenes con un mayor número de imágenes de WikiArt. Parte de este conjunto de datos se ha utilizado para construir el modelo en el presente proyecto. El siguiente paso es conseguir un entorno más potente que nos permita procesar más imágenes y hacer un ajuste fino.
- Creación de un modelo de generación de música más manipulable, en el que se puedan imprimir sentimientos con mayor precisión. Para ello queremos desarrollar dos estrategias diferentes:
- ____ Entrenamiento de un modelo para cada sentimiento. El proyecto actual utiliza un único Transformer que ha sido entrenado con música de todo tipo de sentimientos. Con esta estrategia entrenaríamos diferentes Transformers, uno para cada sentimiento, de modo que tengamos más control sobre las características de la música de salida.
- ____ Entrenamiento de un modelo etiquetado con la salida del valence-arousal. Con esta estrategia obtenemos la entrada del modelo musical a partir de la salida del modelo de clasificación de imágenes directamente, simplificando el pipeline del proyecto.
- Generación de música más realista añadiendo más instrumentos a la orquesta.
- Desde GANs N’ Roses queremos que esta aplicación se utilice de acuerdo con las necesidades de sus usuarios, por lo que queremos ponernos en contacto con organizaciones de personas con discapacidad visual y pedirles su opinión para incorporar las mejoras necesarias a la herramienta.
- Creación de una aplicación complementaria para personas con discapacidades auditivas, para que puedan visualizar las sensaciones que transmiten los sonidos. También para ponernos en la piel de las personas que experimentan sinestesia auditiva. Estas personas experimentan de forma automática e involuntaria una percepción visual ante un estímulo auditivo, por lo que cada sonido se asocia a un color. Al igual que ocurre con otros trastornos, como el daltonismo, visualizar cómo ven el mundo otras personas nos acerca a ellas y contribuye a crear una sociedad más comprensiva y tolerante.
Si te ha gustado el proyecto y quieres colaborar, siéntete libre de contactarnos y compartirlo con tus amigos y familiares!
Y muchas gracias por haber llegado hasta aquí 😃