Uma camada convolucional é uma camada densa à qual essas duas coisas foram impostas:
localidade e compartilhamento de pesos. Nada é acrescentado — capacidade é retirada, de propósito.
Uma arquitetura é um prior escrito como restrição sobre os pesos.
6 entradas → 4 saídas (1-D, kernel 3). Cada célula é um peso; a cor diz quais são o mesmo número.
passo 1, sem padding
O PyTorch faz correlação cruzada (não gira o kernel). Para a rede não importa: o kernel é aprendido. Para conferir derivadas à mão, importa — volta na passagem reversa.
Quase todo bug de CNN é de formato. Quando o PyTorch reclamar no primeiro Linear, imprima o formato camada por camada — não chute o número.
Entrada (1, 1, 28, 28) = (imagens, canais, altura, largura): uma imagem cinza de 28×28. Preencha antes de virar o slide.
| camada | saída |
|---|---|
Conv2d(1, 8, 5) |
? |
MaxPool2d(2) |
? |
Conv2d(8, 16, 3, padding=1) |
? |
MaxPool2d(2) |
? |
Conv2d(16, 32, 3, stride=2) |
? |
Flatten() |
? |
Conv2d(canais que entram, nº de filtros, lado do kernel)
MaxPool2d(2): janela 2×2, passo 2
Lado da saída:
Responda em canais × altura × largura.
| camada | saída | de onde vem |
|---|---|---|
Conv2d(1, 8, 5) |
8 × 24 × 24 |
8 filtros · (28 + 0 − 5)/1 + 1 = 24 |
MaxPool2d(2) |
8 × 12 × 12 |
mesmos canais · (24 − 2)/2 + 1 = 12 |
Conv2d(8, 16, 3, padding=1) |
16 × 12 × 12 |
16 filtros · (12 + 2 − 3)/1 + 1 = 12 |
MaxPool2d(2) |
16 × 6 × 6 |
mesmos canais · (12 − 2)/2 + 1 = 6 |
Conv2d(16, 32, 3, stride=2) |
32 × 2 × 2 |
32 filtros · ⌊(6 + 0 − 3)/2⌋ + 1 = 2 |
Flatten() |
128 |
32 · 2 · 2 → o próximo é Linear(128, …) |
Conv2d(3, 64, 3) numa imagem 32 × 32. Quantos parâmetros?
Compartilhar pesos dá uma propriedade exata: desloque a entrada e o mapa se desloca junto.
Isso é equivariância à translação — o certo para um detector.
Um classificador quer "bota" onde quer que a bota esteja. Equivariância só vira invariância quando:
| mecanismo | o que faz |
|---|---|
| pooling / conv com passo | descarta a posição dentro da janela — invariância pequena e local |
| global average pooling no fim | colapsa |
| data augmentation | compra, com exemplos, invariância ao que a conv não cobre |
O prior cobre translação e mais nada. Rotação, escala, ponto de vista: comprados com augmentation e dados — numa CNN exatamente como num Transformer.
Flatten não colapsa nada: mantém cada posição numa coordenada própria do vetor.No laboratório: MLP, CNN + Flatten e CNN + GAP treinadas no Fashion-MNIST. Desloque o teste 4 px. Qual cai menos? E se girar 90°?
Três épocas de treino no Fashion-MNIST, Adam, lr = 1e-3. Acurácia de teste:
| rede | parâmetros | no lugar | deslocado 4 px | deslocado 8 px | girado 90° |
|---|---|---|---|---|---|
MLP 784 → 256 → 128 → 10 |
235 146 | 0,86 | 0,25 | 0,18 | 0,05 |
| CNN + Flatten | 20 586 | 0,90 | 0,33 | 0,19 | 0,06 |
| CNN + GAP | 24 170 | 0,85 | 0,81 | 0,65 | 0,07 |
| CNN + Flatten, augmentation ±4 px | 20 586 | 0,85 | 0,80 | 0,26 | — |
Uma unidade funda não vê a imagem: vê o que a alimentou, recursivamente.
Self-attention alcança todas as posições na camada 1, a um custo O(n²). O trade-off CNN × Transformer inteiro está nessa frase.
Qual enxerga mais? Qual custa menos?
| gradiente | o que é | implementação |
|---|---|---|
| soma de |
uma redução | |
| correlação cruzada da entrada com |
uma convolução | |
| correlação "full" de |
uma convolução (a "transposta") |
Com passo s > 1: insira s − 1 zeros entre as entradas de ∂L/∂Y e aplique a mesma receita.
Chega
ConvTranspose2d: o upsampling de decodificadores e GANs.A correção que todo mundo usa:
nn.Upsample + Conv2d — nunca uma transposta pura.
Odena, Dumoulin & Olah (2016), Deconvolution and Checkerboard Artifacts, Distill.
Nenhum peso. Resume cada janela num número — e a escolha do resumo decide quem recebe gradiente.
Entrada 6 × 6, max 2 × 2, passo 2, gradiente 1 em cada saída. Quantas das 36 células recebem algo?
Flatten desmancha
Linear(25088, 4096)GAP tira a média de cada canal sobre
Linear(C, classes).| camada | saída | parâmetros | campo receptivo |
|---|---|---|---|
| entrada | 1 × 28 × 28 | — | 1 |
Conv2d(1, 16, 3, padding=1) + BatchNorm + ReLU |
16 × 28 × 28 | 192 | 3 |
MaxPool2d(2) |
16 × 14 × 14 | 0 | 4 |
Conv2d(16, 32, 3, padding=1) + BatchNorm + ReLU |
32 × 14 × 14 | 4 704 | 8 |
MaxPool2d(2) |
32 × 7 × 7 | 0 | 10 |
Conv2d(32, 64, 3, padding=1) + BatchNorm + ReLU |
64 × 7 × 7 | 18 624 | 18 |
AdaptiveAvgPool2d(1) + Flatten |
64 | 0 | a imagem toda |
Linear(64, 10) |
10 | 650 | — |
| total | 24 170 |
Resolução cai, canais sobem · os parâmetros moram no fim · um MLP de acurácia parecida tem 235 146.
1×1 — uma camada densa por posição: mistura canais, não olha vizinhos. É como toda arquitetura muda o número de canais barato.
Separável em profundidade = um kernel
64 → 128, 3×3 |
parâmetros |
|---|---|
Conv2d(64, 128, 3) |
73 856 |
depthwise Conv2d(64, 64, 3, groups=64) |
640 |
pointwise Conv2d(64, 128, 1) |
8 320 |
| separável | 8 960 (12%) |
Previsão: 1/128 + 1/9 ≈ 0,119. Todo modelo que roda num celular (MobileNet, EfficientNet) usa isso.
2020–2021: "a atenção venceu a convolução". Será?
Boa parte da vantagem reportada dos ViTs era a receita de treino, não a arquitetura. As duas famílias convergiram para o mesmo bloco, vindo de direções opostas.
Convolução
prior forte, barato e fixo
vence quando os dados são escassos, a latência importa ou a estrutura é genuinamente local
Transformer
prior fraco, caro e aprendível
vence quando você pode pagar por dados suficientes para aprender uma estrutura melhor do que a que teria imposto
Esse trade-off é o eixo ao longo do qual as próximas quatro aulas se movem: atenção, Transformers, ViT e transfer learning.
Notebook no Colab, ~2 h, Fashion-MNIST. Cada seção termina num checkpoint com valor de verificação.
LinearRoteiro: (1) por que restringir uma camada densa; (2) formato e parâmetros; (3) equivariância e campo receptivo; (4) a volta: convolução e pooling; (5) a arquitetura que sobreviveu e onde as convoluções vivem em 2026. Fecha com o laboratório no Colab.
Deixe a turma chutar antes de revelar. O ponto do segundo item é o que importa mais que a contagem: a densa não sabe que uma borda é uma borda em qualquer lugar.
Linha i = saída i, coluna j = entrada j. Densa: tudo ligado a tudo. Localidade: só a faixa diagonal sobra. Compartilhamento: a faixa usa os mesmos três números em toda linha — isso é uma matriz de Toeplitz. Multiplicá-la é exatamente deslizar o kernel.
Aperte play com "borda vertical". Depois mude passo para 2 e padding para same e peça a fórmula antes de olhar a linha de baixo. A razão densa/conv é o argumento da aula.
No laboratório (seção 2) o mesmo exercício aparece com o erro do Linear(256, 10).
As duas CNNs têm BatchNorm: a única diferença entre elas é a cabeça. Notebook, seção 7.
Peça previsões: 5 camadas 3x3 passo 1 → 11. Passo 2 → ? (63). Dilatação 2 → 21.
Caso inicial = os números do slide anterior. Avançar linha a linha; na linha 4 clicar em Y[1,1] (7), na linha 7 no centro de dXp (quatro janelas, 1) e depois num canto (uma janela). Depois: "conte as janelas" (dX = 1 2 1 / 2 4 2 / 1 2 1), padding "same" (o gradiente da saída do canto cai quase todo nos zeros e some na linha 8) e passo 2 (janelas sem sobreposição: dX são cópias de K escaladas por dY).
Resposta da pergunta anterior: 9 recebem, 27 ficam sem nada. Depois arraste o passo para 1 e mostre o acúmulo quando as janelas se sobrepõem.