Autoencoders
Visão geral
Um autoencodificador (autoencoder) é uma rede neural (neural network) treinada para reconstruir sua entrada. Ele faz isso aprendendo dois mapeamentos acoplados:
- um codificador (encoder) que comprime a entrada em uma representação latente (latent representation) (geralmente) de menor dimensionalidade
- um decodificador (decoder) que expande a representação latente de volta ao espaço de entrada original
Autoencodificadores são amplamente usados para:
- Compressão (aprender códigos compactos)
- Remoção de ruído (remover ruído ou corrupção)
- Aprendizado de representações (aprender características úteis sem rótulos)
- Detecção de anomalias (sinalizar entradas que são mal reconstruídas)
Conceitualmente, autoencodificadores se inserem na família mais ampla de arquiteturas codificador–decodificador (encoder–decoder architectures), mas, ao contrário de muitos codificador–decodificadores supervisionados (por exemplo, modelos de tradução), o alvo de treinamento normalmente é a própria entrada. Autoencodificadores são treinados com ferramentas padrão de aprendizado profundo (deep learning): Redes Neurais, Retropropagação (Backpropagation) e Descida do Gradiente (Gradient Descent).
Arquitetura central e objetivo
Codificador → código latente → decodificador
Dada uma entrada vetorial (ou tensor) (x), um autoencodificador define:
- Codificador: (z = f_\theta(x))
- Decodificador: (\hat{x} = g_\phi(z))
onde:
- (z) é o código latente (latent code) (também chamado de incorporação (embedding), gargalo (bottleneck), representação)
- (\hat{x}) é a reconstrução
- (\theta, \phi) são parâmetros treináveis
A rede é treinada para tornar (\hat{x}) o mais próximo possível de (x).
Perda de reconstrução
Um objetivo típico é:
[ \min_{\theta,\phi} ; \mathbb{E}{x \sim \mathcal{D}}\left[ \mathcal{L}(x, g\phi(f_\theta(x))) \right] ]
Escolhas comuns de perda incluem:
- Erro quadrático médio (mean squared error, MSE) para valores contínuos: [ \mathcal{L}(x,\hat{x}) = |x - \hat{x}|_2^2 ]
- Entropia cruzada binária (binary cross-entropy, BCE) para entradas em ([0,1]) (por exemplo, pixels normalizados tratados como Bernoulli-like): [ \mathcal{L}(x,\hat{x}) = -\sum_i x_i \log \hat{x}_i + (1-x_i)\log(1-\hat{x}_i) ]
- Perdas perceptuais / de características (perceptual / feature losses) (menos comuns em autoencodificadores “clássicos”, mais comuns em pipelines de visão)
A escolha importa: MSE tende a incentivar reconstruções borradas em imagens (ele faz média de saídas plausíveis), enquanto perdas alternativas podem preservar detalhes mais nítidos.
Subcompleto vs. sobrecompleto
Uma escolha de projeto central é a dimensionalidade latente:
- Autoencodificador subcompleto (undercomplete autoencoder): (\dim(z) < \dim(x))
Força compressão; ajuda a evitar a cópia trivial. - Autoencodificador sobrecompleto (overcomplete autoencoder): (\dim(z) \ge \dim(x))
Ainda pode aprender representações úteis, mas precisa de regularização (regularization); caso contrário, pode aprender o mapeamento identidade (copiar a entrada para a saída sem abstração).
Dinâmica de treinamento
Autoencodificadores são treinados como redes feedforward (feedforward) padrão:
- Passagem direta: (x \to z \to \hat{x})
- Calcular a perda de reconstrução (\mathcal{L}(x,\hat{x}))
- Retropropagar gradientes pelo decodificador e pelo codificador
- Atualizar parâmetros com SGD/Adam
Na prática, um treinamento estável frequentemente se beneficia de:
- camadas de normalização (normalization layers) (normalização em lote (BatchNorm)/normalização de camada (LayerNorm))
- inicialização cuidadosa
- função de ativação de saída (output activation) apropriada (por exemplo, sigmoide (sigmoid) para pixels em ([0,1]))
Fundamentos teóricos (o que autoencodificadores aprendem)
Conexão com PCA (autoencodificadores lineares)
Um resultado clássico: se você usa
- codificador/decodificador lineares (sem não linearidades (nonlinearities)),
- perda MSE,
- e um gargalo subcompleto,
então o subespaço aprendido coincide com a Análise de Componentes Principais (Principal Component Analysis, PCA) sob certas condições. Em outras palavras, um autoencodificador linear subcompleto aprende (aproximadamente) o mesmo subespaço que a Análise de Componentes Principais: ele projeta os dados em direções de máxima variância.
Autoencodificadores não lineares generalizam essa ideia ao aprender variedades não lineares (nonlinear manifolds) em vez de subespaços lineares.
Intuição de aprendizado de variedades
Muitos conjuntos de dados do mundo real ficam próximos de uma variedade de menor dimensionalidade (por exemplo, imagens naturais ocupam um subconjunto minúsculo de todas as grades possíveis de pixels). Autoencodificadores podem ser vistos como aprendendo:
- um codificador que mapeia pontos de dados para coordenadas em/próximas de uma variedade latente
- um decodificador que mapeia essas coordenadas de volta ao espaço dos dados
Variantes de remoção de ruído e variantes regularizadas reforçam esse efeito, incentivando representações que capturam estrutura estável em vez de ruído.
Regularização como a chave para características “úteis”
Sem restrições, um autoencodificador pode aprender uma solução degenerada (especialmente se for sobrecompleto): simplesmente copiar entradas. A regularização força o modelo a equilibrar fidelidade de reconstrução com uma representação que tenha propriedades desejáveis (esparsidade, robustez, suavidade etc.). Isso faz paralelo com ideias mais amplas em Regularização.
Variantes comuns de autoencodificadores
Autoencodificadores de remoção de ruído (Denoising Autoencoders, DAE)
Um autoencodificador de remoção de ruído é treinado para reconstruir a entrada limpa a partir de uma versão corrompida:
- corrupção: (\tilde{x} \sim q(\tilde{x}\mid x))
- objetivo: minimizar (\mathcal{L}(x, g(f(\tilde{x}))))
Corrupções podem incluir:
- ruído Gaussiano aditivo
- mascaramento de pixels/características aleatórios
- ruído sal-e-pimenta
- dropout aleatório (dropout) de dimensões de entrada
Por que funciona: o modelo precisa inferir conteúdo faltante/perturbado a partir do contexto, o que incentiva o aprendizado de características robustas e semânticas em vez de copiar.
Autoencodificadores esparsos
Um autoencodificador esparso (sparse autoencoder) incentiva a maioria das unidades latentes a ficar próxima de zero para qualquer entrada dada. Isso pode ser feito por meio de:
- uma penalidade (L_1) nas ativações: (\lambda |z|_1)
- uma penalidade de divergência KL (KL-divergence) impondo uma ativação média-alvo por unidade
Esparsidade frequentemente produz características mais interpretáveis e pode melhorar a utilidade a jusante (downstream), especialmente quando (\dim(z)) não é muito pequena.
Autoencodificadores contrativos
Um autoencodificador contrativo (contractive autoencoder) penaliza a sensibilidade da representação latente a pequenas mudanças na entrada adicionando um termo como:
[ \lambda \left|\frac{\partial f_\theta(x)}{\partial x}\right|_F^2 ]
Isso incentiva invariância local e representações mais suaves (com custo computacional adicional devido a jacobianos (Jacobians)).
Autoencodificadores convolucionais
Para imagens e dados espaciais, a escolha padrão é um autoencodificador convolucional (convolutional autoencoder), usando camadas de convolução e reamostragem (upsampling)/convolução transposta (transposed convolution). Isso se alinha ao viés indutivo espacial das Redes Neurais Convolucionais (CNNs) e geralmente produz reconstruções melhores do que achatar pixels em um MLP.
Estrutura típica:
- Codificador: Conv → reduzir amostragem (stride/pool) → Conv → …
- Decodificador: Reamostrar/convolução transposta → Conv → …
Autoencodificadores de sequência
Para sequências (texto, áudio, séries temporais), você pode construir autoencodificadores usando:
- codificadores–decodificadores com redes neurais recorrentes (RNNs) e LSTM (historicamente)
- convoluções 1D
- modelos baseados em atenção (attention-based) como Transformadores (Transformers)
Um cuidado para texto: tokens discretos complicam perdas de reconstrução e decodificação; autoencodificadores de sequência geralmente são mais complexos do que AEs de imagem/tabelares e podem se misturar a objetivos de modelagem de linguagem (language-modeling).
Autoencodificadores variacionais (VAEs)
Um Autoencoder Variacional (Variational Autoencoder, VAE) torna o código latente probabilístico e adiciona um termo de regularização KL, transformando o modelo em um verdadeiro modelo gerativo (generative model). VAEs são importantes o suficiente para merecer um tratamento próprio; veja Autoencodificadores Variacionais. Na prática, VAEs também são usados como compressores de espaço latente (latent-space compressors) em alguns pipelines gerativos modernos (por exemplo, difusão latente (latent diffusion)).
Aplicações práticas
1) Compressão e redução de dimensionalidade
Autoencodificadores podem servir como esquemas de compressão aprendidos:
- O codificador produz um código compacto (z)
- Armazenar/transmitir (z)
- O decodificador reconstrói (\hat{x})
Isso é mais útil quando:
- você tem um domínio de dados restrito (por exemplo, um tipo específico de imagem médica)
- você pode tolerar reconstrução com perdas (lossy)
- você precisa de uma representação ajustada ao seu conjunto de dados, em vez de codecs genéricos
Notas práticas:
- Se você precisa de razões de compressão garantidas e artefatos bem compreendidos, codecs tradicionais podem superar.
- Autoencodificadores brilham quando “fidelidade perceptual (perceptual fidelity)” ou desempenho em tarefas a jusante importa mais do que reconstrução perfeita pixel a pixel.
2) Remoção de ruído e restauração de sinais
Autoencodificadores de remoção de ruído podem remover ruído em:
- imagens (ruído de sensor, artefatos de compressão)
- áudio (ruído de fundo)
- sinais científicos (ruído de medição)
Exemplo: treine em imagens limpas, corrompa-as com ruído Gaussiano durante o treinamento e aprenda a reconstruir a versão limpa. No tempo de inferência (inference), forneça uma imagem ruidosa e obtenha uma saída mais limpa.
3) Detecção de anomalias
Uma abordagem comum: treinar um autoencodificador apenas com dados normais. Na inferência, compute o erro de reconstrução:
[ s(x) = \mathcal{L}(x, \hat{x}) ]
Se (s(x)) for grande, trate (x) como anômalo.
Isso funciona melhor quando anomalias estão fora da distribuição (out-of-distribution) de um jeito que o modelo não consegue reconstruir bem. Pode falhar quando:
- anomalias são sutis e ainda reconstruíveis
- o autoencodificador generaliza bem demais e reconstrói anomalias mesmo assim
Esse padrão é amplamente usado em monitoramento industrial, sinais de fraude e controle de qualidade; ele se relaciona a métodos mais amplos de Detecção de Anomalias.
4) Aprendizado de representações (pré-treinamento autossupervisionado)
Autoencodificadores são uma forma inicial e influente de Aprendizado Autossupervisionado (Self-Supervised Learning): eles aprendem características sem rótulos.
Um fluxo de trabalho típico:
- Treine um autoencodificador em grandes dados não rotulados.
- Use a saída do codificador (z) como características para um modelo supervisionado.
- Opcionalmente, faça ajuste fino (fine-tune) do codificador de ponta a ponta (end-to-end).
Na prática moderna, métodos contrastivos (contrastive) e de previsão mascarada (masked-prediction) frequentemente são preferidos para aprendizado de representações, mas objetivos no estilo de autoencodificadores continuam importantes, especialmente quando:
- reconstrução é diretamente significativa (remoção de ruído, compressão)
- você precisa de um espaço latente fiel para tarefas gerativas ou de restauração a jusante
5) Imputação de dados ausentes
Se você treina com ruído de mascaramento (ocultar aleatoriamente características), o decodificador aprende a prever valores faltantes a partir do contexto observado. Isso é útil em conjuntos de dados tabulares e de sensores com observações parciais.
Considerações práticas e escolhas de projeto
Tamanho do gargalo e capacidade
- Pequeno demais: subajusta, perde informações importantes, reconstruções ficam ruins.
- Grande demais (sem regularização): risco de aprender o mapeamento identidade, códigos latentes ficam menos significativos.
Um bom ponto de partida é escolher uma dimensão de gargalo que produza uma reconstrução aceitável enquanto ainda restringe o modelo (ou adicionar regularização).
Escolha do decodificador e da ativação de saída
Combine a parametrização da saída com os dados:
- imagens escaladas para ([0,1]): saída sigmoide + BCE (ou MSE)
- sinais de valores reais: saída linear + MSE
- características categóricas: softmax por campo + entropia cruzada (cross-entropy)
Um descompasso aqui é uma fonte comum de treinamento instável e reconstruções ruins.
Evitando cópia trivial
Se você observa reconstruções quase perfeitas, mas características inúteis, considere:
- reduzir a dimensão latente (subcompleto)
- adicionar corrupção por remoção de ruído
- adicionar penalidade de esparsidade
- adicionar dropout dentro da rede
- limitar o poder do decodificador (um decodificador poderoso demais pode memorizar)
Avaliação além da perda de reconstrução
A perda de reconstrução por si só pode enganar. Dependendo do seu objetivo, avalie:
- desempenho em tarefas a jusante usando características do codificador
- ROC/AUPRC de detecção de anomalias
- métricas perceptuais para imagens (quando apropriado)
- robustez a ruído/corrupção
Exemplo prático: autoencodificador de remoção de ruído em PyTorch (imagens)
Abaixo está um autoencodificador convolucional compacto de remoção de ruído. Ele treina com entradas ruidosas e prediz a imagem limpa.
import torch
import torch.nn as nn
import torch.nn.functional as F
class ConvDenoisingAE(nn.Module):
def __init__(self, in_ch=1, latent_ch=32):
super().__init__()
# Encoder: downsample twice
self.enc = nn.Sequential(
nn.Conv2d(in_ch, 16, 3, stride=2, padding=1), # H/2
nn.ReLU(inplace=True),
nn.Conv2d(16, latent_ch, 3, stride=2, padding=1), # H/4
nn.ReLU(inplace=True),
)
# Decoder: upsample twice
self.dec = nn.Sequential(
nn.ConvTranspose2d(latent_ch, 16, 4, stride=2, padding=1), # H/2
nn.ReLU(inplace=True),
nn.ConvTranspose2d(16, in_ch, 4, stride=2, padding=1), # H
nn.Sigmoid(), # for images scaled to [0, 1]
)
def forward(self, x):
z = self.enc(x)
x_hat = self.dec(z)
return x_hat
def add_gaussian_noise(x, sigma=0.2):
noise = sigma * torch.randn_like(x)
return torch.clamp(x + noise, 0.0, 1.0)
# Sketch of a training step
def train_step(model, optimizer, clean_batch):
model.train()
noisy = add_gaussian_noise(clean_batch, sigma=0.2)
recon = model(noisy)
loss = F.mse_loss(recon, clean_batch)
optimizer.zero_grad()
loss.backward()
optimizer.step()
return loss.item()
Dicas práticas:
- Comece com MSE para remoção de ruído; experimente perda (L_1) para saídas mais nítidas.
- Garanta que as entradas estejam normalizadas de forma consistente (por exemplo, ([0,1])).
- Se as saídas parecerem suaves demais, considere perdas perceptuais ou arquiteturas mais fortes — mas tenha em mente que “mais nítido” nem sempre significa “mais preciso”.
Quando usar autoencodificadores (e quando não)
Autoencodificadores são uma boa escolha quando você precisa:
- de reconstrução como tarefa (remoção de ruído, compressão, imputação)
- de uma representação latente que preserve informações da entrada
- de uma linha de base não supervisionada (unsupervised baseline) para detecção de anomalias
Você pode preferir alternativas quando:
- você quer representações otimizadas para discriminação: métodos contrastivos em Aprendizado Autossupervisionado frequentemente vencem
- você precisa de uma linha de base linear simples: Análise de Componentes Principais é rápida, interpretável e robusta
- você quer geração de alta qualidade: modelos probabilísticos como Autoencodificadores Variacionais ou abordagens modernas de difusão (veja Modelos de Difusão (Diffusion Models)) normalmente são mais adequadas
Resumo
Autoencodificadores aprendem a reconstruir entradas por meio de um pipeline codificador–decodificador, o que os torna úteis para compressão, remoção de ruído e aprendizado de representações. O principal desafio técnico é impedir mapeamentos identidade triviais, tipicamente via um gargalo de informação (information bottleneck) (espaço latente subcompleto) ou regularização (remoção de ruído, esparsidade, penalidades contrativas). Na prática, autoencodificadores convolucionais são o padrão para imagens, enquanto autoencodificadores de sequência adaptam a mesma ideia a séries temporais e texto com componentes recorrentes ou baseados em atenção.