Autograd
PyTorch autograd calcula automáticamente los gradientes de las salidas escalares con respecto a las entradas tensoriales. Potencia todo el entrenamiento de redes neuronales a través de la diferenciación automática en modo reverso.
Receta
Tarjeta de referencia rápida - lista para copiar y pegar.
import torch
x = torch.tensor(2.0, requires_grad=True)
y = x ** 2 + 3 * x
y.backward()
print(x.grad) # dy/dx en x=2: 2*2+3 = 7
# Inferencia: sin seguimiento de gradientes
with torch.no_grad():
pred = model(x)Cuándo usar esto:
- Para entender por qué funcionan
loss.backward()yoptimizer.step(). - Para depurar el flujo de gradientes en capas o funciones de pérdida personalizadas.
- Para implementar funciones autograd personalizadas para operaciones no estándar.
- Para deshabilitar gradientes durante la inferencia o evaluación.
Ejemplo de Trabajo
"""autograd.py - cálculo de gradientes y verificación de gradientes."""
import torch
import torch.nn as nn
# Grafo de cómputo simple
w = torch.tensor([1.0, 2.0], requires_grad=True)
b = torch.tensor(0.5, requires_grad=True)
x = torch.tensor([3.0, 4.0])
# Adelante: y = w . x + b, loss = y^2
y = (w * x).sum() + b
loss = y ** 2
loss.backward()
print("w.grad:", w.grad) # d(loss)/dw
print("b.grad:", b.grad) # d(loss)/db
# Modelo con autograd
model = nn.Linear(3, 1)
x_batch = torch.randn(16, 3)
target = torch.randn(16, 1)
model.zero_grad(set_to_none=True)
pred = model(x_batch)
loss = nn.functional.mse_loss(pred, target)
loss.backward()
for name, param in model.named_parameters():
print(f"{name}: grad norm = {param.grad.norm().item():.4f}")Lo que esto demuestra:
- Los tensores hoja (
w,b) acumulan gradientes en.grad. loss.backward()recorre el grafo en reversa.- Los parámetros del modelo reciben gradientes automáticamente.
zero_grad(set_to_none=True)limpia los gradientes de manera eficiente.
Profundización
Cómo Funciona
- Cada operación tensorial registra las entradas y la función de retroceso en un grafo de cómputo.
backward()aplica la regla de la cadena desde la salida hacia las hojas.- Solo los tensores con
requires_grad=Trueacumulan.grad. - Los gradientes de los tensores no hoja se liberan después de
backwarda menos queretain_graph=True. torch.inference_mode()es más estricto y rápido queno_grad()para la inferencia.
Controles de Gradiente
| Contexto | Efecto | Uso |
|---|---|---|
requires_grad=True | Rastrea operaciones | Parámetros del modelo, entradas que necesitan gradiente |
torch.no_grad() | Deshabilita el rastreo | Inferencia, cálculo de métricas |
torch.inference_mode() | Modo sin gradiente más estricto | Inferencia en producción |
.detach() | Rompe la conexión con el grafo | Detiene gradientes a través de un tensor |
retain_graph=True | Mantiene el grafo después de backward | Múltiples llamadas a backward |
Notas de Python
# Función autograd personalizada
class MyReLU(torch.autograd.Function):
@staticmethod
def forward(ctx, input):
ctx.save_for_backward(input)
return input.clamp(min=0)
@staticmethod
def backward(ctx, grad_output):
input, = ctx.saved_tensors
grad_input = grad_output.clone()
grad_input[input < 0] = 0
return grad_inputErrores Comunes
- Olvidar
zero_grad()- los gradientes se acumulan entre pasos. Solución: llama aoptimizer.zero_grad(set_to_none=True)antes de cadabackward. - Llamar a
backwarddos veces sinretain_graph- el grafo se libera después de la primera llamada abackward. Solución:loss.backward(retain_graph=True)o pases hacia adelante separados. - Operaciones in-place en tensores que necesitan gradiente - rompe el seguimiento de autograd. Solución: evita
x.add_(1)en tensores rastreados; usax = x + 1. - Memoria de GPU por grafos guardados - mantener referencias a tensores de pérdida retiene el grafo. Solución: usa
.item()para registrar;del lossdespués debackward. - Gradientes en tensores enteros - solo los tensores de punto flotante/complejos soportan autograd. Solución: convierte a
floatantes de operaciones que necesiten gradientes. - Mezclar numpy y torch - los cambios in-place de numpy en memoria compartida corrompen los gradientes. Solución: usa
.detach().cpu().numpy()para exportar.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| PyTorch autograd | Por defecto para redes neuronales | Necesitas matemáticas simbólicas (usa JAX) |
torch.func (functorch) | Gradientes por muestra, vmap | Entrenamiento de modelos simple |
| Gradientes manuales | Enseñanza, verificación | Código de modelo en producción |
| JAX autograd | Transformaciones funcionales, TPU | Ecosistema PyTorch existente |
Preguntas Frecuentes
¿Qué es un grafo de cómputo?
- Un grafo acíclico dirigido de operaciones tensoriales.
- Construido dinámicamente en cada pase hacia adelante (define-por-ejecución).
- Liberado después de
backwarda menos que se retenga.
¿Por qué la pérdida debe ser un escalar para `backward`?
backward()calcula los gradientes de una salida escalar.- Para salidas vectoriales, pasa un argumento de gradiente:
y.backward(gradient=torch.ones_like(y)). - Las funciones de pérdida se reducen a un escalar automáticamente.
¿Cuál es la diferencia entre `no_grad` y `inference_mode`?
inference_modedeshabilita más infraestructura de autograd - más rápido.- Usa
inference_modepara inferencia en producción. no_gradestá bien para bucles de validación durante el entrenamiento.
¿Cómo compruebo si los gradientes están fluyendo?
for name, p in model.named_parameters():
if p.grad is None:
print(f"no grad: {name}")- Gradientes faltantes indican un grafo desconectado o capas congeladas.
¿Qué hace `requires_grad=False` en los parámetros?
- Congela el parámetro - no se calcula ni se actualiza ningún gradiente.
- Úsalo para aprendizaje por transferencia en capas tempranas.
- Establece
param.requires_grad = Falseo usa patrones comomodel.freeze().
¿Qué es el recorte de gradientes?
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)- Limita la magnitud del gradiente antes de
optimizer.step(). - Previene la explosión de gradientes en RNNs y redes profundas.
¿Puedo calcular segundas derivadas?
loss.backward(create_graph=True)
grad_grad = torch.autograd.grad(loss, model.parameters(), create_graph=True)create_graph=Truemantiene el grafo para gradientes de orden superior.- Necesario para algunos algoritmos de meta-aprendizaje.
¿Qué significa `set_to_none` en `zero_grad`?
optimizer.zero_grad(set_to_none=True)establece.gradaNoneen lugar de cero.- Ligeramente más rápido y reduce la memoria en modelos grandes.
- Patrón recomendado por defecto en PyTorch 2.x.
¿Cómo interactúa autograd con `torch.compile`?
- Los modelos compilados todavía usan autograd para el entrenamiento.
- La compilación solo para inferencia puede omitir autograd por completo.
- Prueba los bucles de entrenamiento compilados para equivalencia numérica.
¿Qué son los tensores hoja?
- Tensores creados directamente por el usuario (no a partir de operaciones).
- Solo los tensores hoja tienen
.gradpoblado por defecto. - Usa
retain_grad()en tensores no hoja si es necesario.
¿Por qué explotan mis gradientes?
- Tasa de aprendizaje demasiado alta, redes profundas no normalizadas o arquitecturas recurrentes.
- Solución: recorte de gradientes, LR más bajo, normalización de capas.
¿Cómo deshabilito el gradiente para una parte del pase hacia adelante?
with torch.no_grad():
features = frozen_encoder(x)
output = trainable_head(features)- Patrón común en aprendizaje por transferencia.
Relacionado
- Fundamentos de PyTorch - fundamentos de tensores
- Bucles de Entrenamiento -
backwarden la práctica - Construcción de Modelos con nn.Module -
nn.Parameter - Aprendizaje por Transferencia y Ajuste Fino - congelación de capas
- GPUs y Precisión Mixta -
autocasty escalado de gradientes
Versiones de Stack: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.