Enseñando a una Red Neuronal a hablar Español y resolver problemas matemáticos

Source: Deep Learning on Medium


source: www.thesun.co.uk

Hace un tiempo hice un nuevo amigo a través de mi cuenta en GitHub. Antony de Peru vio el repositorio de un proyecto con redes neuronales artificiales que hice a finales del año pasado para una clase de la universidad, me contó sobre una especie de bot que está tratando de construir con el que se puedan entablar conversaciones, pero que sus respuestas son escogidas mediante cadenas de Markov, su objetivo inicialmente era crear una inteligencia artificial que pudiera hablar entrenándola con cualquier temática (en especial me hacía énfasis en química y matemáticas).

Decidí aceptar el reto, como amante de la inteligencia artificial y de las redes neuronales más que como un experto en el tema, a fin de cuentas, lo único que podía perder era la oportunidad de aprender. Este artículo describe nuestros resultados y resumir todo lo que aprendimos.

Reto #1: Enseñar Español a una IA

Cuando Antony me planteó el problema, yo había escuchado y leído un poco sobre cómo construir redes neuronales que procesan texto, sabía que para esto las Redes Neuronales Recurrentes (RNN) pero nunca me había dado a la tarea de entenderlas ni mucho menos aplicarlas.

El mejor artículo para comprender este tipo de red neuronal que pude encontrar fue RNN or Recurrent Neural Network for Noobs, de Debarko De. Una vez entendimos las bases de este tipo de redes, la búsqueda se hizo más específica, hasta que Antony dio con el siguiente video:

“How I taught my neural network to speak almost as well as Rajoy — Alex Gascón Bononad”

Alex Gascón lo hizo! explica en su video como uso LSTM (un tipo de RNN) para enseñar español a una red neuronal. Antony y yo nos propusimos reproducir su trabajo (para lo cual fue de mucha ayuda los notebooks de su GitHub). Explicar LSTM no es la función de este articulo, pero las fuentes que más me ayudaron a comprender lo que estaba haciendo, y cómo entender el código fuente de Alex fueron:

Debido al costo computacional que requería el entrenamiento (cerca de 5 horas por cada iteración) decidí utilizar Kaggle, con un kernel privado cada iteración extraía los pesos de la red neuronal para continuar luego el entrenamiento.

Finalmente, Luego de 50 entrenamientos utilizando como datos de entrenamiento el popular libro de Don Quijote de la Mancha los resultados fueron textos como el siguiente:

Texto en español generado por una red neuronal LSTM

Básicamente, el texto generado es casi inentendible y solo algunas palabras están bien escritas, para mejorar este resultado decidí incrementar los datos de entrenamiento y cambiar un poco la estructura de la red utilizada. La red con estos cambios aún está en entrenamiento. Pero parece ir por buen camino.


Reto #2: Enseñar matemáticas a una IA

Como parte del proceso de aprendizaje en este tema de las redes neuronales recurrentes, con la intención de explorar el aprendizaje de fórmulas matemáticas llegamos a las RNN de tipo Sequence To Sequence (Seq2seq). Este tipo de red básicamente utiliza dos RNN de tipo LSTM, una ejerce la función de codificador y la otra de decodificador. La idea es que los datos con los que se entrenen estén estructurados como una secuencia, es por esto que para su implementación es necesario aplicar variadas técnicas como crear diccionarios de las letras y símbolos presentes en el texto. Finalizado el proceso de entrenamiento el modelo aprenderá a crear secuencias a partir de secuencias de entradas de la misma estructura.

Utilizando el modelo LSTM y con la inspiración de este ejemplo desarrollé una Red Neuronal para sumar dos número de hasta 4 dígitos con una precisión muy alta. Los datos de entrenamiento contienen 400,000 operaciones de suma de dígitos de distinta longitud en una columna y su solución en otra.

Source: https://blog.keras.io/a-ten-minute-introduction-to-sequence-to-sequence-learning-in-keras.html

El reto principalmente con este tipo de modelos claramente es lograr estandarizar las secuencias de los ejemplos de entrenamiento para que tanto el ejemplo como su respuesta tengan un tamaño fijo cada uno. En este caso, para la adición de números se agregan espacios para completar espacios sin llenar en la secuencia. Como se trabaja con números de hasta 4 dígitos entonces el número más grande que deberá devolver como resultado será 19998 (solución a 9999 + 9999) luego entonces las secuencias son transformadas para tener una longitud de 5.

Pruebas

Luego del entrenamiento, el modelo resultó ser todo un éxito. El código de toda la implementación se encuentra en este repositorio, pero igualmente la solución entrenada se encuentra desplegada como API de Flask y puede accederse a ella utilizando el navegador con la dirección https://rest-adder-api.appspot.com/. Para consumir el API debe enviarsele un método GET a la dirección, esta espera recibir la operación a realizar en forma de cadena en el parámetro llamado operation. Para agregar el símbolo “+” es necesario usar %2B. Así, por ejemplo, para operar 3+3 a la dirección principal debe agregarse ?operation=3%2B3 y se recibirá en la pantalla la solución del modelo.

Resultado de la operación 3+3. https://rest-adder-api.appspot.com/?operation=3%2B3

Conclusiones

Con este par de proyectos mi amigo Antony y yo pudimos experimentar el verdadero potencial de las redes neuronales para la producción de texto o interpretación de secuencias, la conclusión a la que llegamos es que en la medida en que podamos modelar datos en forma de secuencia, siempre podrá crearse una red neuronal ya sea LSTM, Seq2seq o cualquier otro tipo de RNN capaz de aprender y generar el tipo de contenido con el que sea entrenada.