Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

438
Vistas
¿Por qué necesitamos llamar a zero_grad() en PyTorch?

¿Por qué es necesario llamar a zero_grad() durante el entrenamiento?

 | zero_grad(self) | Sets gradients of all model parameters to zero.
over 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

En PyTorch , para cada mini lote durante la fase de entrenamiento , por lo general queremos establecer explícitamente los gradientes en cero antes de comenzar a hacer la retropropagación (es decir, actualizar los pesos y sesgos ) porque PyTorch acumula los gradientes en los pases hacia atrás posteriores. Este comportamiento de acumulación es conveniente cuando se entrenan RNN o cuando queremos calcular el gradiente de la pérdida sumada en varios minilotes . Por lo tanto, la acción predeterminada se ha configurado para acumular (es decir, sumar) los gradientes en cada llamada loss.backward() .

Debido a esto, cuando comience su ciclo de entrenamiento, idealmente debería poner a zero out the gradients para que pueda actualizar los parámetros correctamente. De lo contrario, el gradiente sería una combinación del gradiente antiguo, que ya ha utilizado para actualizar los parámetros de su modelo, y el gradiente recién calculado. Por lo tanto, apuntaría en alguna otra dirección que la dirección prevista hacia el mínimo (o máximo , en el caso de objetivos de maximización).

Aquí hay un ejemplo simple:

 import torch from torch.autograd import Variable import torch.optim as optim def linear_model(x, W, b): return torch.matmul(x, W) + b data, targets = ... W = Variable(torch.randn(4, 3), requires_grad=True) b = Variable(torch.randn(3), requires_grad=True) optimizer = optim.Adam([W, b]) for sample, target in zip(data, targets): # clear out the gradients of all Variables # in this optimizer (ie W, b) optimizer.zero_grad() output = linear_model(sample, W, b) loss = (output - target) ** 2 loss.backward() optimizer.step()

Alternativamente, si está haciendo un descenso de gradiente de vainilla , entonces:

 W = Variable(torch.randn(4, 3), requires_grad=True) b = Variable(torch.randn(3), requires_grad=True) for sample, target in zip(data, targets): # clear out the gradients of Variables # (ie W, b) W.grad.data.zero_() b.grad.data.zero_() output = linear_model(sample, W, b) loss = (output - target) ** 2 loss.backward() W -= learning_rate * W.grad.data b -= learning_rate * b.grad.data

Nota :

  • La acumulación (es decir, la suma ) de gradientes ocurre cuando se llama a .backward() en el tensor de loss .
  • A partir de la versión 1.7.0, Pytorch ofrece la opción de restablecer los gradientes a None optimizer.zero_grad(set_to_none=True) en lugar de llenarlos con un tensor de ceros. Los documentos afirman que esta configuración reduce los requisitos de memoria y mejora ligeramente el rendimiento, pero puede ser propenso a errores si no se maneja con cuidado.
over 4 years ago · Juan Pablo Isaza Denunciar

0

Aunque la idea se puede derivar de la respuesta elegida, siento que quiero escribir eso explícitamente.

Ser capaz de decidir cuándo llamar optimizer.zero_grad() optimizer.step() proporciona más libertad sobre cómo el optimizador acumula y aplica el gradiente en el ciclo de entrenamiento. Esto es crucial cuando el modelo o los datos de entrada son grandes y un lote de entrenamiento real no cabe en la tarjeta gpu.

Aquí, en este ejemplo de google-research, hay dos argumentos, llamados train_batch_size y gradient_accumulation_steps .

  • train_batch_size es el tamaño del lote para el pase hacia adelante, después de loss.backward() . Esto está limitado por la memoria gpu.

  • gradient_accumulation_steps es el tamaño real del lote de entrenamiento, donde se acumula la pérdida de varias pasadas hacia adelante. Esto NO está limitado por la memoria gpu.

A partir de este ejemplo, puede ver cómo optimizer.zero_grad() puede ser seguido por Optimizer.step( optimizer.step() pero NO loss.backward() . loss.backward() se invoca en cada iteración (línea 216), pero Optimizer.Zero_grad( optimizer.zero_grad() y Optimizer.Step( optimizer.step() solo se invocan cuando el número de lotes de tren acumulados es igual a los pasos de acumulación de gradient_accumulation_steps (línea 227 dentro del bloque if en la línea 219 )

https://github.com/google-research/xtreme/blob/master/third_party/run_classify.py

También alguien pregunta sobre el método equivalente en TensorFlow. Supongo que tf.GradientTape tiene el mismo propósito.

(Todavía soy nuevo en la biblioteca AI, corríjame si algo de lo que dije está mal)

over 4 years ago · Juan Pablo Isaza Denunciar

0

zero_grad() reinicia el bucle sin pérdidas desde el último paso si usa el método de gradiente para disminuir el error (o las pérdidas).

Si no usa zero_grad() la pérdida aumentará, no disminuirá, según sea necesario.

Por ejemplo:

Si usa zero_grad() obtendrá el siguiente resultado:

 model training loss is 1.5 model training loss is 1.4 model training loss is 1.3 model training loss is 1.2

Si no usa zero_grad() obtendrá el siguiente resultado:

 model training loss is 1.4 model training loss is 1.9 model training loss is 2 model training loss is 2.8 model training loss is 3.5
over 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda