Redes Neurais:
do zero absoluto ao mercado de trabalho
Um guia progressivo para quem nunca programou nem viu cálculo, escrito para formar profissionais — não apenas curiosos. Cada capítulo termina conectando a teoria ao que empresas realmente pedem em vagas de IA.
Estude os capítulos em ordem — cada um assume apenas o que veio antes. No topo da página há um seletor PyTorch / Keras: escolha um framework e todos os exemplos de código da apostila mudam juntos. Recomendação de mercado: aprenda os conceitos com um, depois releia os códigos no outro (leva poucas horas e dobra seu alcance em vagas). Faça os exercícios antes de abrir as respostas.
O que são redes neurais (e por que todo mundo quer contratar quem as domina)
Sem código, sem matemática. Só as ideias — e o contexto de mercado que justifica seu estudo.
1.1 IA, Machine Learning e Deep Learning: quem é quem
Esses três termos aparecem misturados em notícias e vagas de emprego, mas têm uma relação simples de "caixas dentro de caixas":
- Inteligência Artificial (IA) é a caixa maior: qualquer técnica que faça máquinas executarem tarefas que associamos à inteligência (decidir, reconhecer, prever, conversar).
- Machine Learning (ML), ou aprendizado de máquina, é uma caixa dentro da IA: em vez de um programador escrever regras à mão ("se o e-mail contém 'grátis', é spam"), o computador descobre as regras sozinho a partir de exemplos.
- Deep Learning (DL), ou aprendizado profundo, é uma caixa dentro do ML: a família de técnicas baseada em redes neurais com muitas camadas. É o motor do ChatGPT, dos carros autônomos, dos filtros de câmera e dos sistemas de recomendação.
Programação tradicional: você escreve as regras, entra o dado, sai a resposta. Machine learning inverte o jogo: entram dados + respostas conhecidas (exemplos), e sai um modelo — um conjunto de regras aprendidas automaticamente, capaz de responder para casos que nunca viu.
1.2 O que é uma rede neural, em uma frase
Uma rede neural é uma função matemática ajustável, montada com milhares (ou bilhões) de "botõezinhos" numéricos chamados pesos, que transforma entradas (pixels, palavras, valores de uma planilha) em saídas (uma categoria, um preço, a próxima palavra de uma frase). "Treinar" a rede é girar esses botões, pouco a pouco, até que as saídas fiquem boas.
O nome vem de uma inspiração frouxa no cérebro: neurônios biológicos recebem sinais de outros neurônios, e disparam quando a soma dos estímulos passa de um limiar. O neurônio artificial imita esse esquema com aritmética simples — você fará essa conta à mão no Capítulo 4.
1.3 Uma história em quatro atos
| Época | O que aconteceu | Por que importa |
|---|---|---|
| 1943–1958 | McCulloch & Pitts modelam o neurônio matemático; Rosenblatt cria o Perceptron. | Nasce a ideia de máquina que aprende com exemplos. |
| 1969–1986 | "Inverno da IA" após críticas ao Perceptron; em 1986, o algoritmo de backpropagation é popularizado. | Backpropagation é, até hoje, o mecanismo de aprendizado de praticamente todas as redes. |
| 2012 | A rede AlexNet esmaga a competição de reconhecimento de imagens ImageNet usando GPUs. | Início da era do deep learning: dados massivos + GPUs + redes profundas. |
| 2017–hoje | O artigo "Attention Is All You Need" cria o Transformer, base do GPT, Claude, Gemini, Llama... | É a arquitetura que domina o mercado atual — você a estudará no Capítulo 12. |
1.4 Onde redes neurais estão empregadas (literalmente)
- Visão computacional: diagnóstico por imagem, inspeção industrial, agricultura de precisão, segurança.
- Linguagem (NLP): chatbots, análise de sentimento, tradução, busca semântica, copilotos de código.
- Dados tabulares e negócios: previsão de churn, crédito, fraude, demanda e precificação.
- Áudio e recomendação: transcrição, assistentes de voz, feeds de redes sociais e streaming.
As vagas mais comuns que exigem este conteúdo no Brasil e no exterior: Cientista de Dados, Engenheiro(a) de Machine Learning, Engenheiro(a) de IA e Analista de Dados (porta de entrada). Recrutadores filtram por palavras-chave que você verá nesta apostila: Python, PyTorch, TensorFlow, deep learning, NLP, computer vision, MLOps, Hugging Face. Guarde isto: no fim de cada capítulo, a caixa laranja como esta traduz o conteúdo em linguagem de vaga de emprego.
Exercícios do capítulo
Ex 1.1 Explique com suas palavras a diferença entre programação tradicional e machine learning.
Na programação tradicional, o humano escreve as regras e o computador as aplica aos dados. No machine learning, o humano fornece dados com respostas conhecidas, e o computador descobre as regras (o modelo) sozinho. O modelo aprendido é então usado para responder sobre dados novos.
Ex 1.2 Um app que identifica plantas por foto usa qual das três caixas: IA, ML ou DL?
As três ao mesmo tempo: é um sistema de IA, construído com machine learning, quase certamente usando deep learning (uma rede convolucional, que você verá no Capítulo 10), pois reconhecimento de imagens é o território clássico das redes neurais profundas.
Matemática sem medo: só o que você realmente precisa
Quatro ideias — vetor, matriz, derivada e gradiente — explicadas como se você nunca tivesse visto nada disso. Porque talvez você nunca tenha. E está tudo bem.
Boa notícia: para usar redes neurais profissionalmente você não precisa de anos de faculdade de matemática. Precisa de quatro conceitos, entendidos com intuição sólida. Os frameworks (PyTorch, Keras) fazem as contas pesadas; seu trabalho é entender o que está sendo calculado e por quê.
2.1 Vetores: listas de números com significado
Um vetor é simplesmente uma lista ordenada de números. O pulo do gato é perceber que qualquer coisa pode virar vetor:
Um cliente → [idade, renda, compras_no_mês] → [34, 5200, 7]
Um pixel → [vermelho, verde, azul] → [255, 128, 0]
Redes neurais só entendem números. Portanto, o primeiro passo de qualquer projeto de IA é transformar o mundo (fotos, textos, cadastros) em vetores. Cada número do vetor é chamado de feature (característica) — palavra que aparece em toda vaga da área.
2.2 Matrizes: tabelas de números e a operação mais importante do deep learning
Uma matriz é uma tabela de números (linhas × colunas). Um dataset inteiro é uma matriz: cada linha é um exemplo (um vetor), cada coluna uma feature. E os pesos de uma camada de rede neural também são guardados numa matriz.
A operação-chave é a multiplicação de matriz por vetor. Parece assustador, mas é só uma sequência de "multiplica e soma". Exemplo com uma matriz 2×3 e um vetor de 3 números:
[ 0 1 4 ] [ 1 ]
[ 2 ]
Linha 1: (1×3) + (2×1) + (0×2) = 5
Linha 2: (0×3) + (1×1) + (4×2) = 9
Resultado: W·x = [5, 9]
Multiplicar matriz por vetor = calcular várias médias ponderadas de uma vez. Cada linha da matriz é um conjunto de "importâncias" (pesos) aplicadas às entradas. Uma rede neural inteira é, em grande parte, uma cadeia dessas multiplicações. GPUs são valiosas justamente porque fazem bilhões dessas operações em paralelo.
2.3 Derivada: a pergunta "se eu mexer aqui, o que acontece ali?"
Esqueça as fórmulas do colégio por um instante. A derivada responde a uma pergunta prática:
"Se eu aumentar esta entrada um pouquinho, a saída sobe ou desce — e quão rápido?"
- Derivada positiva: aumentar a entrada aumenta a saída (subida).
- Derivada negativa: aumentar a entrada diminui a saída (descida).
- Derivada zero: a saída está num ponto plano (topo, vale ou platô).
Exemplo concreto: se o erro do seu modelo em função de um peso w tem derivada +4 no valor atual, isso significa "aumentar w piora o erro". Logo, devemos diminuir w. Essa frase é literalmente o coração do treinamento de redes neurais.
2.4 Gradiente: a derivada quando há milhões de botões
Uma rede real tem milhões de pesos. O gradiente é o pacote com a derivada do erro em relação a cada um dos pesos, todas de uma vez. Ele funciona como uma bússola: aponta a direção em que o erro cresce mais rápido. Para melhorar o modelo, andamos na direção oposta ao gradiente — a famosa descida do gradiente (gradient descent), detalhada no Capítulo 6.
Você está numa montanha de neblina densa (não enxerga nada além dos pés) e quer chegar ao vale. Estratégia: sentir a inclinação do chão sob os pés e dar um passo morro abaixo. Repetir milhares de vezes. A inclinação sob seus pés é o gradiente; o tamanho do passo é a taxa de aprendizado (learning rate); o vale é o erro mínimo. Treinamento de rede neural é exatamente isso.
2.5 Bônus: probabilidade em 60 segundos
Muitas redes terminam produzindo probabilidades: "87% gato, 13% cachorro". Você só precisa saber que probabilidades ficam entre 0 e 1 e que, num conjunto de opções exclusivas, somam 1. A função softmax (Capítulo 5) é o que converte números crus da rede nessas porcentagens.
Em entrevistas de emprego júnior, ninguém pede para você derivar fórmulas no quadro. Pedem intuição: "explique gradient descent para um leigo", "o que é learning rate?". Quem responde com a metáfora da montanha e sabe conectá-la ao código passa. A base deste capítulo é exatamente o que essas perguntas cobram.
Exercícios do capítulo
Ex 2.1 Transforme em vetor: um filme com duração 142 min, ano 2010, nota 8.8 e orçamento de 160 milhões.
[142, 2010, 8.8, 160]. Cada posição é uma feature. (No Capítulo 9 você verá que, na prática, normalizamos esses números para escalas parecidas antes de treinar.)
Ex 2.2 Calcule W·x para W = [[2, 1], [0, 3]] e x = [4, 5].
Linha 1: (2×4) + (1×5) = 13. Linha 2: (0×4) + (3×5) = 15. Resultado: [13, 15].
Ex 2.3 A derivada do erro em relação a um peso é −2.5. O peso deve aumentar ou diminuir para reduzir o erro?
Derivada negativa significa que aumentar o peso diminui o erro. Portanto, o peso deve aumentar. Regra geral: o peso anda no sentido oposto ao sinal da derivada — por isso a fórmula da atualização é w = w − lr × derivada.
Python para IA: o mínimo que abre todas as portas
Ambiente gratuito, sintaxe essencial e NumPy — a biblioteca que sustenta todo o ecossistema.
3.1 Onde programar sem instalar nada
Use o Google Colab (colab.research.google.com): um caderno de código no navegador, gratuito, com GPU incluída e PyTorch/TensorFlow pré-instalados. É o padrão para estudar e prototipar — e citado em processos seletivos como ferramenta aceitável para os desafios técnicos iniciais. Alternativa local: instale o Anaconda e use Jupyter Notebook ou VS Code.
3.2 Python essencial em uma página
# Variáveis e tipos
idade = 25 # inteiro
preco = 19.9 # decimal (float)
nome = "Ana" # texto (string)
aprovado = True # booleano
# Listas: a estrutura mais usada
notas = [7.5, 8.0, 9.2]
notas.append(6.8) # adiciona ao final
print(notas[0]) # 7.5 (índices começam em 0!)
# Condições e repetição
for n in notas:
if n >= 7:
print(n, "aprovado")
else:
print(n, "recuperação")
# Funções: blocos reutilizáveis
def media(lista):
return sum(lista) / len(lista)
print(media(notas)) # 7.875
Se cada linha acima fez sentido, você tem o suficiente para acompanhar a apostila. Se não, invista 1–2 semanas num curso introdutório de Python antes de prosseguir — é o melhor investimento possível.
3.3 NumPy: vetores e matrizes de verdade
NumPy é a biblioteca que implementa os vetores e matrizes do Capítulo 2 com altíssima velocidade. PyTorch e TensorFlow copiaram sua interface, então aprender NumPy é aprender 70% deles de graça.
import numpy as np
x = np.array([3, 1, 2]) # vetor
W = np.array([[1, 2, 0],
[0, 1, 4]]) # matriz 2x3
y = W @ x # multiplicação matriz-vetor: [5, 9]
# Exatamente a conta que fizemos à mão no Capítulo 2!
x * 2 # [6, 2, 4] — opera em todos de uma vez
x.mean(), x.max(), x.shape # 2.0, 3, (3,)
dados = np.random.randn(100, 4) # matriz 100x4 de nºs aleatórios
dados[:, 0] # primeira coluna (todas as linhas)
dados[dados[:, 0] > 0] # filtra linhas pela condição
O atributo .shape informa as dimensões de um array — por exemplo, (100, 4) = 100 linhas, 4 colunas. A maioria dos erros de iniciante em deep learning é incompatibilidade de shapes ("mat1 and mat2 shapes cannot be multiplied"). Crie o hábito profissional: imprima o shape antes e depois de cada transformação.
3.4 As outras bibliotecas do arsenal
| Biblioteca | Para quê | Status no mercado |
|---|---|---|
| pandas | Ler e manipular tabelas (CSV, Excel, SQL) | Obrigatória em 100% das vagas de dados |
| matplotlib / seaborn | Gráficos e visualização | Esperada; usada para analisar treinos |
| scikit-learn | ML clássico (sem redes neurais) e métricas | Muito cobrada; complementa o deep learning |
| PyTorch | Deep learning (estilo "Python puro") | Domina pesquisa e cresce na indústria |
| TensorFlow/Keras | Deep learning (estilo "alto nível") | Forte em produção e em grandes empresas |
Vagas júnior de dados pedem, quase palavra por palavra: "Python, pandas, NumPy, scikit-learn; desejável PyTorch ou TensorFlow". Esta apostila cobre exatamente essa pilha. Dica de ouro: crie uma conta no GitHub hoje e suba cada exercício resolvido — no Capítulo 17 esse material vira seu portfólio.
Exercícios do capítulo
Ex 3.1 No Colab, crie um vetor NumPy com 5 preços e calcule média, máximo e o vetor com 10% de desconto.
p = np.array([10.0, 25.5, 8.9, 40.0, 15.0])
p.mean() # 19.88
p.max() # 40.0
p * 0.9 # desconto aplicado a todos de uma vezEx 3.2 Qual o shape de np.random.randn(32, 28, 28)? O que ele poderia representar?
(32, 28, 28): 32 matrizes de 28×28. Em deep learning, isso é um batch (lote) de 32 imagens em tons de cinza de 28×28 pixels — exatamente o formato do dataset MNIST que usaremos no Capítulo 7.
O neurônio artificial: a peça de Lego de toda a IA moderna
Você vai fazer a conta de um neurônio à mão — e descobrir que cabe num guardanapo.
4.1 A anatomia do neurônio
Um neurônio artificial faz apenas três passos:
- Multiplica cada entrada pelo seu peso (a "importância" daquela entrada).
- Soma tudo e adiciona um número extra chamado viés (bias) — um ajuste fino, como o "ponto de partida" da decisão.
- Passa o resultado por uma função de ativação, que decide a intensidade do sinal de saída.
4.2 Exemplo à mão: o neurônio "vou sair de casa hoje?"
Entradas (0 = não, 1 = sim): x₁ = está ensolarado? · x₂ = tenho companhia? · x₃ = estou cansado?
Suponha pesos aprendidos: w₁ = 3 (sol importa muito), w₂ = 2 (companhia importa), w₃ = −4 (cansaço pesa contra) e viés b = −2 (tendência caseira).
soma = (3×1) + (2×0) + (−4×1) + (−2) = 3 + 0 − 4 − 2 = −3
ativação degrau: −3 < 0 → saída = 0 → fico em casa
Dia: sol ✔ (1), companhia ✔ (1), cansado ✘ (0)
soma = 3 + 2 + 0 − 2 = +3 → saída = 1 → saio!
O neurônio é uma votação ponderada: cada entrada vota com força proporcional ao seu peso; o viés define quão difícil é aprovar a proposta. Aprender é descobrir os pesos e o viés certos a partir de exemplos — em vez de defini-los à mão como fizemos aqui.
4.3 Funções de ativação: o ingrediente da inteligência
Sem ativação, empilhar neurônios seria inútil: combinações de somas ponderadas continuam sendo somas ponderadas (tudo "linear" — só retas). A ativação introduz não linearidade, permitindo que a rede aprenda curvas, fronteiras complexas e padrões ricos.
| Função | Fórmula/comportamento | Quando usar |
|---|---|---|
| ReLU | máx(0, z): negativo vira 0, positivo passa direto | Padrão nas camadas internas de quase todas as redes modernas. Rápida e eficaz. |
| Sigmoide | Esmaga qualquer número para o intervalo (0, 1) | Saída de classificação binária (probabilidade de "sim"). |
| Tanh | Esmaga para (−1, 1), centrada em zero | Comum em redes recorrentes (Capítulo 11). |
| Softmax | Converte um vetor em probabilidades que somam 1 | Saída de classificação com várias classes. |
4.4 O mesmo neurônio, agora em código
import torch
x = torch.tensor([1.0, 0.0, 1.0]) # sol, companhia, cansaço
w = torch.tensor([3.0, 2.0, -4.0]) # pesos
b = torch.tensor(-2.0) # viés
z = w @ x + b # soma ponderada: -3.0
saida = torch.relu(z) # ativação ReLU: 0.0
print(z.item(), saida.item()) # -3.0 0.0
# Em redes reais, um "Linear" empacota vários neurônios:
camada = torch.nn.Linear(in_features=3, out_features=1)
print(camada(x.unsqueeze(0))) # pesos aleatórios, ainda não treinados
import numpy as np
import tensorflow as tf
x = np.array([[1.0, 0.0, 1.0]]) # sol, companhia, cansaço
w = np.array([3.0, 2.0, -4.0])
b = -2.0
z = w @ x[0] + b # soma ponderada: -3.0
saida = tf.nn.relu(z) # ativação ReLU: 0.0
print(z, saida.numpy()) # -3.0 0.0
# Em redes reais, um "Dense" empacota vários neurônios:
camada = tf.keras.layers.Dense(units=1, activation="relu")
print(camada(x)) # pesos aleatórios, ainda não treinados
Pergunta clássica de entrevista júnior: "Por que redes neurais precisam de funções de ativação não lineares?" Resposta esperada: sem elas, qualquer pilha de camadas colapsa numa única transformação linear — a rede jamais aprenderia padrões complexos. Você acabou de dominar essa resposta.
Exercícios do capítulo
Ex 4.1 Com os pesos do exemplo, calcule a decisão para: sol ✘, companhia ✔, cansado ✘.
soma = (3×0) + (2×1) + (−4×0) + (−2) = 0. Com degrau em 0 (saída 1 se soma ≥ 0), o neurônio fica exatamente no limiar: sai de casa "por pouco". Note como o viés −2 exige pelo menos 2 pontos de estímulo para sair.
Ex 4.2 Aplique ReLU aos valores: −5, 0, 3.2, −0.1, 7.
0, 0, 3.2, 0, 7. ReLU zera negativos e mantém positivos — simples assim, e é a ativação mais usada do mundo.
Redes de várias camadas: empilhando neurônios
Do neurônio solitário ao MLP — a arquitetura que resolve problemas reais de negócio até hoje.
5.1 Camadas: entrada, ocultas e saída
Uma rede neural organiza neurônios em camadas (reveja o diagrama do início da apostila):
- Camada de entrada: recebe o vetor de features. Não calcula nada — só distribui os números.
- Camadas ocultas: onde a mágica acontece. Cada neurônio recebe todas as saídas da camada anterior. A primeira camada aprende padrões simples; as seguintes combinam esses padrões em conceitos cada vez mais abstratos.
- Camada de saída: produz a resposta — 1 neurônio para prever um número ou dizer sim/não; N neurônios (com softmax) para escolher entre N categorias.
Essa arquitetura se chama MLP (Multi-Layer Perceptron) ou rede densa/totalmente conectada. "Deep" learning significa apenas: MLP (ou variações) com muitas camadas ocultas.
Numa rede que reconhece rostos: as primeiras camadas detectam bordas e manchas de luz; as intermediárias combinam bordas em olhos, narizes e bocas; as finais combinam essas partes em "rosto de fulano". Ninguém programa isso — a hierarquia emerge do treinamento. Essa é a grande sacada do deep learning: a rede aprende as features sozinha.
5.2 Forward pass: o caminho de ida
O forward pass (passagem direta) é o fluxo do dado da entrada até a saída: multiplicar pela matriz de pesos da camada, somar o viés, aplicar a ativação — e repetir para a próxima camada.
camada 2: h₂ = ReLU( W₂·h₁ + b₂ )
saída: ŷ = softmax( W₃·h₂ + b₃ )
O acento em ŷ ("y chapéu") indica previsão — para distinguir da resposta correta y. Comparar ŷ com y é o assunto do próximo capítulo.
5.3 Sua primeira rede completa (só a arquitetura)
import torch.nn as nn
modelo = nn.Sequential(
nn.Linear(4, 16), # 4 features de entrada → 16 neurônios
nn.ReLU(),
nn.Linear(16, 16), # segunda camada oculta
nn.ReLU(),
nn.Linear(16, 3), # 3 classes na saída
)
# O softmax fica embutido na função de perda (CrossEntropyLoss).
print(modelo)
total = sum(p.numel() for p in modelo.parameters())
print(f"Parâmetros treináveis: {total}") # 403
import tensorflow as tf
from tensorflow.keras import layers
modelo = tf.keras.Sequential([
layers.Input(shape=(4,)), # 4 features de entrada
layers.Dense(16, activation="relu"), # 16 neurônios
layers.Dense(16, activation="relu"), # segunda camada oculta
layers.Dense(3, activation="softmax") # 3 classes na saída
])
modelo.summary() # mostra camadas e parâmetros: 403 no total
5.4 De onde vêm os 403 parâmetros?
Camada 2: (16 × 16) + 16 = 272
Saída: (16 × 3) + 3 = 51
Total: 80 + 272 + 51 = 403 "botões" ajustáveis
Quando você lê que o GPT-4 tem "trilhões de parâmetros", é exatamente isto em escala colossal: pesos e vieses. A conta é a mesma que você acabou de fazer.
MLPs não são "coisa de iniciante": são amplamente usados em produção para dados tabulares — churn, risco de crédito, previsão de demanda, precificação. São a espinha dorsal de sistemas de recomendação e aparecem em cases técnicos de processos seletivos de bancos, fintechs e varejo. Saber estimar o nº de parâmetros de cabeça (como acima) impressiona em entrevistas.
Exercícios do capítulo
Ex 5.1 Quantos parâmetros tem uma rede 10 → 32 → 1?
Camada 1: (10×32) + 32 = 352. Saída: (32×1) + 1 = 33. Total: 385.
Ex 5.2 Para prever o preço de um imóvel (um número contínuo), a saída deve ter quantos neurônios e qual ativação?
1 neurônio, sem ativação (ativação "linear"): o preço pode ser qualquer número, então não devemos esmagá-lo com sigmoide ou ReLU. Isso caracteriza um problema de regressão — conceito formalizado no próximo capítulo.
Como a rede aprende: perda, gradiente e backpropagation
O capítulo mais importante da apostila. Leia duas vezes se precisar — tudo depois dele fica fácil.
6.1 O ciclo de treinamento em 4 passos
Esse ciclo roda milhares de vezes. Cada volta completa pelo dataset inteiro é uma época (epoch). Vamos abrir cada passo.
6.2 Passo 2 — Função de perda: o placar do erro
A função de perda (loss function) resume em um único número o quão erradas estão as previsões da rede. Quanto menor, melhor. As duas mais usadas:
| Tarefa | Loss | Como funciona |
|---|---|---|
| Regressão (prever números: preço, temperatura) | MSE (erro quadrático médio) | Média de (previsto − real)². Elevar ao quadrado pune erros grandes com força desproporcional. |
| Classificação (prever categorias: gato/cão, spam/não) | Cross-entropy (entropia cruzada) | Pune a rede conforme a probabilidade que ela deu à resposta certa. Deu 99% para a certa? Loss quase zero. Deu 1%? Loss enorme. |
MSE = ( (10−12)² + (22−20)² ) / 2 = (4 + 4) / 2 = 4.0
6.3 Passo 3 — Backpropagation: distribuindo a culpa
Backpropagation (retropropagação) responde: "qual a parcela de culpa de cada um dos milhões de pesos no erro final?" Ele percorre a rede de trás para frente, camada por camada, aplicando a regra da cadeia do cálculo (a "culpa" se propaga multiplicando as influências ao longo do caminho). O resultado é o gradiente: a derivada da loss em relação a cada peso.
Pense numa fábrica em que o produto final saiu com defeito. O gerente investiga da última etapa para a primeira: "a embalagem contribuiu 5% para o defeito; a montagem, 60%; a matéria-prima, 35%". Backpropagation é essa auditoria de culpa — automática, exata e feita para milhões de "funcionários" (pesos) de uma só vez. Você nunca implementará isso à mão: PyTorch e TensorFlow o fazem automaticamente (recurso chamado autograd). Mas precisa saber explicá-lo.
6.4 Passo 4 — Descida do gradiente: o passo morro abaixo
Com a culpa (gradiente) de cada peso em mãos, a atualização é uma linha de matemática:
O learning rate (taxa de aprendizado, lr) é o hiperparâmetro mais importante do deep learning:
- lr muito alto (ex.: 1.0): passos gigantes — a rede "pula" o vale e o erro explode ou oscila.
- lr muito baixo (ex.: 0.0000001): passos minúsculos — o treino leva uma eternidade.
- Valores típicos: 0.001 a 0.0001. Começar com
1e-3e ajustar é prática padrão de mercado.
Na prática usamos mini-batches: em vez de calcular o gradiente com o dataset inteiro (lento) ou com 1 exemplo (instável), usamos lotes de 32–256 exemplos. Isso se chama SGD (descida do gradiente estocástica). Otimizadores modernos como o Adam (Capítulo 8) refinam esse passo automaticamente.
6.5 O ciclo completo em código
import torch, torch.nn as nn
# Problema-brinquedo: aprender y = 2x + 1 a partir de exemplos
X = torch.tensor([[1.],[2.],[3.],[4.]])
y = torch.tensor([[3.],[5.],[7.],[9.]])
modelo = nn.Linear(1, 1) # 1 peso + 1 viés
loss_fn = nn.MSELoss()
otimizador = torch.optim.SGD(modelo.parameters(), lr=0.01)
for epoca in range(300):
ŷ = modelo(X) # 1) forward pass
loss = loss_fn(ŷ, y) # 2) medir o erro
otimizador.zero_grad() # limpar gradientes antigos
loss.backward() # 3) backpropagation (autograd!)
otimizador.step() # 4) atualizar pesos
w, b = modelo.weight.item(), modelo.bias.item()
print(f"Aprendido: y = {w:.2f}x + {b:.2f}") # ≈ y = 2.00x + 1.00
import numpy as np, tensorflow as tf
# Problema-brinquedo: aprender y = 2x + 1 a partir de exemplos
X = np.array([[1.],[2.],[3.],[4.]])
y = np.array([[3.],[5.],[7.],[9.]])
modelo = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])
modelo.compile( # junta os passos 2, 3 e 4:
optimizer=tf.keras.optimizers.SGD(learning_rate=0.01),
loss="mse")
modelo.fit(X, y, epochs=300, verbose=0) # roda o ciclo completo
w, b = modelo.layers[0].get_weights()
print(f"Aprendido: y = {w[0][0]:.2f}x + {b[0]:.2f}") # ≈ y = 2.00x + 1.00
Repare na filosofia dos frameworks: PyTorch expõe o ciclo (você escreve o loop — ótimo para aprender e pesquisar); Keras o encapsula em compile() + fit() (ótimo para produtividade). Dominar os dois é entender que fazem a mesma coisa.
As três perguntas de entrevista mais frequentes sobre este capítulo: (1) "Explique backpropagation em alto nível" — auditoria de culpa, de trás para frente, via regra da cadeia; (2) "O que acontece se o learning rate for alto demais?" — a loss diverge/oscila; (3) "Diferença entre batch, mini-batch e época?" — agora você sabe as três.
Exercícios do capítulo
Ex 6.1 Um peso vale 0.8, seu gradiente é 0.5 e o lr é 0.1. Qual o novo valor do peso?
0.8 − 0.1 × 0.5 = 0.75. O gradiente positivo indicava que aumentar o peso pioraria a loss; o peso diminuiu.
Ex 6.2 Dataset com 10 000 exemplos, batch de 100. Quantas atualizações de pesos ocorrem em 5 épocas?
10 000 / 100 = 100 atualizações por época × 5 épocas = 500 atualizações.
Ex 6.3 No código acima, troque o lr para 1.0 e rode. O que acontece e por quê?
A loss explode para números gigantes (ou nan): passos grandes demais fazem os pesos "pularem" por cima do vale e se afastarem cada vez mais do mínimo. É o sintoma clássico de learning rate alto — memorize-o, pois você o verá na vida real.
Seu primeiro projeto real: reconhecendo dígitos escritos à mão
O "Olá, Mundo" do deep learning — MNIST — completo, comentado e pronto para o seu GitHub.
7.1 O problema
MNIST é um dataset com 70 000 imagens (28×28 pixels, tons de cinza) de dígitos 0–9 escritos à mão. Tarefa: dada a imagem, dizer o dígito. É simples o bastante para treinar em minutos sem GPU e rico o bastante para exercitar o fluxo profissional completo: carregar dados → preparar → treinar → avaliar → prever.
Cada imagem vira um vetor de 28×28 = 784 features (o brilho de cada pixel, normalizado de 0–255 para 0–1). A saída tem 10 neurônios com softmax — um por dígito.
7.2 O projeto completo
import torch, torch.nn as nn
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
# 1) DADOS: baixar, normalizar e criar loaders (mini-batches)
tfm = transforms.ToTensor() # pixels 0–255 → 0–1
treino = datasets.MNIST("dados", train=True, download=True, transform=tfm)
teste = datasets.MNIST("dados", train=False, download=True, transform=tfm)
dl_treino = DataLoader(treino, batch_size=64, shuffle=True)
dl_teste = DataLoader(teste, batch_size=256)
# 2) MODELO: 784 → 128 → 64 → 10
modelo = nn.Sequential(
nn.Flatten(), # 28x28 → vetor de 784
nn.Linear(784, 128), nn.ReLU(),
nn.Linear(128, 64), nn.ReLU(),
nn.Linear(64, 10), # 10 classes (softmax na loss)
)
loss_fn = nn.CrossEntropyLoss()
otim = torch.optim.Adam(modelo.parameters(), lr=1e-3)
# 3) TREINO
for epoca in range(5):
for X, y in dl_treino:
loss = loss_fn(modelo(X), y)
otim.zero_grad(); loss.backward(); otim.step()
print(f"Época {epoca+1} — loss: {loss.item():.4f}")
# 4) AVALIAÇÃO no conjunto de teste (nunca visto no treino!)
modelo.eval(); acertos = 0
with torch.no_grad():
for X, y in dl_teste:
pred = modelo(X).argmax(dim=1) # classe mais provável
acertos += (pred == y).sum().item()
print(f"Acurácia: {acertos/len(teste):.2%}") # ~97–98%
# 5) SALVAR o modelo treinado
torch.save(modelo.state_dict(), "mnist_mlp.pt")
import tensorflow as tf
from tensorflow.keras import layers
# 1) DADOS: baixar e normalizar
(X_tr, y_tr), (X_te, y_te) = tf.keras.datasets.mnist.load_data()
X_tr, X_te = X_tr / 255.0, X_te / 255.0 # pixels 0–255 → 0–1
# 2) MODELO: 784 → 128 → 64 → 10
modelo = tf.keras.Sequential([
layers.Flatten(input_shape=(28, 28)), # 28x28 → vetor de 784
layers.Dense(128, activation="relu"),
layers.Dense(64, activation="relu"),
layers.Dense(10, activation="softmax") # 10 classes
])
modelo.compile(optimizer=tf.keras.optimizers.Adam(1e-3),
loss="sparse_categorical_crossentropy",
metrics=["accuracy"])
# 3) TREINO (batch de 64, 5 épocas, 10% p/ validação)
modelo.fit(X_tr, y_tr, batch_size=64, epochs=5, validation_split=0.1)
# 4) AVALIAÇÃO no conjunto de teste (nunca visto no treino!)
loss, acc = modelo.evaluate(X_te, y_te)
print(f"Acurácia: {acc:.2%}") # ~97–98%
# 5) SALVAR o modelo treinado
modelo.save("mnist_mlp.keras")
7.3 Lendo os resultados como um profissional
- Loss caindo a cada época = a rede está aprendendo. Se estagnar cedo, o lr pode estar baixo ou o modelo, pequeno demais.
- Acurácia de teste ≈ acurácia de treino = o modelo generaliza. Se treino ≫ teste, há overfitting — assunto do próximo capítulo.
- 97% parece ótimo, mas contexto importa: num sistema bancário lendo cheques, 3% de erro é inaceitável. Definir a métrica-alvo junto ao negócio é habilidade sênior (Capítulo 9).
Suba este projeto no GitHub com um README.md contendo: descrição do problema, como rodar, acurácia obtida e 3 exemplos de erros do modelo (com as imagens). Depois repita com o dataset Fashion-MNIST (roupas em vez de dígitos — troca de 1 linha) e compare. Recrutadores valorizam mais a análise dos erros do que a acurácia em si.
Exercícios do capítulo
Ex 7.1 Por que dividimos os pixels por 255?
Para normalizar as entradas ao intervalo [0, 1]. Entradas em escalas grandes geram gradientes instáveis e treino lento. Normalizar entradas é regra profissional em praticamente todo projeto (mais no Capítulo 9).
Ex 7.2 Por que avaliar num conjunto de teste separado, e não nos próprios dados de treino?
Porque o modelo pode ter decorado o treino. O teste simula dados novos do mundo real — a única medida honesta de desempenho. Avaliar no treino é como corrigir a prova com o gabarito na mão do aluno.
Treinando redes que funcionam: overfitting, regularização e otimizadores
A diferença entre quem roda tutoriais e quem é contratado está neste capítulo.
8.1 Overfitting: o modelo que decora em vez de aprender
Overfitting (sobreajuste) é quando o modelo memoriza os dados de treino — inclusive seus ruídos e acasos — e vai mal em dados novos. É o problema nº 1 da prática de machine learning.
| Sintoma | Diagnóstico |
|---|---|
| Acurácia de treino 99%, de validação 78% | Overfitting — o modelo decorou. A distância treino↔validação é o termômetro. |
| Acurácia de treino 62%, de validação 61% | Underfitting — o modelo é simples demais ou treinou pouco. |
| Treino 94%, validação 92% | Saudável: aprende e generaliza. |
Um aluno que decora as respostas da lista de exercícios tira 10 na lista e 4 na prova (questões novas). Um aluno que entendeu os conceitos tira 9 nas duas. Overfitting é o primeiro aluno. Todo o arsenal deste capítulo existe para forçar a rede a ser o segundo.
8.2 O arsenal anti-overfitting
- Mais dados: o remédio mais eficaz. Difícil de decorar 1 milhão de exemplos.
- Dropout: durante o treino, desliga aleatoriamente uma fração dos neurônios (ex.: 30%) a cada passo. Impede que a rede dependa de neurônios específicos — como treinar um time revezando jogadores para ninguém ser insubstituível.
- Regularização L2 (weight decay): adiciona à loss uma penalidade pelo tamanho dos pesos, empurrando-os para valores pequenos — modelos "modestos" generalizam melhor.
- Early stopping: monitora a loss de validação e para o treino quando ela começa a subir (o exato momento em que a decoreba começa).
- Data augmentation: cria variações artificiais dos dados (girar/espelhar imagens, trocar sinônimos em textos), multiplicando o dataset de graça (Capítulo 10).
- Batch Normalization: normaliza as ativações entre camadas; estabiliza e acelera o treino, com leve efeito regularizador.
import torch.nn as nn, torch
modelo = nn.Sequential(
nn.Flatten(),
nn.Linear(784, 256),
nn.BatchNorm1d(256), # batch normalization
nn.ReLU(),
nn.Dropout(0.3), # desliga 30% dos neurônios no treino
nn.Linear(256, 128),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(128, 10),
)
# weight_decay = regularização L2 direto no otimizador
otim = torch.optim.Adam(modelo.parameters(), lr=1e-3, weight_decay=1e-4)
# Early stopping em PyTorch é manual: guarde a melhor val_loss
# e pare se não melhorar por N épocas ("paciência").
melhor, paciencia, contador = float("inf"), 3, 0
# dentro do loop de épocas:
# if val_loss < melhor: melhor = val_loss; contador = 0
# else: contador += 1
# if contador >= paciencia: break
import tensorflow as tf
from tensorflow.keras import layers, regularizers
modelo = tf.keras.Sequential([
layers.Flatten(input_shape=(28, 28)),
layers.Dense(256, kernel_regularizer=regularizers.l2(1e-4)),
layers.BatchNormalization(), # batch normalization
layers.Activation("relu"),
layers.Dropout(0.3), # desliga 30% dos neurônios no treino
layers.Dense(128, activation="relu"),
layers.Dropout(0.3),
layers.Dense(10, activation="softmax"),
])
# Early stopping é um callback pronto:
parada = tf.keras.callbacks.EarlyStopping(
monitor="val_loss", patience=3, # paciência de 3 épocas
restore_best_weights=True) # volta ao melhor ponto
# modelo.fit(..., validation_split=0.1, callbacks=[parada])
8.3 Otimizadores: SGD, Momentum e Adam
O otimizador decide como usar o gradiente para atualizar os pesos:
| Otimizador | Ideia | Quando usar |
|---|---|---|
| SGD | O passo puro: peso −= lr × gradiente | Base conceitual; com momentum, ainda comum em visão computacional. |
| SGD + Momentum | Acumula "velocidade" como uma bola morro abaixo — atravessa pequenos vales e ruídos | Treinos longos de CNNs; costuma generalizar muito bem. |
| Adam | Adapta o learning rate automaticamente para cada peso | O padrão do mercado. Comece sempre por ele (lr=1e-3). Variante AdamW é o padrão em Transformers. |
8.4 Hiperparâmetros: os botões que VOCÊ controla
Parâmetros (pesos/vieses) a rede aprende. Hiperparâmetros você escolhe: learning rate, nº de camadas e neurônios, batch size, dropout, nº de épocas. Ajustá-los é o dia a dia da profissão. Ordem prática de ajuste: learning rate → tamanho do modelo → regularização → batch size. Ferramentas como Optuna e Keras Tuner automatizam a busca.
Case técnico típico: entregam um dataset e pedem um modelo. O que diferencia candidatos não é a acurácia final, e sim o processo: separar validação corretamente, mostrar as curvas de treino×validação, diagnosticar overfitting e justificar cada hiperparâmetro. Documente esse raciocínio no notebook — é isso que o avaliador lê.
Exercícios do capítulo
Ex 8.1 Treino 99.5%, validação 71%. Cite três ações, em ordem de prioridade.
Overfitting severo: (1) conseguir mais dados ou usar augmentation; (2) adicionar dropout (0.3–0.5) e/ou weight decay; (3) reduzir o tamanho da rede e usar early stopping. Também vale verificar vazamento de dados (Capítulo 9).
Ex 8.2 Por que o dropout é desligado na hora de usar o modelo (inferência)?
O dropout existe só para dificultar a decoreba durante o treino. Na inferência queremos a rede completa e determinística. Os frameworks fazem isso automaticamente (model.eval() no PyTorch; no Keras, predict() já desativa).
Dados e métricas: onde os projetos reais são ganhos ou perdidos
"Garbage in, garbage out." 80% do trabalho real é aqui — e as entrevistas sabem disso.
9.1 A divisão sagrada: treino, validação e teste
- Treino: onde a rede aprende (ajusta pesos).
- Validação: onde você compara modelos e ajusta hiperparâmetros.
- Teste: tocado uma única vez, no fim, para a nota honesta. Se você o usa para decidir algo, ele virou validação e sua estimativa está contaminada.
É quando informação do teste "vaza" para o treino: normalizar usando estatísticas do dataset inteiro, duplicatas entre treino e teste, ou usar uma feature que só existe depois do evento previsto (ex.: prever cancelamento usando "data do cancelamento"). Resultado: métricas ótimas no papel, desastre em produção. É a falha mais eliminatória em cases técnicos — e uma das mais caras na indústria.
9.2 Preparação de dados essencial
- Normalização: colocar features em escalas comparáveis. Padrão: standardization (subtrair a média, dividir pelo desvio padrão) — calculadas só no treino e aplicadas aos demais conjuntos.
- Variáveis categóricas: cidade, plano, cor não são números. Use one-hot encoding (uma coluna 0/1 por categoria) ou embeddings (Capítulo 13) quando há muitas categorias.
- Valores faltantes: preencher com média/mediana, criar uma flag "estava faltando", ou remover — decisão que deve ser justificada, não automática.
- Classes desbalanceadas: 99% "não fraude" e 1% "fraude"? Um modelo que sempre diz "não" tem 99% de acurácia e é inútil. Soluções: reamostragem, pesos de classe na loss e, principalmente, métricas certas (abaixo).
9.3 Métricas além da acurácia
Para classificação, tudo parte da matriz de confusão (acertos e erros por tipo):
| Métrica | Pergunta que responde | Quando priorizar |
|---|---|---|
| Acurácia | Qual fração total acertei? | Classes equilibradas e erros de custo igual. |
| Precisão | Dos que marquei como positivos, quantos eram mesmo? | Falso positivo é caro (ex.: bloquear cliente honesto por "fraude"). |
| Recall | Dos positivos reais, quantos capturei? | Falso negativo é caro (ex.: deixar de detectar um câncer). |
| F1 | Equilíbrio entre precisão e recall | Classes desbalanceadas; comparação de modelos. |
| AUC-ROC | O modelo ordena bem positivos acima de negativos? | Padrão em crédito, risco e propensão. |
Para regressão: MAE (erro médio absoluto — interpretável: "erro médio de R$ 12 mil"), RMSE (pune erros grandes) e R² (fração da variação explicada).
Pergunta de entrevista quase garantida: "Seu dataset tem 1% de fraude. Por que acurácia é uma métrica ruim e qual você usaria?" Resposta: o modelo trivial já atinge 99%; use precisão/recall/F1 e AUC, e discuta o custo de negócio de cada tipo de erro. Falar de custo do erro sinaliza maturidade e distingue você de quem só decorou fórmulas.
Exercícios do capítulo
Ex 9.1 Detector de spam: 90 spams reais, detectou 60 deles e marcou 15 e-mails legítimos como spam. Calcule precisão e recall.
Precisão = 60 / (60 + 15) = 80%. Recall = 60 / 90 = 66,7%. O detector é confiável quando acusa, mas deixa passar 1/3 dos spams.
Ex 9.2 Um colega normalizou o dataset inteiro antes de separar treino/teste. Qual o problema?
Data leakage: a média e o desvio usados na normalização incluem informação do teste. O correto é calcular as estatísticas apenas no treino e aplicá-las aos outros conjuntos. O efeito pode parecer pequeno, mas o princípio é inegociável — e avaliadores procuram exatamente esse deslize.
CNNs: redes convolucionais e visão computacional
Como máquinas enxergam — e como usar redes pré-treinadas para resolver problemas com poucos dados.
10.1 Por que MLPs falham com imagens grandes
Uma foto de celular (1000×1000×3 cores) viraria um vetor de 3 milhões de entradas; a primeira camada densa teria bilhões de pesos. Pior: achatando a imagem, jogamos fora a informação espacial — o fato de pixels vizinhos formarem padrões. A CNN (rede neural convolucional) resolve os dois problemas com uma ideia elegante.
10.2 Convolução: um detector de padrões deslizante
Em vez de conectar cada neurônio a todos os pixels, a CNN usa filtros (kernels): matrizinhas de pesos, tipicamente 3×3, que deslizam pela imagem calculando, a cada posição, uma soma ponderada da vizinhança. O resultado é um mapa de features: um "mapa de calor" indicando onde aquele padrão aparece.
Um filtro é um carimbo detector: um aprende a acender em bordas verticais, outro em cantos, outro em manchas de certa cor. O ponto genial: os pesos do filtro são compartilhados em toda a imagem (um gato no canto é detectado pelo mesmo filtro que o detectaria no centro), reduzindo drasticamente os parâmetros. E, como sempre, os filtros não são desenhados à mão: a rede os aprende via backpropagation.
Componentes que completam a arquitetura:
- Pooling (ex.: MaxPool 2×2): encolhe o mapa mantendo o valor mais forte de cada região — resume e dá tolerância a pequenos deslocamentos.
- Empilhamento: convolução → ReLU → pooling, repetidos. Primeiras camadas: bordas; intermediárias: texturas e partes; finais: objetos. A hierarquia do Capítulo 5, agora visual.
- Cabeça densa: ao final, achata-se o mapa e usa-se um pequeno MLP para classificar.
10.3 Uma CNN completa para imagens
import torch.nn as nn
cnn = nn.Sequential(
# Bloco 1: 1 canal (cinza) → 32 filtros 3x3
nn.Conv2d(1, 32, kernel_size=3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2), # 28x28 → 14x14
# Bloco 2: 32 → 64 filtros
nn.Conv2d(32, 64, kernel_size=3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2), # 14x14 → 7x7
# Cabeça de classificação
nn.Flatten(), # 64 mapas de 7x7 → 3136
nn.Linear(64*7*7, 128), nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(128, 10),
)
# Treino: idêntico ao Capítulo 7 — só o modelo mudou.
# MNIST com esta CNN: ~99% de acurácia.
from tensorflow.keras import Sequential, layers
cnn = Sequential([
layers.Input(shape=(28, 28, 1)),
# Bloco 1: 32 filtros 3x3
layers.Conv2D(32, 3, padding="same", activation="relu"),
layers.MaxPooling2D(2), # 28x28 → 14x14
# Bloco 2: 64 filtros
layers.Conv2D(64, 3, padding="same", activation="relu"),
layers.MaxPooling2D(2), # 14x14 → 7x7
# Cabeça de classificação
layers.Flatten(), # 64 mapas de 7x7 → 3136
layers.Dense(128, activation="relu"),
layers.Dropout(0.3),
layers.Dense(10, activation="softmax"),
])
# Treino: idêntico ao Capítulo 7 — só o modelo mudou.
# MNIST com esta CNN: ~99% de acurácia.
10.4 Transfer learning: a técnica mais valiosa do capítulo
Empresas raramente treinam CNNs do zero. Usa-se uma rede pré-treinada em milhões de imagens (ResNet, EfficientNet, MobileNet), aproveitando seus detectores de padrões já aprendidos, e treina-se apenas uma nova cabeça para o seu problema. Com poucas centenas de imagens você atinge resultados que exigiriam milhões — e é assim que quase todo projeto real de visão começa.
import torch.nn as nn
from torchvision import models
# 1) Carrega ResNet-18 pré-treinada no ImageNet
modelo = models.resnet18(weights="IMAGENET1K_V1")
# 2) Congela todos os pesos (não serão treinados)
for p in modelo.parameters():
p.requires_grad = False
# 3) Substitui só a camada final: 2 classes (ex.: OK/defeito)
modelo.fc = nn.Linear(modelo.fc.in_features, 2)
# 4) Treina normalmente — só a nova camada aprende.
# Depois, opcional: descongelar as últimas camadas com lr
# bem baixo (fine-tuning) para ganhar mais alguns pontos.
import tensorflow as tf
from tensorflow.keras import layers
# 1) Carrega MobileNetV2 pré-treinada no ImageNet (sem o topo)
base = tf.keras.applications.MobileNetV2(
input_shape=(160, 160, 3), include_top=False,
weights="imagenet")
# 2) Congela a base (não será treinada)
base.trainable = False
# 3) Adiciona só a nova cabeça: 2 classes (ex.: OK/defeito)
modelo = tf.keras.Sequential([
base,
layers.GlobalAveragePooling2D(),
layers.Dropout(0.2),
layers.Dense(2, activation="softmax"),
])
# 4) Treina normalmente — só a nova cabeça aprende.
# Depois, opcional: base.trainable=True com lr bem baixo
# (fine-tuning) para ganhar mais alguns pontos.
Data augmentation completa a receita: rotações, espelhamentos, cortes e variações de brilho aplicados ao treino multiplicam seu dataset e reduzem overfitting quase de graça.
Visão computacional emprega em: indústria (inspeção de defeitos), agro (pragas e contagem por drone), saúde (laudos por imagem), varejo (prateleiras e checkout) e segurança. O projeto de portfólio que mais converte entrevistas: classificador com transfer learning num dataset do seu domínio de interesse — ex.: 500 fotos de peças boas/defeituosas — com métricas honestas e análise de erros. Termos de vaga: CNN, ResNet, transfer learning, data augmentation, OpenCV, YOLO (detecção de objetos).
Exercícios do capítulo
Ex 10.1 Por que um filtro 3×3 aplicado a uma imagem inteira usa tão menos parâmetros que uma camada densa?
O filtro tem apenas 9 pesos (+1 viés) e é reutilizado em todas as posições da imagem (compartilhamento de pesos). Uma camada densa teria um peso para cada par pixel-neurônio — milhões. Menos parâmetros = menos overfitting e mais velocidade.
Ex 10.2 Você tem só 300 imagens rotuladas. Treinar uma CNN do zero ou usar transfer learning? Por quê?
Transfer learning, sem dúvida: 300 imagens são insuficientes para aprender bons detectores do zero (overfitting garantido). A base pré-treinada já traz detectores universais de bordas, texturas e formas; você treina apenas a cabeça. Complementar com augmentation.
RNNs e LSTMs: redes com memória para sequências
Texto, séries temporais e áudio têm ordem — e a ordem carrega significado.
11.1 O problema das sequências
"O filme não foi bom" e "O filme foi bom, não?" usam as mesmas palavras com sentidos opostos: a ordem importa. MLPs e CNNs recebem entradas de tamanho fixo e sem noção de "antes/depois". Sequências (frases, vendas diárias, batimentos cardíacos) pedem uma arquitetura que leia um passo por vez lembrando do que veio antes.
11.2 RNN: a rede que lê como você
A RNN (rede neural recorrente) processa a sequência elemento a elemento, mantendo um estado oculto — um vetor-resumo de tudo que já foi visto, atualizado a cada passo:
É o mesmo neurônio de sempre, com um ingrediente extra: parte da entrada é a própria memória da rede. O problema: em sequências longas, os gradientes do backpropagation atravessam dezenas de multiplicações e desvanecem (viram ~0) — a rede "esquece" o começo da frase. É o famoso vanishing gradient.
11.3 LSTM: memória com portões
A LSTM (Long Short-Term Memory) resolve o esquecimento adicionando uma esteira de memória de longo prazo controlada por três portões aprendidos (pequenas sigmoides que decidem quanto passa, de 0 a 1):
- Portão de esquecimento: o que apagar da memória ("mudamos de assunto, descarte o sujeito anterior").
- Portão de entrada: o que gravar de novo ("o sujeito agora é 'Maria', guarde").
- Portão de saída: o que da memória usar na resposta deste passo.
A GRU é uma prima simplificada (dois portões), mais leve e frequentemente equivalente. Para séries temporais de negócio, LSTM/GRU continuam escolhas sólidas e baratas.
import torch.nn as nn
class Sentimento(nn.Module):
def __init__(self, vocab=10000, dim=64):
super().__init__()
# cada palavra (id) vira um vetor denso aprendido
self.emb = nn.Embedding(vocab, dim)
self.lstm = nn.LSTM(dim, 128, batch_first=True)
self.fc = nn.Linear(128, 1) # positivo/negativo
def forward(self, x): # x: (batch, tamanho_frase)
e = self.emb(x) # (batch, frase, 64)
_, (h, _) = self.lstm(e) # h: resumo final da frase
return self.fc(h[-1]) # logit do sentimento
# Loss: nn.BCEWithLogitsLoss() — classificação binária
from tensorflow.keras import Sequential, layers
modelo = Sequential([
# cada palavra (id) vira um vetor denso aprendido
layers.Embedding(input_dim=10000, output_dim=64),
layers.LSTM(128), # resumo final da frase
layers.Dense(1, activation="sigmoid") # positivo/negativo
])
modelo.compile(optimizer="adam",
loss="binary_crossentropy",
metrics=["accuracy"])
# Dataset clássico p/ praticar: IMDB reviews
# tf.keras.datasets.imdb.load_data(num_words=10000)
Em NLP, Transformers (próximo capítulo) tomaram o trono das RNNs. Mas LSTMs/GRUs seguem empregadas em séries temporais: previsão de demanda e estoque (varejo), consumo de energia, sinais de sensores/IoT e finanças — onde são rápidas, baratas e suficientes. Entrevistas ainda cobram o conceito de vanishing gradient e o papel dos portões: é teste de profundidade teórica.
Exercícios do capítulo
Ex 11.1 Por que a ordem das camadas Embedding → LSTM → Dense faz sentido?
Embedding traduz ids de palavras em vetores com significado; a LSTM lê a sequência desses vetores acumulando contexto; a Dense converte o resumo final em decisão. É o pipeline padrão de classificação de texto pré-Transformers.
Ex 11.2 O que é vanishing gradient e como a LSTM o mitiga?
Na RNN simples, o gradiente atravessa muitas multiplicações ao voltar no tempo e tende a zero — passos antigos param de aprender. A LSTM cria um "corredor" de memória cujo fluxo é regulado por portões aditivos, permitindo que a informação (e o gradiente) atravesse longas distâncias quase intacta.
Atenção e Transformers: a arquitetura que mudou tudo
GPT, Claude, Gemini, Llama, BERT — todos são variações do que você aprenderá aqui.
12.1 A limitação que restava
LSTMs leem um passo por vez: lento (não paraleliza em GPU) e, mesmo com portões, o resumo de um texto longo num único vetor perde detalhes. Em 2017, o artigo "Attention Is All You Need" propôs abolir a recorrência: processar todas as palavras ao mesmo tempo, deixando que cada uma "olhe" diretamente para todas as outras. Nascia o Transformer.
12.2 Self-attention: cada palavra pergunta às outras
Para cada palavra, a rede aprende a gerar três vetores:
- Query (Q) — "o que estou procurando?"
- Key (K) — "o que eu ofereço como referência?"
- Value (V) — "que informação eu carrego?"
A palavra compara sua Query com a Key de todas as outras (produto escalar = afinidade), transforma as afinidades em pesos com softmax, e monta sua nova representação como média ponderada dos Values — dando mais peso a quem é mais relevante para ela.
Na frase "A âncora do navio caiu porque ela era pesada", a palavra "ela" lança sua Query e recebe alta afinidade da Key de "âncora": sua representação passa a incorporar "âncora". A ambiguidade se resolve por atenção, em um único passo paralelo — sem ler palavra por palavra. Cada camada tem várias "cabeças" de atenção (multi-head), cada uma especializada num tipo de relação (sintaxe, correferência, posição...).
12.3 A arquitetura completa
Um bloco Transformer = multi-head attention → soma com a entrada (conexão residual) e normalização → MLP (o mesmo do Capítulo 5!) → residual + normalização. Empilhe dezenas desses blocos e adicione:
- Tokenização: o texto é picado em tokens (pedaços de palavras) convertidos em ids.
- Embeddings + codificação posicional: como tudo é processado em paralelo, injeta-se um vetor que informa a posição de cada token — senão a frase viraria um saco de palavras.
Duas famílias dominam:
| Família | Como funciona | Exemplos e usos |
|---|---|---|
| Encoders (BERT) | Leem o texto inteiro bidirecionalmente e produzem representações ricas | Classificação, busca semântica, extração de entidades |
| Decoders (GPT, Claude, Llama) | Preveem o próximo token olhando só para os anteriores; gerar texto = prever em cadeia | Chatbots, geração e resumo de texto, copilotos de código |
Um LLM é "apenas" um decoder Transformer gigante treinado em trilhões de tokens para prever o próximo token — e depois refinado para seguir instruções (Capítulo 15). Toda a matemática envolvida você já viu: multiplicação de matrizes, softmax, MLPs, backpropagation.
12.4 Usando um Transformer em 6 linhas
# pip install transformers — biblioteca Hugging Face (framework-agnóstica)
from transformers import pipeline
clf = pipeline("sentiment-analysis",
model="nlptown/bert-base-multilingual-uncased-sentiment")
print(clf("O produto chegou rápido e a qualidade é excelente!"))
# [{'label': '5 stars', 'score': 0.81}]
"Transformers" e "LLMs" são hoje as palavras mais quentes das vagas de IA. O que entrevistas de fato cobram deste capítulo: explicar self-attention com um exemplo (use o da âncora), a diferença encoder × decoder, o que é tokenização e por que existe codificação posicional. Com essas quatro respostas você conversa de igual para igual em 90% dos processos que mencionam IA generativa.
Exercícios do capítulo
Ex 12.1 Por que o Transformer treina muito mais rápido que uma LSTM no mesmo hardware?
A LSTM é sequencial: o passo t depende do t−1, impossibilitando paralelizar dentro da frase. No Transformer, a atenção processa todos os tokens simultaneamente — multiplicações de matrizes gigantes, exatamente o que GPUs fazem de melhor.
Ex 12.2 Para um sistema de busca semântica em documentos internos da empresa, você usaria um modelo tipo BERT ou tipo GPT? Por quê?
Tipo BERT (encoder): a tarefa é gerar boas representações para comparar pergunta e documentos, não gerar texto. Na prática usam-se encoders de sentença (sentence-transformers) para criar embeddings e compará-los — a base do RAG que você verá no Capítulo 15.
NLP moderno na prática: embeddings e Hugging Face
O fluxo de trabalho que a indústria realmente usa para texto — e que cabe no seu portfólio.
13.1 Embeddings: o mapa do significado
Um embedding é a representação de algo (palavra, frase, produto, usuário) como um vetor denso em que proximidade geométrica = semelhança de significado. "Rei" fica perto de "rainha"; "ótimo atendimento" fica perto de "equipe muito prestativa" mesmo sem palavras em comum. É o conceito que conecta tudo: a camada Embedding do Capítulo 11, as representações internas dos Transformers e os sistemas de busca semântica/RAG do Capítulo 15.
# pip install sentence-transformers
from sentence_transformers import SentenceTransformer, util
modelo = SentenceTransformer("paraphrase-multilingual-MiniLM-L12-v2")
frases = ["Como cancelo minha assinatura?",
"Quero encerrar meu plano",
"Qual o horário de funcionamento?"]
emb = modelo.encode(frases) # 3 vetores de 384 dims
print(util.cos_sim(emb[0], emb[1])) # ~0.85 → mesmo assunto
print(util.cos_sim(emb[0], emb[2])) # ~0.15 → assuntos diferentes
A similaridade de cosseno mede o ângulo entre vetores (1 = mesmíssima direção). Com isso você constrói buscadores semânticos, deduplicação, clustering de tickets e recomendação — projetos de altíssimo valor com pouquíssimo código.
13.2 Fine-tuning de um Transformer para o seu problema
O transfer learning do Capítulo 10, agora com texto: parte-se de um modelo pré-treinado (ex.: BERTimbau, o BERT em português) e ajusta-se ao seu dataset rotulado. A biblioteca Hugging Face Transformers integra-se aos dois frameworks:
from transformers import (AutoTokenizer,
AutoModelForSequenceClassification,
TrainingArguments, Trainer)
nome = "neuralmind/bert-base-portuguese-cased"
tok = AutoTokenizer.from_pretrained(nome)
modelo = AutoModelForSequenceClassification.from_pretrained(
nome, num_labels=2) # ex.: reclamação × elogio
# dataset: textos tokenizados + rótulos (via lib `datasets`)
args = TrainingArguments(
output_dir="saida", num_train_epochs=3,
per_device_train_batch_size=16,
eval_strategy="epoch")
treinador = Trainer(model=modelo, args=args,
train_dataset=ds_treino,
eval_dataset=ds_val)
treinador.train() # fine-tuning completo
from transformers import (AutoTokenizer,
TFAutoModelForSequenceClassification)
import tensorflow as tf
nome = "neuralmind/bert-base-portuguese-cased"
tok = AutoTokenizer.from_pretrained(nome)
modelo = TFAutoModelForSequenceClassification.from_pretrained(
nome, num_labels=2) # ex.: reclamação × elogio
# textos → tensores (padding/truncation cuidam do tamanho)
X = tok(textos, padding=True, truncation=True,
return_tensors="tf")
modelo.compile(optimizer=tf.keras.optimizers.Adam(2e-5),
metrics=["accuracy"]) # loss já embutida
modelo.fit(dict(X), rotulos,
epochs=3, batch_size=16) # fine-tuning completo
Detalhe profissional: em fine-tuning de Transformers usa-se learning rate minúsculo (2e-5 em vez de 1e-3) — os pesos pré-treinados são valiosos e não devem ser destruídos por passos grandes.
Casos reais que empresas brasileiras contratam para resolver: classificar tickets do SAC, detectar toxicidade, rotear e-mails, extrair dados de contratos, medir sentimento de reviews. O combo de portfólio imbatível: fine-tuning do BERTimbau no dataset B2W-Reviews (reviews em português, público) + um buscador semântico com sentence-transformers. Termos de vaga: Hugging Face, BERT, embeddings, NER, fine-tuning, RAG.
Exercícios do capítulo
Ex 13.1 "Notebook barato bom para estudar" e "laptop econômico para faculdade" não compartilham palavras. Como um buscador os conecta?
Via embeddings: ambos são mapeados para vetores próximos no espaço semântico (o modelo aprendeu que "notebook/laptop" e "estudar/faculdade" ocorrem em contextos similares). A busca compara vetores por cosseno em vez de casar palavras.
Ex 13.2 Por que fine-tuning com lr=1e-3 costuma destruir um modelo pré-treinado?
Passos grandes sobrescrevem rapidamente os pesos cuidadosamente aprendidos no pré-treino ("esquecimento catastrófico"). Com lr ~2e-5, os pesos se ajustam delicadamente à nova tarefa preservando o conhecimento geral.
Modelos generativos: autoencoders, GANs e difusão
Redes que não classificam o mundo — elas o criam.
14.1 Autoencoders: aprender comprimindo
Um autoencoder é treinado para uma tarefa aparentemente boba: reconstruir a própria entrada. O truque está no meio: um gargalo (bottleneck) força a rede a comprimir a entrada num vetor pequeno — o espaço latente — e depois reconstruí-la.
Para reconstruir bem com tão pouco espaço, o encoder é obrigado a aprender a essência dos dados. Aplicações diretas de mercado:
- Detecção de anomalias: treine só com dados normais; um dado anômalo (fraude, defeito, falha de sensor) será mal reconstruído — erro de reconstrução alto = alarme. Muito usado em bancos e indústria.
- Redução de dimensionalidade e denoising (limpar ruído de imagens/sinais).
O VAE (autoencoder variacional) organiza o espaço latente como distribuições de probabilidade contínuas, permitindo amostrar pontos e decodificá-los: nasce a geração de dados novos.
14.2 GANs: o falsificador e o perito
Uma GAN (rede adversária generativa) coloca duas redes para competir:
- O Gerador ("falsificador") transforma ruído aleatório em dados falsos (ex.: rostos).
- O Discriminador ("perito") tenta distinguir dados reais de falsos.
O gerador é treinado para enganar o discriminador; o discriminador, para não ser enganado. Nesse cabo de guerra, o falsificador fica tão bom que suas criações se tornam indistinguíveis das reais. GANs dominaram a geração de imagens por anos (deepfakes, super-resolução, dados sintéticos) — e são notoriamente instáveis de treinar (colapso de modo, equilíbrio delicado), o que caiu em muitas entrevistas.
14.3 Modelos de difusão: o estado da arte em imagens
Stable Diffusion, DALL·E, Midjourney e afins usam difusão: no treino, adiciona-se ruído progressivo a imagens reais até virar estática pura, e a rede aprende a reverter cada passinho de ruído. Na geração, parte-se de ruído puro e remove-se ruído iterativamente, guiado por um texto (via embeddings — Capítulo 13!), até emergir uma imagem nova. Mais estáveis que GANs e com qualidade superior, são o padrão atual.
Os três paradigmas em uma linha cada: o autoencoder aprende a essência comprimindo; a GAN aprende gerando num duelo; a difusão aprende a desfazer o caos passo a passo. E um LLM? É um modelo generativo de texto: gera o próximo token — parente direto de tudo isso.
Aplicações que pagam salário: detecção de anomalias com autoencoders (fraude, manutenção preditiva — subestimada e muito contratada), dados sintéticos para balancear classes raras e proteger privacidade, e IA generativa aplicada (marketing, design, jogos). Projeto de portfólio expert: autoencoder para detectar transações anômalas no dataset público Credit Card Fraud, comparando com métodos clássicos.
Exercícios do capítulo
Ex 14.1 Por que o autoencoder de anomalias é treinado APENAS com dados normais?
Para que ele só aprenda a comprimir/reconstruir o padrão normal. Uma anomalia foge desse padrão, o gargalo não a representa bem e a reconstrução sai ruim — o erro alto é justamente o sinal de detecção. Se treinasse com anomalias, aprenderia a reconstruí-las também e o alarme sumiria.
Ex 14.2 Na GAN, o que significa o discriminador atingir 50% de acerto?
Que ele está chutando: não distingue mais real de falso. É o equilíbrio teórico ideal — o gerador venceu, produzindo amostras indistinguíveis das reais.
LLMs na prática: prompting, RAG, LoRA e RLHF
A camada de habilidades mais demandada de 2024 em diante — construída sobre tudo que você já sabe.
15.1 Como nasce um assistente como o ChatGPT ou o Claude
- Pré-treino: um decoder Transformer gigante (Cap. 12) aprende a prever o próximo token em trilhões de tokens da internet. Resultado: um "completador de texto" enciclopédico, mas sem noção de conversa.
- Fine-tuning de instruções (SFT): treina-se com milhares de exemplos de (instrução → boa resposta). O modelo aprende o formato "assistente".
- RLHF (aprendizado por reforço com feedback humano): humanos comparam pares de respostas ("A é melhor que B"); treina-se um modelo de recompensa que imita essas preferências; o LLM é então otimizado para maximizar essa recompensa. É o que torna respostas úteis, seguras e no tom certo. (Variação popular: DPO, que simplifica o processo.)
15.2 Prompt engineering: a habilidade barata que rende caro
- Seja específico: papel, tarefa, formato, restrições. "Você é analista de crédito. Resuma o texto em 3 bullets, tom formal, máx. 20 palavras cada."
- Few-shot: dê 2–3 exemplos de entrada→saída; o modelo imita o padrão.
- Chain-of-thought: peça o raciocínio passo a passo antes da resposta final — melhora tarefas de lógica e cálculo.
- Saída estruturada: exija JSON com esquema definido quando o consumidor for outro sistema.
15.3 RAG: o LLM com acesso aos SEUS dados
LLMs não conhecem os documentos internos da sua empresa e podem alucinar (inventar fatos com confiança). O RAG (Retrieval-Augmented Generation) resolve os dois problemas combinando busca semântica (Cap. 13) com geração:
# Esqueleto de RAG (conceitual, ~mercado usa LangChain/LlamaIndex)
docs = dividir_em_pedacos(pdfs, tamanho=500) # chunking
vetores = modelo_embedding.encode(docs) # Cap. 13
banco.indexar(vetores, docs) # FAISS, Chroma, pgvector...
pergunta = "Qual o prazo de reembolso da política?"
top3 = banco.buscar(modelo_embedding.encode(pergunta), k=3)
prompt = f"""Responda APENAS com base no contexto.
Se não estiver no contexto, diga que não sabe.
Contexto: {top3}
Pergunta: {pergunta}"""
resposta = llm(prompt) # resposta com fonte
RAG é hoje o projeto de IA generativa mais contratado em empresas: chatbots sobre bases de conhecimento internas, suporte, jurídico, RH.
15.4 Fine-tuning eficiente: LoRA e quantização
Ajustar todos os bilhões de pesos de um LLM é caro. LoRA (Low-Rank Adaptation) congela o modelo e treina apenas pequenas matrizes adicionais "acopladas" às camadas de atenção — tipicamente <1% dos parâmetros, com resultado próximo ao fine-tuning completo. Combinado com quantização (representar pesos com 4–8 bits em vez de 16–32, encolhendo memória), o QLoRA permite ajustar modelos de 7–13B numa única GPU — inclusive no Colab. Regra de decisão profissional: prompting → RAG → fine-tuning, nessa ordem; só avance quando o anterior for insuficiente (conhecimento novo pede RAG; comportamento/estilo consistente pede fine-tuning).
Cargo em explosão: Engenheiro(a) de IA / LLM Engineer — constrói aplicações sobre APIs de LLMs (OpenAI, Anthropic, modelos abertos). Stack pedida: Python, APIs de LLM, LangChain/LlamaIndex, bancos vetoriais, RAG, avaliação de LLMs, LoRA. Portfólio matador: um RAG completo sobre documentos públicos (ex.: editais ou legislação), com interface simples (Streamlit) e uma seção de avaliação mostrando taxa de alucinação antes/depois. Poucas pessoas fazem a parte da avaliação — seja quem faz.
Exercícios do capítulo
Ex 15.1 O chatbot da empresa precisa responder sobre o manual interno de 800 páginas, sempre atualizado. Prompting, RAG ou fine-tuning?
RAG: o conhecimento é volumoso, específico e muda com frequência — basta re-indexar os documentos, sem retreinar nada. Fine-tuning "grava" conhecimento de forma estática e cara; prompting puro não comporta 800 páginas de contexto com confiabilidade.
Ex 15.2 Explique alucinação e cite duas mitigações.
Alucinação é o LLM gerar informação falsa com aparência de certeza — consequência natural de um modelo treinado para prever texto plausível, não verdadeiro. Mitigações: RAG com instrução de responder só com base no contexto (e citar fontes); pedir que admita não saber; validação estruturada da saída; e avaliação sistemática com conjuntos de teste.
MLOps: da pesquisa à produção
Modelo no notebook não gera valor. A habilidade mais escassa (e mais bem paga) é colocá-lo no ar — e mantê-lo vivo.
16.1 O ciclo de vida real de um modelo
MLOps é a disciplina que faz esse ciclo girar de forma confiável e repetível — o DevOps do machine learning.
16.2 Servindo o modelo como API
O padrão da indústria em Python é FastAPI: o modelo salvo é carregado uma vez e exposto num endpoint HTTP que qualquer sistema consome.
# pip install fastapi uvicorn — api.py
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
modelo = carregar_modelo("mnist_mlp") # .pt ou .keras (Cap. 7)
class Entrada(BaseModel):
pixels: list[float] # 784 valores 0–1
@app.post("/prever")
def prever(dado: Entrada):
prob = modelo.prever(dado.pixels)
return {"digito": int(prob.argmax()),
"confianca": float(prob.max())}
# uvicorn api:app → POST /prever → {"digito": 7, "confianca": 0.98}
Complete o pacote profissional com: Docker (empacota código+dependências para rodar igual em qualquer servidor), Git (versionamento — inegociável) e nuvem (AWS/GCP/Azure — endpoints gerenciados como SageMaker/Vertex AI).
16.3 Rastreando experimentos e versões
Depois de 50 treinos, qual combinação deu o melhor F1? Ferramentas como MLflow e Weights & Biases registram automaticamente hiperparâmetros, métricas e artefatos de cada execução, e versionam modelos ("model registry"). Em entrevistas de ML Engineer, citar rastreamento de experimentos com naturalidade sinaliza experiência real.
16.4 Monitoramento e drift: o modelo apodrece
O mundo muda; o modelo, não. Data drift: a distribuição das entradas muda (novo perfil de clientes). Concept drift: a relação entrada→saída muda (comportamento de fraude evolui para burlar o modelo). Por isso produção exige monitorar a distribuição das features e das previsões, alarmar em desvios e retreinar periodicamente. A pergunta de entrevista sênior favorita: "seu modelo caiu de desempenho em produção sem ninguém mexer em nada — o que aconteceu?" Agora você sabe: drift.
16.5 Otimização para inferência
- Quantização: pesos em 8/4 bits → modelo 2–4× menor e mais rápido, com perda mínima.
- ONNX: formato aberto para exportar modelos de qualquer framework e servir com runtimes otimizados.
- Destilação: treinar um modelo pequeno ("aluno") para imitar um grande ("professor") — qualidade próxima, custo muito menor.
ML Engineer (foco em produção) costuma pagar mais que Cientista de Dados exatamente porque une modelagem + engenharia — e é raro. Checklist de vaga: Python, Docker, Git, FastAPI, nuvem (AWS/GCP), CI/CD, MLflow, monitoramento. Upgrade de portfólio que muda seu patamar: pegue QUALQUER projeto desta apostila e publique-o como API dockerizada com README de arquitetura. 90% dos candidatos param no notebook; você não.
Exercícios do capítulo
Ex 16.1 Modelo de aprovação de crédito treinado em 2023 começou a errar mais em 2026. Dê duas causas prováveis e a resposta operacional.
Data drift (perfil econômico/clientes mudou — inflação, renda, novos produtos) e concept drift (a relação entre features e inadimplência mudou). Resposta: monitoramento contínuo de distribuições e métricas com rótulos atrasados, alarmes de desvio e pipeline de retreino periódico com dados recentes.
Ex 16.2 Por que empacotar o modelo em Docker se ele já roda na sua máquina?
"Funciona na minha máquina" não é garantia: versões de Python/bibliotecas/SO variam entre ambientes. O contêiner congela o ambiente inteiro, garantindo execução idêntica no servidor, na nuvem e na máquina do colega — pré-requisito de qualquer deploy sério.
Carreiras, portfólio e entrevistas: convertendo estudo em contratação
O capítulo que transforma os 16 anteriores em salário.
17.1 O mapa das carreiras
| Cargo | O que faz no dia a dia | Peso desta apostila |
|---|---|---|
| Analista de Dados | SQL, dashboards, análises descritivas; porta de entrada comum | Caps. 2–3, 9 · ML é diferencial |
| Cientista de Dados | Modela problemas de negócio: churn, crédito, demanda; experimenta e comunica | Caps. 1–9 são o núcleo; 10–13 diferenciam |
| Engenheiro(a) de ML | Leva modelos à produção: APIs, pipelines, monitoramento, escala | Caps. 6–10 + 16 é o coração |
| Engenheiro(a) de IA / LLM | Aplicações com LLMs: RAG, agentes, avaliação, integração | Caps. 12–13 + 15 + 16 |
| Pesquisador(a) de ML | Cria arquiteturas e métodos novos; papers | Tudo + mestrado/doutorado em geral |
Faixas salariais variam muito por região, senioridade e empresa; em geral, no Brasil, a progressão júnior → pleno → sênior nessas trilhas costuma ir de patamares próximos ao de dev júnior até valores bem acima da média de TI, com ML/IA Engineer entre os mais valorizados. Vagas remotas para o exterior multiplicam esses valores — e exigem inglês.
17.2 O portfólio que entrevista por você
Regra de ouro: 3 projetos profundos > 15 tutoriais copiados. A combinação ideal ao fim desta apostila:
- Dados tabulares + negócio (Caps. 5–9): previsão de churn ou crédito em dataset público, com EDA, métricas justificadas pelo custo do erro e comparação com baseline simples.
- Deep learning aplicado (Cap. 10 ou 13): transfer learning em imagens do seu domínio de interesse, ou fine-tuning de BERT em português — com análise de erros.
- IA generativa em produção (Caps. 15–16): RAG com interface, dockerizado, com seção de avaliação. É o que mais chama atenção hoje.
Cada projeto no GitHub precisa de: README com problema→abordagem→resultados (com números), instruções de reprodução, código organizado (não um notebook monolítico) e — o toque raro — um parágrafo de limitações e próximos passos. LinkedIn: publique um post curto por projeto explicando a decisão mais difícil que você tomou nele.
17.3 Como as entrevistas funcionam (e como passar)
- Triagem técnica: Python/SQL básicos + conceitos (overfitting, métricas, train/test). Coberto pelos Caps. 3, 8 e 9.
- Case técnico: dataset + problema, para resolver em dias ou ao vivo. Avaliam o processo: validação correta, ausência de leakage, baseline antes de rede neural, comunicação. Releia o Cap. 9 na véspera.
- Entrevista de ML: as perguntas das caixas laranjas desta apostila — literalmente. Backprop, learning rate, ativação, atenção, drift, RAG vs fine-tuning.
- Comportamental: prepare 3 histórias no formato situação→ação→resultado (com número). Projetos do portfólio contam como experiência se você os narrar como projetos, com decisões e trade-offs.
(1) Ir direto para rede neural sem baseline simples — sinaliza imaturidade; comece com regressão logística e mostre o ganho da rede. (2) Data leakage no case — eliminatório. (3) Não saber explicar o próprio projeto do portfólio em profundidade — decoreba detectada, entrevista encerrada.
Não espere "se sentir pronto" — aplique quando tiver 2 projetos sólidos. Personalize as 3 primeiras linhas do currículo com as palavras-chave da vaga (os filtros automáticos são literais: se a vaga diz "TensorFlow", escreva TensorFlow). Vagas de Analista de Dados e estágios em dados são portas de entrada legítimas para quem vem de outra área: dentro da empresa, migrar para ciência de dados/ML é caminho comum e comprovado.
Roteiro de estudos de 6 meses
Um plano realista para quem estuda ~10 h/semana, do zero à primeira candidatura competitiva.
| Mês | Foco | Capítulos | Entregável do mês |
|---|---|---|---|
| 1 | Python + NumPy + pandas; matemática intuitiva | 1–3 | Conta no GitHub com 4+ notebooks de exercícios; análise exploratória de um CSV real |
| 2 | Neurônio, MLP, treinamento; primeiro modelo | 4–7 | MNIST e Fashion-MNIST no GitHub com README e análise de erros |
| 3 | Regularização, dados e métricas; ML clássico (scikit-learn) como base | 8–9 | Projeto 1 do portfólio: churn/crédito com baseline vs rede, métricas de negócio |
| 4 | CNNs e transfer learning OU NLP com Hugging Face (escolha seu foco) | 10–13 | Projeto 2: transfer learning no seu domínio, ou fine-tuning de BERT em PT |
| 5 | LLMs, RAG e deploy | 14–16 | Projeto 3: RAG com interface + API dockerizada de um projeto anterior |
| 6 | Polimento e mercado | 17 | READMEs revisados, LinkedIn atualizado, currículo com palavras-chave, 20+ candidaturas e simulações de entrevista |
Hábitos que sustentam o plano: code diariamente nem que sejam 30 min; explique cada conceito em voz alta como se ensinasse (técnica Feynman — as caixas de intuição desta apostila são seus roteiros); participe de 1 competição iniciante do Kaggle no mês 3–4; e releia os códigos da apostila no outro framework no mês 5.
Recursos complementares gratuitos: curso "Machine Learning" e especialização "Deep Learning" de Andrew Ng (Coursera, auditáveis), fast.ai (prático, top-down), documentação e cursos da Hugging Face, "Neural Networks: Zero to Hero" de Andrej Karpathy (YouTube) e o livro aberto "Dive into Deep Learning" (d2l.ai). Em português: material do curso de ML da USP/UFMG no YouTube e a comunidade Data Hackers.
Glossário essencial (o vocabulário das vagas e entrevistas)
| Termo | Definição em uma linha |
|---|---|
| Feature | Cada característica numérica de entrada do modelo. |
| Peso / viés | Os "botões" ajustáveis da rede; aprendidos no treino. |
| Ativação | Função não linear (ReLU, sigmoide...) que dá poder expressivo à rede. |
| Loss | Número único que mede o erro; treinar = minimizá-lo. |
| Gradiente | Direção e intensidade de como cada peso afeta a loss. |
| Backpropagation | Algoritmo que calcula os gradientes de trás para frente. |
| Learning rate | Tamanho do passo na atualização dos pesos. |
| Época / batch | Uma passada completa pelo dataset / o lote de exemplos por atualização. |
| Overfitting | Decorar o treino e falhar em dados novos. |
| Dropout / L2 / early stopping | Técnicas de regularização contra overfitting. |
| Adam | Otimizador padrão do mercado; adapta o lr por peso. |
| Data leakage | Informação do teste vazando para o treino; invalida as métricas. |
| Precisão / recall / F1 / AUC | Métricas de classificação além da acurácia. |
| CNN / filtro / pooling | Rede para imagens; detector deslizante; resumo espacial. |
| Transfer learning / fine-tuning | Reaproveitar modelo pré-treinado; ajustá-lo ao seu problema. |
| RNN / LSTM / vanishing gradient | Redes com memória para sequências; e o problema que a LSTM mitiga. |
| Transformer / self-attention | Arquitetura dominante; cada token pondera todos os outros (Q, K, V). |
| Token / embedding | Pedaço de texto virando id; vetor denso onde perto = parecido. |
| LLM / alucinação | Transformer decoder gigante; sua tendência a inventar fatos plausíveis. |
| RAG | Busca semântica + LLM: respostas baseadas nos seus documentos. |
| LoRA / quantização | Fine-tuning leve de LLMs; compressão de pesos para inferência barata. |
| RLHF | Refino de LLMs com preferências humanas via reforço. |
| MLOps / drift | Disciplina de modelos em produção; a degradação natural deles com o tempo. |
| Autoencoder / GAN / difusão | Três famílias generativas: comprimir, duelar, remover ruído. |