CNNs: ResNet, EfficientNet, ConvNeXt
- ⬜🔄 Image processing em pipeline(Computer Vision Clássico)
Recomendamos completar os pré-requisitos antes de seguir, mas nada te impede de continuar.
Convolution: modelo mental correto
| Ideia arquitetural | Problema que resolveu | Custo |
|---|---|---|
| Convolução com pesos compartilhados | Rede densa em imagem tem parâmetros demais e ignora a localidade | Só captura padrão local — o alcance vem da profundidade |
| Redução de resolução | Ampliar o campo de visão sem explodir o cálculo | Perde detalhe fino |
| Conexão de atalho | Rede mais profunda ficava PIOR — dificuldade de otimização, não sobreajuste | Praticamente nenhum; virou padrão |
| Escala coordenada | Aumentar só a profundidade satura rápido | Exige buscar a proporção entre profundidade, largura e resolução |
| Normalização por lote | Treino instável e lento | Comportamento diferente em treino e inferência — origem de bug clássico |
Convolução 2D é um filtro deslizante que calcula produto escalar numa janela. Três propriedades importam: locality (pixel vizinho influencia mais), weight sharing (mesmo filtro em todas as posições — poucos parâmetros) e translation equivariance (objeto deslocado gera feature map deslocado). É esse bias indutivo que faz CNN aprender com menos dados que um MLP.
import torch.nn as nn
block = nn.Sequential(
nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(128),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2), # downsample 2x
)ResNet: skip connections
class BasicBlock(nn.Module):
def __init__(self, ch):
super().__init__()
self.conv1 = nn.Conv2d(ch, ch, 3, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(ch)
self.conv2 = nn.Conv2d(ch, ch, 3, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(ch)
def forward(self, x):
identity = x
out = torch.relu(self.bn1(self.conv1(x)))
out = self.bn2(self.conv2(out))
out = out + identity # skip connection
return torch.relu(out)O truque conceitual: a rede aprende o resíduo (quanto mudar), não a representação toda. Se mudar nada é ótimo, basta zerar os pesos de F(x) — gradiente flui direto pelo atalho.
EfficientNet e ConvNeXt
EfficientNet (2019) trouxe compound scaling. ConvNeXt (2022) pegou o design do Swin Transformer e aplicou em CNN: kernel 7x7, LayerNorm em vez de BatchNorm, GELU, inverted bottleneck. Mostrou que CNN bem modernizada ainda compete com ViT no ImageNet.
# Transfer learning pragmático com timm
import timm
model = timm.create_model("convnext_tiny", pretrained=True, num_classes=10)
# Congelar backbone nas primeiras épocas
for p in model.parameters():
p.requires_grad = False
for p in model.head.parameters():
p.requires_grad = TrueO que a operação de convolução explora que uma rede densa não explora?
Transfer learning: receita que funciona
# Fase 1: head only, lr alto (1e-3), 3-5 epochs
# Fase 2: descongela tudo, lr baixo (1e-4 head, 1e-5 backbone), 10-20 epochs
from torch.optim import AdamW
param_groups = [
{"params": model.head.parameters(), "lr": 1e-4},
{"params": [p for n, p in model.named_parameters() if "head" not in n], "lr": 1e-5},
]
optim = AdamW(param_groups, weight_decay=1e-4)Em 2026, para 90% dos problemas de classificação com <100k imagens: timm + ConvNeXt-Tiny ou EfficientNet-B0 pretrained → fine-tune em 2 fases → acurácia competitiva com uma fração do custo de treinar ViT do zero.
Perguntas frequentes
❓ O que a conexão de atalho resolveu?
❓ Como escolher a arquitetura de classificação?
❓ Ajuste fino de todas as camadas ou só das últimas?
Fixando
Qual problema as conexões residuais resolveram?
O que a escala composta propõe?
Terminou de ler?
Marcar como concluído registra o XP, mantém sua sequência e coloca 3 cartas deste módulo na fila de revisão espaçada.
Próximos passos sugeridos
Temas deste módulo
Discussão
Carregando comentários…