Pular para conteúdo

Aula 17 - Redes Neurais Convolucionais (CNNs) e Visão 👁️

Objetivo Pedagógico

Objetivo: Arquitetura e matemática das Redes Neurais Convolucionais (CNNs): Operação de Convolução 2D, Kernels, Padding, Stride, Pooling e arquiteturas clássicas (ResNet com Residual Connections).


📑 1. Fundamentos Teóricos & Análise Técnica

O processamento de dados visuais (imagens e vídeos) por redes neurais densas tradicionais (Multi-Layer Perceptrons - MLPs) é inviável devido à explosão de parâmetros (uma imagem colorida de \(1024 \times 1024\) pixels exigiria milhões de conexões por neurônio) e à perda da coerência geométrica bidimensional.

As Redes Neurais Convolucionais (CNNs) resolvem essa barreira através de dois princípios de inspiração biológica: 1. Campos Receptivos Locais (Local Receptive Fields): Pequenas matrizes de pesos compartilhados denominadas Kernels / Filtros (ex: \(3 \times 3\) ou \(5 \times 5\)) deslizam sobre a imagem calculando o produto escalar local, detectando bordas, texturas e contornos. 2. Compartilhamento de Pesos (Weight Sharing): O mesmo filtro de detecção de borda é aplicado a toda a extensão da imagem, conferindo Invariância à Translação com número reduzido de parâmetros. 3. Conexões Residuais (Skip Connections / ResNet): Introduzidas por Kaiming He (2015), permitem treinar redes com centenas de camadas ao permitir que o gradiente flua sem atenuação através do atalho \(F(x) + x\), mitigando o problema do gradiente evanescente (Vanishing Gradient).

📐 Arquitetura Conceitual & Diagrama de Fluxo

graph LR
    Input["Imagem de Entrada: 3x224x224"] --> Conv["Convolução 2D (Filtros 3x3 + ReLU)"]
    Conv --> Pool["Max Pooling (Redução Espacial 2x2)"]
    Pool --> ResBlock["Bloco Residual ResNet: F(x) + x"]
    ResBlock --> GAP["Global Average Pooling"]
    GAP --> Linear["Camada Linear Softmax (Classificação)"]
    style Input fill:#e1f5fe,stroke:#01579b
    style Conv fill:#fff3e0,stroke:#e65100
    style ResBlock fill:#e8f5e9,stroke:#2e7d32
    style Linear fill:#f3e5f5,stroke:#7b1fa2

🔍 Pilares e Diretrizes Técnicas

Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Operação Matemática de Convolução: \(S(i,j) = (I * K)(i,j) = \sum_m \sum_n I(i-m, j-n) K(m,n)\). - Max Pooling para Redução Dimensional: Extração do valor máximo local para reduzir o custo computacional e aumentar a robustez. - Padding e Stride: Controle rigoroso das dimensões espaciais de saída das matrizes de ativação. - Conexões Residuais de Identidade: Superação da barreira de profundidade em modelos profundos de visão computacional.


🛠️ 2. Implementação Prática em Deep Learning, PyTorch e Visão Computacional

Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:

// cnn_resnet_block.py (Implementação de Bloco Residual em PyTorch)
import torch
import torch.nn as nn

class ResidualBlock(nn.Module):
    def __init__(self, channels: int):
        super().__init__()
        self.conv1 = nn.Conv2d(channels, channels, kernel_size=3, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(channels)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = nn.Conv2d(channels, channels, kernel_size=3, padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(channels)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        residual = x # Salva a identidade
        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)
        out = self.conv2(out)
        out = self.bn2(out)

        out += residual # Conexão de Atalho Residual: F(x) + x
        return self.relu(out)

# Teste com tensor aleatório (Batch: 8, Canais: 64, Altura: 32, Largura: 32)
x = torch.randn(8, 64, 32, 32)
block = ResidualBlock(channels=64)
output = block(x)
print("Dimensão da Saída Residual:", output.shape) # Preserva 8, 64, 32, 32!

💡 Análise Passo a Passo do Código

  1. Conexão Residual out += residual: Adiciona a entrada original diretamente à saída das convoluções, facilitando a retropropagação do gradiente.
  2. BatchNorm2d Obrigatório: Normaliza as ativações entre camadas para estabilizar e acelerar o treinamento.
  3. Preservação Espacial com padding=1: Kernels \(3 \times 3\) com preenchimento 1 preservam a largura e altura exatas do tensor.

🎯 3. Próximos Passos & Sequência Didática