¿Qué es PyTorch y por qué es relevante en la inteligencia artificial?
PyTorch es una biblioteca de Python utilizada para el desarrollo de redes neuronales profundas. Desarrollada por Facebook AI Research, se caracteriza por su facilidad de uso y flexibilidad, lo que la hace muy popular entre los investigadores y desarrolladores. Su relevancia en el campo de la inteligencia artificial reside en su capacidad para modelar redes neuronales complejas de manera intuitiva y eficiente.
¿Cómo se configura un modelo básico de PyTorch?
Para configurar un modelo básico de PyTorch, es fundamental seguir ciertos pasos que facilitan la creación de modelos de inteligencia artificial. Aquí te mostramos un ejemplo práctico utilizando Google Colab, una herramienta que permite el uso gratuito de GPU:
Importación de PyTorch y sus módulos:
import torch
import torch.nn as nn
Creación de una subclase de nn.Module:
En este ejemplo, creamos la clase TextClassifier, que sirve para clasificar texto.
Definimos las dimensiones necesarias para crear el modelo:
vocab_size =1000# Tamaño del vocabularioembedding_dim =100# Dimensiones del embeddinghidden_dim =256# Dimensiones ocultasoutput_dim =2# Dimensiones de salida (clasificación binaria)model = TextClassifier(vocab_size, embedding_dim, hidden_dim, output_dim)
¿Cuáles son los hiperparámetros clave?
Al configurar modelos de redes neuronales en PyTorch, existen varios hiperparámetros a considerar que impactan en el rendimiento y la eficiencia del modelo:
Tamaño del vocabulario (vocab_size): El número de palabras únicas que el modelo manejará. Puede variar ampliamente dependiendo del conjunto de datos.
Dimensiones del embedding (embedding_dim): Define el tamaño de los vectores en que se traducen las palabras. Tamaños comunes incluyen 100 o más, dependiendo de la complejidad del modelo.
Dimensiones ocultas (hidden_dim): Se refiere a la "profundidad" y complejidad de la red. Cuanto mayor sea el valor, más capacidad tiene el modelo para capturar matices del texto, aunque esto también implica un mayor costo computacional.
Dimensiones de salida (output_dim): Corresponde al número de clases que deseas clasificar. En problemas de clasificación binaria, output_dim suele ser 2.
A medida que continúas tu viaje en el aprendizaje profundo y la inteligencia artificial, experimentar con estos hiperparámetros te permitirá personalizar modelos para satisfacer necesidades específicas. Mantente curioso y creativo, ¡y las posibilidades serán infinitas!
import torch
import torch.nn as nn
classTextClassifier(nn.Module):def__init__(self, vocab_size, embedding_dim, hidden_dim, output_dim):super().__init__()# Capa de embedding para mapear índices de palabras a vectores de embeddings self.embedding = nn.Embedding(vocab_size, embedding_dim)# Capa LSTM para procesar los embeddings y obtener estados ocultos self.rnn = nn.LSTM(embedding_dim, hidden_dim, num_layers=2, batch_first=True)# Capa lineal para proyectar el último estado oculto en la salida final self.fc = nn.Linear(hidden_dim, output_dim)defforward(self, text):# Obtener los embeddings de las palabras embedded = self.embedding(text)# Propagar los embeddings a través de la capa LSTM output,(hidden, cell)= self.rnn(embedded)# Seleccionar el último estado oculto como estado final final_hidden = hidden[-1]# Pasar el estado final a través de la capa lineal para obtener la salida finalreturn self.fc(final_hidden)# Parámetros del modelovocab_size =10000embedding_dim =100hidden_dim =256output_dim =2# Crear instancia del modelomodel = TextClassifier(vocab_size, embedding_dim, hidden_dim, output_dim)# Imprimir la estructura del modeloprint(model)
Respuesta esperada:
TextClassifier(
(embedding): Embedding(10000, 100)
(rnn): LSTM(100, 256, num_layers=2, batch_first=True)
(fc): Linear(in_features=256, out_features=2, bias=True)
)
Process finished with exit code 0
Expliquemos el código paso a paso:
Se importan las bibliotecas necesarias: torch para el uso de PyTorch y torch.nn para las capas y funciones de redes neuronales.
Se define la clase TextClassifier, que es una subclase de nn.Module, la cual es la base para definir modelos de PyTorch.
En el método __init__ de la clase TextClassifier, se definen los componentes del modelo. Los parámetros que recibe son:
vocab_size: Tamaño del vocabulario, es decir, la cantidad de palabras únicas en el corpus de texto.
embedding_dim: Dimensión de los vectores de embeddings. Cada palabra será representada por un vector de esta dimensión.
hidden_dim: Dimensión de los estados ocultos de la capa LSTM.
output_dim: Dimensión de la salida del clasificador.
En el cuerpo del método, se definen tres capas:
self.embedding: Una capa de embedding (nn.Embedding) que mapea cada índice de palabra a un vector de embeddings de tamaño embedding_dim.
self.rnn: Una capa LSTM (nn.LSTM) que recibe los embeddings y produce secuencias de estados ocultos. Tiene num_layers=2 capas LSTM apiladas y batch_first=True indica que la entrada se proporcionará en el formato (batch_size, sequence_length, input_size).
self.fc: Una capa lineal (nn.Linear) que proyecta el último estado oculto de la capa LSTM (hidden_dim) en la dimensión de salida (output_dim).
En el método forward de la clase TextClassifier, se define cómo se propagan los datos a través del modelo. El parámetro text representa las secuencias de palabras de entrada.
Primero, los embeddings de las palabras se obtienen utilizando self.embedding y se almacenan en embedded.
A continuación, embedded se pasa a través de la capa LSTM (self.rnn) y se obtienen output, hidden y cell. output contiene los estados ocultos de todas las palabras de la secuencia, mientras que hidden y cell contienen los estados finales de la capa LSTM.
El último estado oculto hidden[-1] se selecciona como el estado oculto final y se pasa a través de la capa lineal (self.fc) para obtener la salida final del clasificador.
La salida final se devuelve.
A continuación, se definen los parámetros para construir una instancia del modelo. vocab_size se establece en 10000, embedding_dim en 100, hidden_dim en 256 y output_dim en 2.
Se crea una instancia del modelo TextClassifier utilizando los parámetros definidos.
Finalmente, se imprime el modelo creado. Esto mostrará la estructura del modelo, incluyendo las capas y sus dimensiones.
Les compartos algunas definiciones de los parametros que se necesitan para crear una red neuronal LSTM en Pytorch
input_size: Especifica la dimensión del espacio de características de entrada. Indica el tamaño del vector de características de cada elemento de la secuencia de entrada. Por ejemplo, si cada elemento de la secuencia de entrada es un vector de 10 dimensiones, input_size sería igual a 10.
hidden_size: Define la dimensión del espacio de características ocultas. Determina el número de unidades de memoria en la capa LSTM. Cuanto mayor sea el valor de hidden_size, más capacidad tendrá la capa para capturar patrones complejos en los datos, pero también requerirá más recursos computacionales. Es un hiperparámetro que debes ajustar según las necesidades y la complejidad del problema.
num_layers: Indica el número de capas LSTM apiladas una encima de la otra. Puedes tener una sola capa LSTM o múltiples capas apiladas para construir una red LSTM más profunda. Las capas LSTM adicionales pueden ayudar al modelo a aprender representaciones jerárquicas y patrones de mayor complejidad en los datos.
batch_first: Un valor booleano que indica el formato de entrada y salida de los datos. Si se establece en True, los datos se esperan en el formato (batch_size, sequence_length, input_size), lo que significa que la dimensión del lote se coloca en primer lugar. Si se establece en False, el formato esperado es (sequence_length, batch_size, input_size). Esto depende de cómo estén estructurados tus datos y cómo prefieras trabajar con ellos.
Excelente aporte !!! justo las preguntas que quedan después de ver la clase
estoy creando nueva arquitectura de Deep learning inspirada en los modelos Transformers donde el sistema aprende a recordar lo que ya ha hecho y utiliza esta información para sus futuras predicciones y para su aprendizaje, por el momento llevo solo la teoría estoy aprendiendo.
Suerte! No es que sea un experto pero creo que es mejor empezar por las redes recurrentes con LSTM porque te dan algunos conceptos sobre como manejar varios inputs, luego ver mecanismos como el self-attention y cross-attention.
Cuesta bastante seguir la clase, en el sentido de saber hacia donde se quiere ir, más allá de lo obvio que se comenta en la clase.
Aquí tienes un ejemplo básico de "Hola, mundo" en PyTorch, que simplemente crea un tensor y lo imprime:
import torch
\# Crear un tensor
hola\_mundo = torch.tensor(\[1,2,3])
\# Imprimir el tensor
print("Hola, mundo en PyTorch:", hola\_mundo)
Este código crea un tensor simple con los valores \[1, 2, 3] utilizando PyTorch y lo imprime en la consola junto con el mensaje "Hola, mundo en PyTorch". Es una forma simple de verificar que PyTorch está funcionando correctamente en tu entorno.
Yo cómo alguien con una mente muy dispersa y con muy poca tolerancia a la frustración recomiendo mucho tomarse su tiempo en cada clase, aprovechar que se está trabajando desde las primeras e ir preguntando a ChatGpt sobre porque puso esa linea de código o hacia dónde se quiere ir, me hace avanzar más lento pero de verdad cuándo acabas te da un sentido de satisfacción enorme saber si estás aprendiendo y que no solamente acabas los videos por acabarlos, y además que puedes reutilizar el bosquejo general del código en algún otro proyecto una vez que lo entiendes mejor
Yo ya sabía TensorFlow, solo cosas normales con la API, hasta que hace unos meses comencé a olvidarlo al meterme con Pytorch, con ayuda de GPT, claro, tampoco me perdía tanto con Pytorch por errores porque como que uno le pierde el miedo a leer errores, también es obvio, saber pedirle a GPT cosas que sabes que hay en tensorflow y que acá necesitas sus equivalentes en pytorch y que puedes hacer más personalizado.
Ahora vine para ver lo de redes convolucionales y vamos a ver que hay curso nuevo y el viejo C perdió :( ya no aparece en el buscador.
Totalmente de acuerdo, aunque pienso que eso debió hacerlo el profesor
Creación de la Clase del Modelo: Definimos una clase para nuestro modelo de clasificación de texto, derivada de nn.Module. Esta clase encapsula todos los componentes necesarios para procesar y clasificar el texto.
Definición de la Arquitectura del Modelo: Establecemos los parámetros y componentes fundamentales:
Embeddings: Utilizamos una capa de embeddings para convertir índices de palabras en vectores densos de longitud fija (embedding_dim). Esto permite representar palabras de manera numérica adecuada para el procesamiento por redes neuronales.
LSTM: Implementamos una Long Short-Term Memory (LSTM) para manejar secuencias de texto. La LSTM recibe vectores de embeddings y tiene:
Una dimensión de entrada igual al embedding_dim.
Una dimensión de capas ocultas (hidden_dim), que define la capacidad de la red para capturar patrones en las secuencias. Aumentar el hidden\_dim y el número de capas (num_layers) incrementa la capacidad de la red, pero también la complejidad computacional y el riesgo de sobreajuste.
Capa Lineal: La capa lineal transforma la salida de la LSTM en un espacio de dimensiones output_dim, correspondiente al número de clases en la clasificación. Esta capa es responsable de producir la predicción final basada en la representación aprendida de la secuencia de texto.
Función forward: Define cómo se procesan los datos a través del modelo
Vectorización del Texto: Convierte los índices de palabras en vectores de embeddings utilizando la capa de embeddings.
Procesamiento en la LSTM: Pasa los embeddings a través de la LSTM para capturar dependencias en la secuencia.
Extracción del Último Estado Oculto: Obtiene el estado oculto final de la última capa de la LSTM. Este estado final representa la información sintetizada de toda la secuencia.
Clasificación Final: Pasa el último estado oculto por la capa lineal para obtener las predicciones de clase, que corresponden a las probabilidades de cada clase.
Les dejo algunas importantes, si van perdidos como yo.
La red neuronal de tipo LSTM (Long Short-Termmantenerse Memory) es simplemente algo más secuencial, para recordar en este caso texto hacia atrás y memoria corta (como describe el nombre). De esta forma elegimos que debe de recordar la red neuronal y en el siguiente paso, "el modelo", que tiene que mantenerse en contexto.
Es un poco mas complejo, pero es importante, comprender que esta red neuronal, sirve para el caso de texto, audio, etc. Algo temporal, cómo un chat simple.
Otro concepto que me pareció importante buscar es hidden_size, para la red neuronal. Encontré que es una forma de controlar el tamaño del vector, de justamente la memoria que genera la red neuronal. Concepto avanzado igualmente, es importante para todo básicamente.
Les recomiendo repasar sobre vectores, embeddings, que son conceptos sencillos, para tener base en lo anterior.
Pero los descargo y luego los monto en un colab o algo asi ? uy creo que seria bueno que explicaran alternativas o algo por el estilo a modo de opinion personal posiblemente sesgada
■ Resumen:
**Creación de la Clase del Modelo**: Definimos una clase para nuestro modelo de clasificación de texto, derivada de nn.Module. Esta clase encapsula todos los componentes necesarios para procesar y clasificar el texto.
- **Definición de la Arquitectura del Modelo**: Establecemos los parámetros y componentes fundamentales:
- **Embeddings**: Utilizamos una capa de embeddings para convertir índices de palabras en vectores densos de longitud fija (embedding_dim). Esto permite representar palabras de manera numérica adecuada para el procesamiento por redes neuronales.
- **LSTM**: Implementamos una Long Short-Term Memory (LSTM) para manejar secuencias de texto. La LSTM recibe vectores de embeddings y tiene:
Una dimensión de entrada igual al embedding_dim.
Una dimensión de capas ocultas (hidden_dim), que define la capacidad de la red para capturar patrones en las secuencias. Aumentar el hidden\_dim y el número de capas (num_layers) incrementa la capacidad de la red, pero también la complejidad computacional y el riesgo de sobreajuste.
- **Capa Lineal**: La capa lineal transforma la salida de la LSTM en un espacio de dimensiones output_dim, correspondiente al número de clases en la clasificación. Esta capa es responsable de producir la predicción final basada en la representación aprendida de la secuencia de texto.
**Función forward**: Define cómo se procesan los datos a través del modelo
- **Vectorización del Texto**: Convierte los índices de palabras en vectores de embeddings utilizando la capa de embeddings.
- **Procesamiento en la LSTM**: Pasa los embeddings a través de la LSTM para capturar dependencias en la secuencia.
- **Extracción del Último Estado Oculto**: Obtiene el estado oculto final de la última capa de la LSTM. Este estado final representa la información sintetizada de toda la secuencia.
- **Clasificación Final**: Pasa el último estado oculto por la capa lineal para obtener las predicciones de clase, que corresponden a las probabilidades de cada clase.
Que tal, les comparto un breve artículo con una explicación sobre como funcionan las redes neuronales, por si les es de utilidad para recordar algunos conceptos que se usan en el código.
Esta clase de 13 minutos, se volvió una de 7 horas.
No lo digo por la mala explicación del profesor, al contrario, me pareció una explicación fantástica.
Si tuve que investigar ciertos conceptos que no entendía y para profundizar más en el tema.
Las clases se están viendo en google colab, para aprovechar un poco esa CPU. Pero quería sacarle provecho a mi tarjeta gráfica y fue un poco complejo instalar las dependencias y hacer que VS code use la GPU y recursos CUDA para hacer los modelos.
Sin embargo, la velocidad se nota y de lejos
Clase de 13 min de videos, pero de 1 hora de práctica