Consejos de PyTorch para aumentar tu productividad

Consejos de PyTorch para ser más productivo

 

Introducción

 

¿Alguna vez has pasado horas depurando un modelo de aprendizaje automático pero parece que no encuentras una razón por la cual la precisión no mejora? ¿Alguna vez has sentido que todo debería funcionar perfectamente pero por alguna razón misteriosa no estás obteniendo resultados ejemplares?

Bueno, ya no más. Explorar PyTorch como principiante puede ser desalentador. En este artículo, explorarás flujos de trabajo probados que seguramente mejorarán tus resultados y aumentarán el rendimiento de tu modelo.

 

1. Sobreajusta un Solo Lote

 

¿Alguna vez has entrenado un modelo durante horas en un conjunto de datos grande solo para descubrir que la pérdida no disminuye y la precisión se estanca? Bueno, haz una comprobación de cordura primero.

Puede llevar mucho tiempo entrenar y evaluar en un conjunto de datos grande, y es más fácil depurar modelos en un subconjunto pequeño de los datos. Una vez que estemos seguros de que el modelo está funcionando, entonces podemos escalar fácilmente el entrenamiento al conjunto de datos completo.

En lugar de entrenar en todo el conjunto de datos, siempre entrena en un solo lote para una comprobación de cordura.

lote = next(iter(train_dataloader)) # Obtén un solo lote

# Para todas las épocas, sigue entrenando en el solo lote.
for epoch in range(num_epochs):
    entradas, objetivos = lote    
    predicciones = modelo.entrenar(entradas)

 

Considera el fragmento de código anterior. Supongamos que ya tenemos un cargador de datos de entrenamiento y un modelo. En lugar de iterar sobre todo el conjunto de datos, podemos obtener fácilmente el primer lote del conjunto de datos. Luego podemos entrenar en el solo lote para verificar si el modelo puede aprender los patrones y la variación dentro de esta pequeña porción de los datos.

Si la pérdida disminuye a un valor muy pequeño, sabemos que el modelo puede sobreajustar estos datos y podemos estar seguros de que está aprendiendo en poco tiempo. Luego podemos entrenar esto en el conjunto de datos completo simplemente cambiando una sola línea de la siguiente manera:

# Para todas las épocas, iterar sobre todos los lotes de datos.
for epoch in range(num_epochs):
    for lote in iter(dataloader):
        entradas, objetivos = lote    
        predicciones = modelo.entrenar(entradas)

 

Si el modelo puede sobreajustar un solo lote, debería poder aprender los patrones en el conjunto de datos completo. Este método de sobreajuste de lotes permite una depuración más fácil. Si el modelo ni siquiera puede sobreajustar un solo lote, podemos estar seguros de que hay un problema con la implementación del modelo y no con el conjunto de datos.

 

2. Normalizar y Mezclar los Datos

 

Para conjuntos de datos donde la secuencia de datos no es importante, es útil mezclar los datos. Por ejemplo, para las tareas de clasificación de imágenes, el modelo se ajustará mejor a los datos si se le alimentan imágenes de diferentes clases dentro de un solo lote. Al pasar datos en la misma secuencia, corremos el riesgo de que el modelo aprenda los patrones basados en la secuencia de datos pasada, en lugar de aprender la variación intrínseca dentro de los datos. Por lo tanto, es mejor pasar datos mezclados. Para esto, simplemente podemos usar el objeto DataLoader proporcionado por PyTorch y establecer shuffle en True.

from torch.utils.data import DataLoader

conjunto_datos = # Cargar Datos
cargador_datos = DataLoader(conjunto_datos, shuffle=True)

 

Además, es importante normalizar los datos cuando se utilizan modelos de aprendizaje automático. Es esencial cuando hay una gran variación en nuestros datos y un parámetro en particular tiene valores más altos que todos los demás atributos en el conjunto de datos. Esto puede hacer que uno de los parámetros domine a todos los demás, lo que resulta en una menor precisión. Queremos que todos los parámetros de entrada estén dentro del mismo rango y es mejor tener una media de 0 y una varianza de 1.0. Para esto, tenemos que transformar nuestro conjunto de datos. Conociendo la media y la varianza del conjunto de datos, simplemente podemos usar la función torchvision.transforms.Normalize.

