Autoencoders: o Gargalo, a Reconstrução e o Latente

por Frank de Alcantara em 28/07/2026

Autoencoders: o Gargalo, a Reconstrução e o Latente

Um sistema de inteligência artificial não percebe o mundo diretamente. Ele recebe medições: valores de pixels, amostras de áudio, leituras de sensores, identificadores de palavras ou estados fornecidos por outro programa. Antes de classificar uma imagem, compreender uma frase ou escolher uma ação, o sistema precisa transformar essas medições numa descrição interna em que as regularidades relevantes estejam acessíveis. Sem essa transformação, cada tarefa posterior teria de redescobrir, a partir dos dados brutos, o que pode ser ignorado e o que não pode ser perdido.

Chamaremos de representação essa descrição interna. Se $x$ é uma observação e $r$ é uma função de transformação, podemos escrever

\[z=r(x),\]

na qual $z$ é a representação de $x$. A fórmula é curta, mas esconde escolhas importantes e determinantes para o sucesso do projeto.

Uma representação de uma imagem pode conservar cor e descartar posição; outra pode conservar contornos e descartar textura. Ambas são descrições menores ou mais organizadas da mesma observação, porém servem a tarefas diferentes.

Estudar representações é descobrir quais invariâncias, separações e perdas de informação a função $r$ introduz antes que um classificador, um planejador ou uma política receba os dados.

Uma representação, sozinha, ainda não é um modelo de mundo. Ela descreve uma observação. Um modelo de mundo acrescenta estrutura preditiva: relaciona partes ocultas, estados sucessivos ou consequências de ações. Em outras palavras, a representação responde como descrever o que foi observado?; o modelo de mundo tenta responder também o que não foi observado, o que pode acontecer depois e como uma intervenção altera esse futuro?. A passagem da primeira pergunta para a segunda fornece o esforço que faremos nesta série.

No mapa do blog, a série Transformers explica como sequências são representadas, processadas e geradas, enquanto a série IA Aplicada acompanha os problemas, agentes e métodos que compõem uma disciplina clássica de inteligência artificial em cursos de graduação no Brasil.

Representações podem ser simbólicas, probabilísticas, geométricas ou neurais; as redes neurais não receberam monopólio sobre o assunto por decreto. Receberam por direito e, talvez, por aplicabilidade computacional.

Nesta série, começaremos pela linhagem neural porque ela aprende a transformação $r$ diretamente dos dados por gradiente e porque é dessa linhagem que surgem os métodos que conduzirão ao JEPA e os algoritmos mais recentes.

Este é um recorte técnico e histórico, não uma definição de toda a inteligência artificial. É apenas uma base de estudo. Se continuar, a persistente leitora me acompanhará numa jornada difícil, mas eu prometo, será fascinante. Mas, precisamos fazer um acordo: eu escrevo em C++23, vou usar a matemática e tentar mostrar tudo de forma que os exemplos possam ser feitos à mão. Se concordar com isso, continue. Se não concordar, obrigado por ter lido até aqui.

Partiremos de objetivos de reconstrução, contraste, destilação e mascaramento até chegar às arquiteturas JEPA, de joint-embedding predictive architecture (arquitetura preditiva de incorporação conjunta). Em cada etapa perguntaremos quais regularidades a tarefa obriga o modelo a preservar, quais detalhes permite descartar e quais custos transfere para o treinamento ou para o uso.

Vamos começar por uma rede que reconstrói a própria entrada. Porque esse é o contrato neural mais simples em que a representação precisa mostrar serviço sem receber rótulos humanos. A entrada fornece simultaneamente o problema e o alvo, e qualquer restrição colocada entre os dois lados torna visível o que o modelo prefere conservar. Antes de estudar alvos lentos, pares contrastivos ou previsão de representações, convém observar essa escolha na sua forma menos ornamentada.

A astuta leitora deve, portanto, começar desconfiando de uma rede neural cuja tarefa seja receber uma entrada $x$ e devolver a mesma entrada $x$. Se este for todo o contrato, a função identidade vence a batalha antes que o primeiro gradiente seja calculado:

\[\hat{x}=x.\]

