Fundamentos

Python, NumPy e PyTorch em 20 minutos

Um fluxo compacto cobre arrays, tensores, broadcasting, diferenciação automática, módulos e experimentos seguros.

Atualizada em

1

Conceito

Python é a camada de coordenação de muito trabalho em machine learning. Você usa variáveis, funções, loops, imports e exceções comuns, enquanto bibliotecas numéricas executam operações pesadas em kernels compilados. O hábito importante é tornar o fluxo de dados explícito. Dê significado aos shapes, evite estado global escondido, confira premissas nas fronteiras e torne um experimento pequeno reproduzível antes de escalar.

O objeto central do NumPy é o array multidimensional. Este exemplo executável cria duas matrizes e as multiplica:

import numpy as np

x = np.array([[1.0, 2.0], [3.0, 4.0]])
w = np.array([[0.5, -1.0], [1.5, 2.0]])
y = x @ w
print(y.shape, y)

x * w, elemento a elemento, difere de x @ w, multiplicação matricial. Inspecione .shape, .dtype e, quando necessário, .strides. Broadcasting permite que um array menor compatível atue sobre um maior: somar shape (features,) a (batch, features) adiciona o mesmo bias a cada linha. A conveniência também pode esconder erros; raciocine primeiro sobre as dimensões pretendidas.

Tensores PyTorch oferecem operações parecidas, devices e diferenciação automática. Tensores numa mesma operação normalmente precisam de dtypes compatíveis e do mesmo device. Mover um tensor para GPU não move todos os objetos relacionados. Comece em CPU para exemplos minúsculos; introduza aceleração quando o compute e o custo de transferência justificarem.

Autograd registra operações envolvendo tensores que pedem gradientes. O exemplo aprende um peso escalar:

import torch

torch.manual_seed(7)
x = torch.tensor([1.0, 2.0, 3.0])
target = torch.tensor([2.0, 4.0, 6.0])
w = torch.nn.Parameter(torch.tensor(0.0))
optimizer = torch.optim.SGD([w], lr=0.1)

for _ in range(20):
    optimizer.zero_grad()
    prediction = w * x
    loss = ((prediction - target) ** 2).mean()
    loss.backward()
    optimizer.step()

print(w.item())

O loop tem ritmo estável: limpar gradientes, rodar o forward, reduzir erros a uma loss escalar, chamar backward e atualizar parâmetros. backward calcula gradientes; não muda parâmetros. step os muda; não calcula a loss. Separar responsabilidades facilita o debug.

Modelos maiores compõem módulos existentes ou estendem torch.nn.Module. Parâmetros registrados aparecem em model.parameters(). model.train() e model.eval() mudam o comportamento de módulos como dropout; não ligam ou desligam gradientes. Use with torch.no_grad(): na avaliação quando derivadas forem desnecessárias. Salve um state_dict e configuração suficiente para reconstruir o modelo, em vez de estado opaco de execução.

Reprodutibilidade exige mais que uma seed. Registre versões, splits, pré-processamento, hiperparâmetros, device, precisão e avaliação. Operações em aceleradores podem continuar não determinísticas. Compare com baseline simples, examine exemplos individuais e faça assertions de shape e loss finita. Um training loop verde consegue otimizar perfeitamente o target errado.

A habilidade portátil não é decorar APIs, mas ler programas como transformações de shape com estado explícito. Pergunte o significado de cada eixo, quais valores pedem gradiente, onde entra aleatoriedade, qual redução cria a loss e quando parâmetros mudam. Com essa disciplina, NumPy e PyTorch viram instrumentos transparentes, não sintaxe mágica.

No debug, guarde o menor tensor que reproduz a falha e seu shape esperado. Dez números inspecionáveis normalmente ensinam mais do que executar novamente um training job opaco com milhões de valores.

2

Como explicar para uma criança de cinco anos

Pense em Python como a linguagem da oficina, NumPy como uma bancada precisa de medição e corte e PyTorch como a mesma oficina com uma câmera gravando cada operação diferenciável. Depois de calcular a loss, autograd rebobina a gravação para medir como cada botão ajustável afetou o resultado. A câmera não escolhe um bom projeto nem detecta uma medida errada; ela diferencia fielmente as operações executadas.

3

Ensine de volta

Descreva uma etapa mínima de treinamento em PyTorch e os papéis de shapes, autograd, zero_grad, backward e optimizer.step.

Mínimo: 80 caracteres e 15 palavras. Seu texto fica somente neste navegador.

Salvo somente neste dispositivo.

Ver uma resposta-modelo

Entradas e targets são tensores com shapes deliberados. O modelo calcula previsões e uma loss escalar enquanto autograd registra operações diferenciáveis. optimizer.zero_grad limpa gradientes acumulados. loss.backward calcula gradientes dos parâmetros no grafo. optimizer.step atualiza parâmetros. Shape, dtype, device, modos train/eval e seeds precisam de controle porque autograd não sabe se o experimento está logicamente correto.

4

Teste seu entendimento

1. Por que optimizer.zero_grad costuma vir antes de backward?
Resposta e explicação

PyTorch acumula gradientes por padrão — Acumulação é útil em alguns fluxos, mas uma etapa independente comum precisa limpar os gradientes anteriores.

2. O que broadcasting faz?
Resposta e explicação

Aplica shapes menores compatíveis sobre dimensões maiores sem cópias manuais — Broadcasting alinha dimensões por regras precisas; ainda é essencial inspecionar os shapes resultantes.

Conclua o teach-back e acerte o quiz para finalizar a aula.

Fontes

  1. Charles R. Harris et al. (2020). Array programming with NumPy.
  2. Adam Paszke et al. (2019). PyTorch: An Imperative Style, High-Performance Deep Learning Library.