import torchvision.transforms as transforms

transformaciones_imagen = transforms.Compose([
    transforms.ToTensor(),
    # Normalizar los valores en nuestros datos
    transforms.Normalize(mean=(0.5,), std=(0.5))
])

 

Podemos pasar nuestra media por canal y desviación estándar en la función transforms.Normalize y automáticamente convertirá los datos teniendo una media de 0 y una desviación estándar de 1.

 

3. Recorte de Gradientes

 

El problema de los gradientes explosivos es conocido en las RNNs y LSTMs. Sin embargo, no se limita únicamente a estas arquitecturas. Cualquier modelo con capas profundas puede sufrir de gradientes explosivos. La retropropagación en gradientes altos puede llevar a una divergencia en lugar de una disminución gradual de la pérdida.

Considera el siguiente fragmento de código.

for epoch in range(num_epochs):
    for batch in iter(train_dataloader):
        inputs, targets = batch
        predictions = model(inputs)
     
     
        optimizer.zero_grad() # Remover todos los gradientes previos
        loss = criterion(targets, predictions)
        loss.backward() # Calcula los gradientes para los pesos del modelo
     
        # Recortar los gradientes de los pesos del modelo a un valor máximo especificado.
        torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1)
     
        # Optimizar los pesos del modelo DESPUÉS DE RECORTARLOS
        optimizer.step()

 

Para resolver el problema de los gradientes explosivos, utilizamos la técnica de recorte de gradientes que recorta los valores de los gradientes dentro de un rango especificado. Por ejemplo, si usamos 1 como nuestro valor de recorte o norma como se muestra arriba, todos los gradientes se recortarán en el rango [-1, 1]. Si tenemos un valor de gradiente explosivo de 50, se recortará a 1. Así, el recorte de gradientes resuelve el problema de los gradientes explosivos permitiendo una optimización lenta del modelo hacia la convergencia.

 

4. Alternar entre Modo de Entrenamiento / Evaluación

 

Esta sola línea de código seguramente aumentará la precisión de prueba de tu modelo. Casi siempre, un modelo de aprendizaje profundo utilizará capas de dropout y normalización. Estas solo son necesarias para un entrenamiento estable y para asegurar que el modelo no se sobreajuste o diverja debido a la varianza en los datos. Capas como BatchNorm y Dropout ofrecen regularización para los parámetros del modelo durante el entrenamiento. Sin embargo, una vez entrenado, no son necesarias. Cambiar un modelo al modo de evaluación deshabilita las capas solo necesarias para el entrenamiento y se utilizan todos los parámetros completos del modelo para hacer predicciones.

Para una mejor comprensión, considera este fragmento de código.

for epoch in range(num_epochs):
    
    # Usando Modo de Entrenamiento al iterar sobre el conjunto de datos de entrenamiento
    model.train()
    for batch in iter(train_dataloader):
            # Código de entrenamiento y optimización de la pérdida
    
    # Usando Modo de Evaluación al verificar la precisión en el conjunto de datos de validación
    model.eval()
    for batch in iter(val_dataloader):
            # Solo predicciones y cálculos de pérdida. Sin retropropagación
            # Sin paso del optimizador, por lo que podemos omitir capas innecesarias.

 

Cuando evaluamos, no necesitamos hacer ninguna optimización de los parámetros del modelo. No calculamos ningún gradiente durante los pasos de validación. Para una mejor evaluación, podemos omitir las capas de Dropout y otras capas de normalización. Por ejemplo, habilitará todos los parámetros del modelo en lugar de solo un subconjunto de pesos como en la capa de Dropout. Esto aumentará sustancialmente la precisión del modelo, ya que podrás utilizar el modelo completo.

 

5. Utilizar Module y ModuleList

 

Normalmente, el modelo de PyTorch hereda de la clase base torch.nn.Module. Según la documentación:

Los submódulos asignados de esta manera se registrarán y tendrán sus parámetros convertidos cuando llames a to(), etc.