Seria uma façanha digna de um bom departamento de marketing: milhões de parâmetros para descobrir que $x=x$. Não é um esforço simples de justificar.

O problema se torna intelectualmente útil quando estragamos essa saída. Estreitamos o caminho, corrompemos a entrada ou regularizamos a representação. Quando copiar deixa de ser possível, a rede precisa decidir o que conservar para que a reconstrução continue aceitável.

Este é o território dos autoencoders. Eles abrem Representações e Modelos de Mundo porque expõem, sem qualquer gentileza, a pergunta que acompanhará todos os artigos seguintes: o que a função objetivo obriga uma representação a conservar, e quanto estamos dispostos a pagar pelo que ela esquece?

1. Encoder, latente e decoder

Um autoencoder possui duas funções. O encoder (codificador) $f_\theta$ transforma a entrada $x\in\mathbb{R}^D$ numa representação latente $z\in\mathbb{R}^d$:

\[z=f_\theta(x).\]

O decoder (decodificador) $g_\phi$ percorre o caminho inverso e produz uma reconstrução $\hat{x}\in\mathbb{R}^D$:

\[\hat{x}=g_\phi(z)=g_\phi(f_\theta(x)).\]

Chamaremos de $\mathcal{D}(x,\hat{x})\ge 0$ a função que mede a dívida entre a entrada e sua reconstrução. Para vetores reais, uma escolha comum é o MSE, de mean squared error (erro quadrático médio):

\[\mathcal{L}_{\mathrm{rec}} =\frac{1}{D}\sum_{j=0}^{D-1}(x_j-\hat{x}_j)^2.\]

Os parâmetros $\theta$ e $\phi$ são ajustados para minimizar a perda média sobre o conjunto de treino. Nenhum ser humano precisa escrever um rótulo, pois o próprio $x$ fornece o alvo. Temos, portanto, self-supervised learning (aprendizado autossupervisionado) por reconstrução.

Se $d\ge D$, as redes forem expressivas e não houver outra restrição, o sistema pode aproximar a identidade. A representação latente não precisa organizar o mundo; basta transportar informação suficiente para copiá-lo. Um gargalo subcompleto impõe $d<D$. A passagem fica estreita, mas a atenta leitora não deve confundir estreiteza com inteligência: o modelo conservará aquilo que mais reduz a distância escolhida, não aquilo que nós consideramos semanticamente importante.

2. O caso linear revela a geometria

Retiremos ativações, vieses e qualquer oportunidade de a arquitetura esconder o mecanismo. Considere dados centrados, isto é, com média zero, e uma direção unitária $u\in\mathbb{R}^D$, para a qual $\lVert u\rVert_2=1$. Um gargalo unidimensional codifica

\[z=u^\top x\]

e reconstrói

\[\hat{x}=u z=uu^\top x.\]

A matriz $uu^\top$ projeta $x$ sobre a reta gerada por $u$. O erro é a componente ortogonal descartada:

\[\lVert x-\hat{x}\rVert_2^2 =\lVert x\rVert_2^2-(u^\top x)^2.\]

O termo $\lVert x\rVert_2^2$ não depende de $u$. Portanto, ao somarmos o erro sobre o conjunto de treino, minimizá-lo equivale a maximizar a energia projetada $(u^\top x)^2$. Como os dados estão centrados, essa energia é proporcional à variância na direção $u$. A direção vencedora é a primeira componente da PCA, de principal component analysis (análise de componentes principais).

Para um gargalo linear com $d$ dimensões e perda quadrática, o mínimo global reconstrói pela projeção sobre o subespaço gerado pelas $d$ componentes principais. Há uma sutileza que resumos apressados costumam perder: o subespaço é identificado, mas as coordenadas internas do latente podem ser rotacionadas sem mudar a reconstrução. Um autoencoder não linear, por sua vez, não é “PCA com mais camadas”. A equivalência pertence ao caso linear, aos dados centrados e à perda quadrática.

A série IA Aplicada apresenta PCA no contexto da disciplina. Aqui precisamos apenas deste resultado geométrico para entender o gargalo; o material de aula permanece intocado e poderá receber uma referência quando o artigo correspondente entrar no ar.

3. Reconstruir exige escolher uma distância

