Autograd
O autograd do PyTorch calcula automaticamente os gradientes de saídas escalares em relação às entradas de tensor. Ele impulsiona todo o treinamento de redes neurais através da diferenciação automática no modo reverso.
Receita
Cartão de receita de referência rápida - pronto para copiar e colar.
import torch
x = torch.tensor(2.0, requires_grad=True)
y = x ** 2 + 3 * x
y.backward()
print(x.grad) # dy/dx em x=2: 2*2+3 = 7
# Inferência: sem rastreamento de gradiente
with torch.no_grad():
pred = model(x)Quando usar isso:
- Para entender por que
loss.backward()eoptimizer.step()funcionam. - Para depurar o fluxo de gradientes em camadas ou funções de perda personalizadas.
- Para implementar funções autograd personalizadas para operações não padrão.
- Para desabilitar gradientes durante a inferência ou avaliação.
Exemplo de Trabalho
"""autograd.py - cálculo de gradiente e verificação de gradiente."""
import torch
import torch.nn as nn
# Grafo computacional simples
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])
# Forward: 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 com 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}")O que isso demonstra:
- Tensores folha (
w,b) acumulam gradientes em.grad. loss.backward()percorre o grafo em reverso.- Parâmetros do modelo recebem gradientes automaticamente.
zero_grad(set_to_none=True)limpa os gradientes de forma eficiente.
Mergulho Profundo
Como Funciona
- Cada operação de tensor registra as entradas e a função de backward em um grafo computacional.
backward()aplica a regra da cadeia da saída de volta para as folhas.- Apenas tensores com
requires_grad=Trueacumulam.grad. - Gradientes de tensores não folha são liberados após o backward, a menos que
retain_graph=True. torch.inference_mode()é mais rigoroso e rápido queno_grad()para inferência.
Controles de Gradiente
| Contexto | Efeito | Uso |
|---|---|---|
requires_grad=True | Rastreia operações | Parâmetros do modelo, entradas que precisam de gradiente |
torch.no_grad() | Desabilita rastreamento | Inferência, cálculo de métricas |
torch.inference_mode() | no-grad mais rigoroso | Inferência em produção |
.detach() | Desconecta do grafo | Interrompe gradientes através de um tensor |
retain_graph=True | Mantém o grafo após o backward | Múltiplas chamadas de backward |
Notas Python
# Função 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_inputArmadilhas
- Esquecer
zero_grad()- gradientes se acumulam entre as etapas. Correção: chameoptimizer.zero_grad(set_to_none=True)antes de cada backward. - Chamar backward duas vezes sem retain_graph - o grafo é liberado após o primeiro backward. Correção:
loss.backward(retain_graph=True)ou passes forward separados. - Operações in-place em tensores que precisam de gradiente - quebra o rastreamento do autograd. Correção: evite
x.add_(1)em tensores rastreados; usex = x + 1. - Memória de GPU de grafos salvos - manter referências a tensores de perda retém o grafo. Correção: use
.item()para log;del lossapós o backward. - Gradientes em tensores inteiros - apenas tensores de ponto flutuante/complexos suportam autograd. Correção: converta para float antes de operações que precisam de gradientes.
- Misturar numpy e torch - alterações in-place do numpy em memória compartilhada corrompem gradientes. Correção:
.detach().cpu().numpy()para exportação.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| PyTorch autograd | Padrão para redes neurais | Você precisa de matemática simbólica (use JAX) |
torch.func (functorch) | Gradientes por amostra, vmap | Treinamento simples de modelo |
| Gradientes manuais | Ensino, verificação | Código de modelo em produção |
| JAX autograd | Transformações funcionais, TPU | Ecossistema PyTorch existente |
FAQs
O que é um grafo computacional?
- Um grafo acíclico direcionado de operações de tensor.
- Construído dinamicamente em cada passe forward (define-by-run).
- Liberado após o backward, a menos que retido.
Por que a perda tem que ser um escalar para o backward?
backward()calcula gradientes de uma saída escalar.- Para saídas vetoriais, passe um argumento de gradiente:
y.backward(gradient=torch.ones_like(y)). - Funções de perda reduzem a um escalar automaticamente.
Qual a diferença entre no_grad e inference_mode?
inference_modedesabilita mais infraestrutura de autograd - mais rápido.- Use
inference_modepara inferência em produção. no_gradé aceitável para loops de validação durante o treinamento.
Como verifico se os gradientes estão fluindo?
for name, p in model.named_parameters():
if p.grad is None:
print(f"no grad: {name}")- Gradientes ausentes indicam grafo desconectado ou camadas congeladas.
O que significa requires_grad=False nos parâmetros?
- Congela o parâmetro - nenhum gradiente é calculado ou atualizado.
- Use para aprendizado de transferência em camadas iniciais.
- Defina
param.requires_grad = Falseou padrõesmodel.freeze().
O que é clipping de gradiente?
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)- Limita a magnitude do gradiente antes de
optimizer.step(). - Previne gradientes explosivos em RNNs e redes profundas.
Posso calcular segundas derivadas?
loss.backward(create_graph=True)
grad_grad = torch.autograd.grad(loss, model.parameters(), create_graph=True)create_graph=Truemantém o grafo para gradientes de ordem superior.- Necessário para alguns algoritmos de meta-aprendizado.
O que é set_to_none em zero_grad?
optimizer.zero_grad(set_to_none=True)define.gradcomo None em vez de zero.- Ligeiramente mais rápido e reduz a memória em modelos grandes.
- Padrão recomendado em PyTorch 2.x.
Como o autograd interage com torch.compile?
- Modelos compilados ainda usam autograd para treinamento.
- A compilação apenas para inferência pode pular o autograd completamente.
- Teste loops de treinamento compilados para equivalência numérica.
O que são tensores folha?
- Tensores criados diretamente pelo usuário (não de operações).
- Apenas tensores folha têm
.gradpreenchido por padrão. - Use
retain_grad()em tensores não folha, se necessário.
Por que meus gradientes explodem?
- Taxa de aprendizado muito alta, redes profundas não normalizadas ou arquiteturas recorrentes.
- Corrija com clipping de gradiente, LR menor, normalização de camada.
Como desabilito o gradiente para parte do passe forward?
with torch.no_grad():
features = frozen_encoder(x)
output = trainable_head(features)- Padrão comum em aprendizado de transferência.
Relacionados
- Fundamentos do PyTorch - fundamentos de tensor
- Loops de Treinamento - backward na prática
- Construindo Modelos com nn.Module - nn.Parameter
- Aprendizado de Transferência e Fine-Tuning - congelando camadas
- GPUs e Precisão Mista - autocast e escalonamento de gradiente
Versões da Stack: Esta página foi escrita para Python 3.14.0 (estável 3.14, manutenção 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+, e uv 0.6+.