Lo que permite la clase base del módulo es registrar cada capa dentro del modelo. Luego podemos usar model.to() y funciones similares como model.train() y model.eval() y se aplicarán a cada capa dentro del modelo. Si no lo hacemos, no se cambiará el dispositivo o el modo de entrenamiento para cada capa contenida en el modelo. Tendrás que hacerlo manualmente. La clase base del módulo automáticamente hará las conversiones por ti una vez que uses una función simplemente en el objeto del modelo.

Además, algunos modelos contienen capas secuenciales similares que se pueden inicializar fácilmente usando un bucle for y se pueden contener dentro de una lista. Esto simplifica el código. Sin embargo, causa el mismo problema que se mencionó anteriormente, ya que los módulos dentro de una simple lista de Python no se registran automáticamente dentro del modelo. Deberíamos utilizar un ModuleList para contener capas secuenciales similares dentro de un modelo.

import torch
import torch.nn as nn


# Heredar de la Clase Base del Módulo
class Modelo(nn.Module):
      def __init__(self, tamaño_entrada, tamaño_salida):
            # Inicializar la Clase Padre del Módulo
            super().__init__()

            self.capas_densas = nn.ModuleList()

            # Agregar 5 capas lineales y contenerlas dentro de un ModuleList
            for i in range(5):
                self.capas_densas.append(
                    nn.Linear(tamaño_entrada, 512)
                )

            self.capa_salida = nn.Linear(512, tamaño_salida)

    def forward(self, x):

            # Simplifica la Propagación Hacia Adelante.
            # En lugar de repetir una sola línea para cada capa, usa un bucle
            for capa in range(len(self.capas_densas)):
            x = capa(x)

            return self.capa_salida(x)

 

El fragmento de código anterior muestra la forma adecuada de crear el modelo y las subcapas con el modelo. El uso de Module y ModuleList ayuda a evitar errores inesperados al entrenar y evaluar el modelo.

 

Conclusión

 

Los métodos mencionados anteriormente son las mejores prácticas para el marco de aprendizaje automático PyTorch. Son ampliamente utilizados y son recomendados por la documentación de PyTorch. El uso de tales métodos debe ser la forma principal de flujo de código de aprendizaje automático y seguramente mejorará sus resultados. Muhammad Arham es un Ingeniero de Aprendizaje Profundo que trabaja en Visión por Computadora y Procesamiento de Lenguaje Natural. Ha trabajado en la implementación y optimización de varias aplicaciones de IA generativa que alcanzaron los primeros puestos a nivel mundial en Vyro.AI. Está interesado en construir y optimizar modelos de aprendizaje automático para sistemas inteligentes y cree en la mejora continua.

We will continue to update Zepes; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Inteligencia Artificial

¿Cómo codificar usando ChatGPT?

Introducción Incorporar inteligencia artificial en la programación moderna ha dado inicio a una nueva era de eficienc...

Inteligencia Artificial

Conoce AUDIT Un modelo de edición de audio guiado por instrucciones basado en modelos de difusión latente

Los modelos de difusión están avanzando rápidamente y facilitando la vida. Desde el Procesamiento del Lenguaje Natura...

Inteligencia Artificial

Un experto de la industria impulsa una alternativa abierta a la inteligencia artificial de las grandes empresas tecnológicas.

El Instituto Allen para la IA, una organización sin fines de lucro liderada por un respetado científico informático q...

Inteligencia Artificial

Conoce a Nous-Hermes-Llama2-70b Un modelo de lenguaje de última generación ajustado finamente en más de 300,000 instrucciones.

El Transformer de Hugging Face es una biblioteca inmensamente popular en Python, que proporciona modelos pre-entrenad...

Inteligencia Artificial

Artista Co-creatividad y colaboración entre computadoras y humanos en las artes

Lejos de sentirse amenazados por la inteligencia artificial, muchos profesionales creativos ya la están adoptando, co...

Inteligencia Artificial

Congelación de capas de un modelo de aprendizaje profundo - la forma correcta

A menudo es útil congelar algunos de los parámetros, por ejemplo, cuando estás ajustando tu modelo y quieres congelar...