Logotipo de Zephyrnet

Consejos de PyTorch para aumentar su productividad – KDnuggets

Fecha:

Consejos de PyTorch para aumentar su productividad
Imagen del autor
 

¿Alguna vez ha pasado horas depurando un modelo de aprendizaje automático pero parece que no puede encontrar una razón por la que la precisión no mejora? ¿Alguna vez ha sentido que todo debería funcionar a la perfección, pero por alguna misteriosa razón no está obteniendo resultados ejemplares?

Bueno, no más. Explorar PyTorch como principiante puede resultar abrumador. En este artículo, explorará flujos de trabajo probados que seguramente mejorarán sus resultados y aumentarán el rendimiento de su modelo.

¿Alguna vez entrenó un modelo durante horas en un gran conjunto de datos solo para descubrir que la pérdida no disminuye y la precisión simplemente se aplana? Bueno, primero haz una prueba de cordura.

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

En lugar de entrenar en todo el conjunto de datos, siempre entrene en un solo lote para un control de cordura.

batch = next(iter(train_dataloader)) # Get a single batch # For all epochs, keep training on the single batch.
for epoch in range(num_epochs): inputs, targets = batch predictions = model.train(inputs)

 

Considere el fragmento de código anterior. Supongamos que ya tenemos un cargador de datos de entrenamiento y un modelo. En lugar de iterar sobre el conjunto de datos completo, podemos obtener fácilmente el primer lote del conjunto de datos. Luego podemos entrenar en el lote único 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:

# For all epochs, iterate over all batches of data.
for epoch in range(num_epochs): for batch in iter(dataloader): inputs, targets = batch predictions = model.train(inputs)

 

Si el modelo puede sobreajustarse a un solo lote, debería poder aprender los patrones en el conjunto de datos completo. Este método por lotes de sobreajuste permite una depuración más sencilla. Si el modelo ni siquiera puede sobreajustarse a un solo lote, podemos estar seguros de que hay un problema con la implementación del modelo y no con el conjunto de 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 recibe 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 según la secuencia de datos pasados, en lugar de aprender la varianza 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 configurar la reproducción aleatoria en True.

from torch.utils.data import DataLoader dataset = # Loading Data
dataloder = DataLoader(dataset, 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 del 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 ello, 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 image_transforms = transforms.Compose([ transforms.ToTensor(), # Normalize the values in our data transforms.Normalize(mean=(0.5,), std=(0.5))
])

 

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

El gradiente explosivo es un problema conocido en RNN y LSTM. Sin embargo, no se limita únicamente a estas arquitecturas. Cualquier modelo con capas profundas puede sufrir gradientes explosivos. La retropropagación en gradientes altos puede generar divergencia en lugar de una disminución gradual de la pérdida.

Considere 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() # Remove all previous gradients loss = criterion(targets, predictions) loss.backward() # Computes Gradients for model weights # Clip the gradients of model weights to a specified max_norm value. torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1) # Optimize the model weights AFTER CLIPPING optimizer.step()

 

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

Esta única línea de código seguramente aumentará la precisión de la prueba de su modelo. Casi siempre, un modelo de aprendizaje profundo utilizará capas de normalización y abandono. Estos solo son necesarios para un entrenamiento estable y para garantizar que el modelo no se sobreajuste ni diverja debido a la variación en los datos. Capas como BatchNorm y Dropout ofrecen regularización de los parámetros del modelo durante el entrenamiento. Sin embargo, una vez capacitados, no son necesarios. Cambiar un modelo al modo de evaluación desactiva las capas que solo se requieren para el entrenamiento y los parámetros completos del modelo se usan para la predicción.

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

for epoch in range(num_epochs): # Using training Mode when iterating over training dataset model.train() for batch in iter(train_dataloader): # Training Code and Loss Optimization # Using Evaluation Mode when checking accuarcy on validation dataset model.eval() for batch in iter(val_dataloader): # Only predictions and Loss Calculations. No backpropogation # No Optimzer Step so we do can omit unrequired layers.

 

Al evaluar, no necesitamos realizar 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 el abandono 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 Abandono. Esto aumentará sustancialmente la precisión del modelo, ya que podrá utilizar el modelo completo.

El modelo PyTorch normalmente se hereda de la clase base torch.nn.Module. Según la documentación:

Los submódulos asignados de esta manera se registrarán y sus parámetros también se convertirán cuando llame a(), 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 hace, no cambiará el dispositivo o el modo de entrenamiento para cada capa contenida dentro del modelo. Tendrás que hacerlo manualmente. La clase base del módulo realizará automáticamente las conversiones por usted una vez que use una función simplemente en el objeto modelo.

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

import torch
import torch.nn as nn # Inherit from the Module Base Class
class Model(nn.Module): def __init__(self, input_size, output_size): # Initialize the Module Parent Class super().__init__() self.dense_layers = nn.ModuleList() # Add 5 Linear Layers and contain them within a Modulelist for i in range(5): self.dense_layers.append( nn.Linear(input_size, 512) ) self.output_layer = nn.Linear(512, output_size) def forward(self, x): # Simplifies Foward Propogation. # Instead of repeating a single line for each layer, use a loop for layer in range(len(self.dense_layers)): x = layer(x) return self.output_layer(x)

 

El fragmento de código anterior muestra la forma correcta 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.

Los métodos mencionados anteriormente son las mejores prácticas para el marco de aprendizaje automático de PyTorch. Son ampliamente utilizados y están recomendados por la documentación de PyTorch. El uso de dichos métodos debería ser la forma principal de un 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 artificial y procesamiento de lenguaje natural. Ha trabajado en la implementación y optimización de varias aplicaciones de IA generativa que alcanzaron las listas de éxitos mundiales en Vyro.AI. Está interesado en construir y optimizar modelos de aprendizaje automático para sistemas inteligentes y cree en la mejora continua.
 

punto_img

Información más reciente

punto_img