O MSE trata cada coordenada como uma dívida quadrática. Em imagens, deslocar um objeto por um pixel altera muitas coordenadas embora preserve o objeto percebido. Textura, reflexo, iluminação e ruído de sensor também entram na conta. Se essas variações dominam o erro, a representação recebe incentivo para conservá-las.

Isso não torna a reconstrução ruim. Torna sua promessa precisa: boa reconstrução significa proximidade segundo $\mathcal{D}(x,\hat{x})$. Utilidade para classificação, controle ou busca é outra propriedade e precisa ser medida separadamente.

Nosso exemplo numérico tornará o conflito impossível de ignorar. Usaremos oito pontos distribuídos em duas colunas, $x=-1$ e $x=1$, com alturas $y\in{-3,-1,1,3}$. A classe é determinada apenas pelo sinal de $x$. Os dados possuem

\[\operatorname{Var}(x)=1,\qquad \operatorname{Var}(y)=5,\qquad \operatorname{Cov}(x,y)=0.\]

A conta cabe na margem. Como a média das duas coordenadas é zero, $\operatorname{Var}(x)=8/8=1$ e $\operatorname{Var}(y)=2(9+1+1+9)/8=5$. A covariância também é zero, pois os produtos $x_i y_i$ se cancelam dois a dois.

A PCA prefere o eixo $y$, pois nele está a maior variância. Projetar sobre $y$ produz MSE de $0{,}5$ por coordenada, mas a classificação pelo sinal do latente cai para $50\%$. Projetar sobre $x$ eleva o MSE para $2{,}5$, porém separa as classes com $100\%$ de acurácia. Ao escolher a melhor reconstrução, perdemos exatamente a coordenada que define a classe.

Nenhum rótulo participa do treino do autoencoder. Nós o usamos apenas depois, como instrumento de diagnóstico. A função objetivo não conhece nossa preferência sem que a coloquemos na perda, nos dados ou na arquitetura. A representação pode reconstruir melhor e servir pior.

4. Denoising muda a tarefa

Um denoising autoencoder (autoencoder de remoção de ruído) recebe uma versão corrompida $\tilde{x}$, amostrada de uma distribuição de corrupção $q(\tilde{x}\mid x)$, mas continua obrigado a reconstruir o original:

\[z=f_\theta(\tilde{x}),\qquad \hat{x}=g_\phi(z),\qquad \mathcal{L}=\mathcal{D}(x,\hat{x}).\]

Agora copiar a observação não basta, mesmo com uma representação larga, pois $\tilde{x}\ne x$. Para remover a corrupção, o modelo precisa explorar regularidades que se repetem nos dados. Sob MSE e capacidade suficiente, a previsão ótima é a média condicional $\mathbb{E}[x\mid\tilde{x}]$. Para uma saída candidata $a$, a decomposição

\[\mathbb{E}\!\left[\lVert x-a\rVert_2^2\mid\tilde{x}\right] = \mathbb{E}\!\left[ \left\lVert x-\mathbb{E}[x\mid\tilde{x}]\right\rVert_2^2 \mid\tilde{x}\right] + \left\lVert a-\mathbb{E}[x\mid\tilde{x}]\right\rVert_2^2\]

separa um termo independente de $a$ e outro não negativo. O segundo zera somente quando $a=\mathbb{E}[x\mid\tilde{x}]$. Entre todos os originais compatíveis com a entrada corrompida, a rede devolve sua média.

A corrupção, portanto, não é um ornamento estatístico. Ruído gaussiano, remoção de coordenadas e mascaramento definem problemas diferentes e favorecem regularidades diferentes. Essa decisão atravessará a série. O SimCLR construirá duas views por aumentos; o MAE esconderá patches; o I-JEPA esconderá regiões e preverá representações. Em todos esses métodos, escolher o que falta é escolher parte do que será aprendido.

5. Um autoencoder linear em C++23

O programa abaixo implementa exatamente a projeção da Seção 2 sobre os oito pontos da Seção 3. Os dados vivem em duas dimensões; o gargalo possui uma. Não treinaremos $u$, porque o objetivo deste programa não é esconder a geometria sob um otimizador. Varremos três direções conhecidas e medimos, para cada uma, o MSE por coordenada e a acurácia obtida apenas com o sinal de $z$.

#include <array>
#include <cmath>
#include <cstddef>
#include <iomanip>
#include <iostream>
#include <numbers>
#include <span>

struct Point {
    double x{};
    double y{};
    int label{};
};

struct Result {
    double latent{};
    Point reconstruction{};
};

Result encode_decode(const Point& point, const double angle) {
    const double ux = std::cos(angle);
    const double uy = std::sin(angle);
    const double latent = ux * point.x + uy * point.y;
    return {latent, {latent * ux, latent * uy, point.label}};
}

double reconstruction_mse(
    const std::span<const Point> points,
    const double angle) {
    double squared_error = 0.0;
    for (const auto& point : points) {
        const auto result = encode_decode(point, angle);
        const double error_x = point.x - result.reconstruction.x;
        const double error_y = point.y - result.reconstruction.y;
        squared_error += error_x * error_x + error_y * error_y;
    }
    const double coordinate_count =
        2.0 * static_cast<double>(points.size());
    return squared_error / coordinate_count;
}

int main() {
    const std::array points{
        Point{-1.0, -3.0, -1}, Point{-1.0, -1.0, -1},
        Point{-1.0, 1.0, -1}, Point{-1.0, 3.0, -1},
        Point{1.0, -3.0, 1}, Point{1.0, -1.0, 1},
        Point{1.0, 1.0, 1}, Point{1.0, 3.0, 1}};

    for (const double degrees : {0.0, 30.0, 90.0}) {
        const double angle = degrees * std::numbers::pi / 180.0;
        std::size_t correct = 0;
        for (const auto& point : points) {
            const double latent = encode_decode(point, angle).latent;
            const int prediction = latent >= 0.0 ? 1 : -1;
            correct += prediction == point.label;
        }
        std::cout << std::fixed << std::setprecision(3)
                  << "ângulo=" << degrees
                  << " mse=" << reconstruction_mse(points, angle)
                  << " acurácia=" << 100.0 * correct / points.size()
                  << "%\n";
    }
}

Compilado em C++23, o programa produz:

ângulo=0.000 mse=2.500 acurácia=100.000%
ângulo=30.000 mse=2.000 acurácia=75.000%
ângulo=90.000 mse=0.500 acurácia=50.000%

O código usa apenas a biblioteca padrão e funciona como referência de correção, não como implementação otimizada. Uma versão treinável acrescentaria o gradiente da perda em relação ao ângulo ou substituiria $u$ por matrizes de pesos ajustadas por retropropagação. A verificação deste artigo foi feita com MSVC 19.51, /std:c++23preview, /W4 e /permissive-.

6. Laboratório: reconstrução e utilidade disputam a reta

No laboratório, os pontos azuis e âmbar formam as duas classes; os pontos verdes são as reconstruções. Comece em $0^\circ$: a representação conserva a classe, mas descarta toda a variação vertical. Depois gire o gargalo até $90^\circ$. O MSE cai de $2{,}5$ para $0{,}5$, uma redução de $80\%$, enquanto a acurácia cai de $100\%$ para $50\%$. A maior variância venceu, exatamente como a Seção 2 previu. O controle de ruído permite observar quanto essa disputa muda quando corrompemos a entrada.

7. O custo físico do gargalo

Numa camada densa, o encoder calcula $Z=XW_e$ para um lote $X\in\mathbb{R}^{B\times D}$ e pesos $W_e\in\mathbb{R}^{D\times d}$. A operação é uma GEMM $(B\times D)(D\times d)$ com aproximadamente $2BDd$ FLOPs. Um decoder simétrico executa outra GEMM do mesmo tamanho, de modo que a passagem direta custa aproximadamente

\[4BDd\ \text{FLOPs},\]

sem contar vieses e ativações. A retropropagação acrescenta produtos matriciais da mesma ordem, mas seu multiplicador exato depende do compartilhamento de pesos, das ativações e do que a implementação conserva para o passo reverso.

Contemos um caso concreto. Para $B=256$, $D=28^2=784$ e $d=64$, cada GEMM executa $2\cdot256\cdot784\cdot64=25\,690\,112$ FLOPs. Encoder e decoder somam $51\,380\,224$ FLOPs na passagem direta. Sem compartilhar pesos, as duas matrizes e os dois vetores de viés totalizam

\[2(784\cdot64)+64+784=101\,200\]

parâmetros, ou $101\,200\cdot4/1024\approx395{,}3$ KiB em FP32.

Em CPUs, o exemplo de oito pontos é pequeno demais para justificar paralelismo; a sobrecarga dominaria o trabalho. No caso $256\times784$, bibliotecas BLAS conseguem explorar cache, SIMD e múltiplos núcleos. Na GPU, lotes maiores oferecem paralelismo suficiente para alimentar unidades matriciais, mas transferir lotes minúsculos ao dispositivo seria trocar cálculo por latência. A matemática da operação pertence a GEMM o Coração Matemático; aqui guardaremos a consequência: “latente menor” precisa ser traduzido em dimensões, FLOPs e tráfego, não tratado como sinônimo automático de treino barato.

8. O que atravessa o gargalo

Um autoencoder aprende a informação necessária para seu decoder, sob a distância, a corrupção e as restrições que escolhemos. A utilidade posterior da representação deve ser medida com uma sonda linear, vizinhos mais próximos, transferência ou uma tarefa do domínio. A perda de reconstrução não pode responder a uma pergunta que nunca recebeu.

No próximo artigo, congelaremos um autoencoder e treinaremos outro modelo dentro do espaço que ele definiu. A difusão latente reduz o custo ao abandonar o espaço de pixels durante a remoção de ruído, mas continua presa ao teto de informação que o decoder consegue devolver.

O gargalo não descobre sozinho o que importa. A perda decide o preço de esquecer, mesmo quando cobra pela coisa errada.

9. Acrônimos e Abreviações neste artigo

A seguir está a lista de todos os acrônimos e abreviações identificados no texto, organizados em ordem alfabética com o termo original em inglês e a tradução para o português:

Acrônimo / Abreviação Definição em Inglês Tradução em Português
BLAS Basic Linear Algebra Subprograms Subprogramas Básicos de Álgebra Linear
CPU / CPUs Central Processing Unit Unidade Central de Processamento
FLOPs Floating Point Operations Operações de Ponto Flutuante
FP32 32-bit Floating Point Ponto Flutuante de 32 bits
GEMM General Matrix Multiply Multiplicação Geral de Matrizes
GPU Graphics Processing Unit Unidade de Processamento Gráfico
IA Artificial Intelligence Inteligência Artificial
I-JEPA Image Joint-Embedding Predictive Architecture Arquitetura Preditiva de Incorporação Conjunta de Imagem
JEPA Joint-Embedding Predictive Architecture Arquitetura Preditiva de Incorporação Conjunta
KiB Kibibyte Kibibyte
MAE Masked Autoencoder Autocodificador Mascarado
MSE Mean Squared Error Erro Quadrático Médio
MSVC Microsoft Visual C++ Microsoft Visual C++
PCA Principal Component Analysis Análise de Componentes Principais
SIMD Single Instruction, Multiple Data Instrução Única, Múltiplos Dados
SimCLR Simple Framework for Contrastive Learning of Visual Representations Estrutura Simples para Aprendizado Contrastivo de Representações Visuais

Referências

BALDI, P.; HORNIK, K. Neural Networks and Principal Component Analysis: Learning from Examples Without Local Minima. Neural Networks, v. 2, n. 1, p. 53-58, 1989. Disponível em: https://doi.org/10.1016/0893-6080(89)90014-2. Acesso em: 28 jul. 2026.

HINTON, G. E.; SALAKHUTDINOV, R. R. Reducing the Dimensionality of Data with Neural Networks. Science, v. 313, n. 5786, p. 504-507, 2006. Disponível em: https://doi.org/10.1126/science.1127647. Acesso em: 28 jul. 2026.

VINCENT, P.; LAROCHELLE, H.; BENGIO, Y.; MANZAGOL, P.-A. Extracting and Composing Robust Features with Denoising Autoencoders. ICML, 2008. Disponível em: https://doi.org/10.1145/1390156.1390294. Acesso em: 28 jul. 2026.

(Updated: )