Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

437
Views
¿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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!