Matrices en las Redes neuronales
En los últimos años, el aprendizaje profundo ha revolucionado la forma en que abordamos problemas complejos en campos como la visualización de datos, el procesamiento del lenguaje natural y la robótica. Sin embargo, detrás de cada modelo de aprendizaje profundo, hay un complejo entramado de matrices y operaciones matemáticas que hacen posible el aprendizaje y la predicción.
En este capítulo del curso “Aprendiendo a trabajar con IA desde 0”, exploraremos la importancia de las matrices y cómo se aprovecha el paralelismo con GPUs y TPUs para hacer que los modelos sean más eficientes y rápidos.
También hablaremos de los optimizadores para descenso de gradientes, haremos varios ejemplos de su implementación de redes neuronales y vamos a ver cómo su elección puede tener un impacto significativo en el éxito y la eficiencia del aprendizaje automático.
Mi misión es hacer que todo esto no suene a chino y abrir camino para que pronto puedas entrenar tu primera red neuronal 🧠✨
Table of Contents
- Matrices en las Redes neuronales
- Repaso de capítulos anteriores
- Matrices
- El problema de mínimos locales
- sin(x) function
- sin(x)+.5x function
- Optimizadores
- Función graficada
- Descenso del gradiente sobre la función
- Descenso del gradiente sobre la función con ruido.
- SGD: Stochastic gradient descent
- SGD sobre la función
- Momentum
- Momentum sobre la función
- RMSProp
- Graficamos
- Graficamos
- Graficamos
- RMSProp sobre la función
- Adam
- Adam sobre la función
- Comparativa: graficamos
Repaso de capítulos anteriores
Este post pertenece a una serie de artículos que forman el curso completo para aprender a trabajar con inteligencia artificial desde cero. Por ello te recomiendo que si no lo has leído, comiences por el primer artículo que te dará las bases para comprender mejor lo que explicaremos en los siguientes
Si no has visto el post anterior te dejamos un enlace aquí donde profundizamos en los siguientes tópicos:
✅ Pendiente
✅ Derivadas y derivadas parciales (sin tablas)
✅ Encontrar el máximo de una función
✅ Descenso del gradiente
✅ Perceptrones
✅ Redes neuronales
✅ Forward Propagation
✅ Backward Propagation
Matrices
Las matrices son uno de los conceptos más importantes para implementar redes neuronales. Sin embargo, no para entenderlas. Es por eso que en el documento anterior decidí saltarme éste paso. Generalmente cuando ves códigos para armar tu primera red lo haces usando matrices. Yo considero que ésto es confuso para las personas que vienen del campo del código pero no de la ingeniería u otras ramas con fuerza en matemáticas.
Las matrices son un conceto fundamental del álgebra lineal. Principalmente las usamos para transformaciones lineales, sistemas de ecuaciones lineales, medir similitudes entre conjuntos de datos y más.
Si te interesa aprender más sobre matrices te recomiendo el siguiente enlace.
Para éste caso, las matrices las utilizamos como un medio de optimización. Una matriz es una entidad matemática que almacena un conjunto de datos en filas y columnas. Veamos por qué son tan útiles…
Paralelismo con GPUs y TPUs
Para ello primero quiero hablar de un componente de tu ordenador; la GPU (o Graphics Processor Unit). La GPU (o tarjeta gráfica) es una componente dedicado principalmente al procesamiento de gráficos. La diferencia con la CPU es su capacidad de paralelismo. Imagina que pudieras ejecutar todas las líneas de código de tu programa al mismo tiempo en paralelo. El programa correría muy rápido, ¿verdad? Sin embargo ésto no es posible ya que para que los algoritmos funcionen antes de ejecutar la línea 3 se tiene que ejecutar las lineas 1 y 2. Por ejemplo, si la línea 3 hace uso de una variable modificada por la línea 1 y 2. Por ello las CPUs están diseñadas para ejecutar una cola de instrucciones en orden rápidamente.
Las GPUs, por contrario, son una unidad de procesamiento diseñada para programas que sí pueden paralelizar mucho código a la vez. Cuando se renderiza un modelo 3D en nuestra pantalla, por ejemplo, el código que se ejecuta por cada pixel es el mismo pero con datos de entrada diferentes. Ésto permite mandar a ejecutar las mismas operaciones sobre diferentes datos al mismo tiempo. Cada ejecución no tiene necesidad de esperar a que la ejecución “del pixel vecino” termine. Por ello la estrategia de la GPU es tener un montón de unidades de procesamiento mientras que la CPU es un hardware especializado en programas secuenciales.
Existen algoritmos que permiten realizar cálculos matriciales muy rápidamente desde la GPU sacando partido al paralelismo. Es por ésta razón que las GPUs se utilizan mucho para el machine learning y la ciencia de datos. El entrenamiento de una red neuronal es una tarea de muchas iteraciones.
Las GPU están diseñadas para el procesamiento de gráifcos. Razón por las que se inventaron las TPU (Tensor Processor Unit). Es un concepto similar solo que su arquitectura está optimizada para operar con tensores (dicho mal y pronto, los tensores son matrices anidadas y las veremos en detalle cuando implementemos nuestra primera red profesional). Es un hardware diseñado para redes neuronales.
En python contamos con numpy, una librería que nos permite hacer uso de nuestra GPU/TPU con una sintaxis sencilla para operar sobre conjuntos de datos y realizar operaciones matriciales (entre muchas otras cosas).
Optimizando la red neuronal con matrices
De ahora en adelante quiero que entiendas que todas las fórmulas que hemos hablado y que hablaremos son expresadas mediante operaciones matriciales siempre que sea posible.
Multiplicación de matrices
La multiplicación de matrices consiste en el sumatorio de filas por columnas tal que:
Dada una matriz A y una matriz B cuyo resultado es la matriz C:
Dicho de una forma algo más gráfica…
No es de mi interés hacer una clase magistral de las matrices. Pero sería recomendable investigar acerca de sus propiedades, operaciones, inversa, determinante…
Ejemplo: Optimizando el forward propagation
Imagina que tenemos una red neuronal de 4 con el siguiente aspecto: