SimCLR: Aprender por Contraste e Pagar pelos Negativos

por Frank de Alcantara em 28/07/2026

SimCLR: Aprender por Contraste e Pagar pelos Negativos

Mostremos à rede duas fotografias do mesmo cão: uma recortada, outra desfocada e com as cores alteradas. Depois mostremos a fotografia de outro cão. Se a representação aproximar as duas primeiras e afastar a terceira, talvez tenha aprendido algo sobre identidade visual. Talvez tenha aprendido apenas nossa escolha de recortes e cores. O SimCLR é interessante justamente porque transforma essa ambiguidade numa tarefa precisa.

O autoencoder organiza um latente para reconstrução. A difusão latente organiza um espaço para geração. O SimCLR abandona ambos os contratos. Em vez de perguntar “consigo refazer a entrada?”, pergunta “duas transformações da mesma imagem chegam ao mesmo lugar, e imagens diferentes permanecem separadas?”. Não há decoder de pixels. Há geometria, temperatura e um lote cheio de adversários involuntários.

1. Duas views definem o positivo

Para cada imagem $x_k$, sorteamos duas transformações $t$ e $t’$ de uma família $\mathcal{T}$:

\[\tilde{x}_{2k}=t(x_k),\qquad \tilde{x}_{2k+1}=t'(x_k).\]

Essas duas views formam um par positivo. As views de outras imagens no lote funcionam como negativos. Com $B$ imagens, o modelo processa $2B$ entradas.

O encoder $f$ produz uma representação $h_i=f(\tilde{x}_i)$. Um pequeno projection head $g$ produz

\[z_i=g(h_i).\]

A perda atua sobre $z_i$, enquanto tarefas posteriores usam $h_i$. O SimCLR mostrou empiricamente que essa separação melhora a representação utilizada depois. O cabeçalho absorve parte da pressão específica da tarefa contrastiva e é descartado ao final.

2. Aumentos são uma declaração de invariância

Recorte, redimensionamento, distorção de cor e borramento não são decoração. Ao declarar duas transformações como positivas, dizemos que a representação deve aproximá-las.

Se remover cor não muda a classe relevante, a invariância ajuda. Se a cor determina o diagnóstico de uma lâmina médica, a mesma transformação pode apagar o sinal. O artigo do SimCLR encontra uma composição forte de recorte e distorção de cor para imagens naturais; isso é evidência naquele domínio, não uma lei que atravessa EEG, áudio e sensoriamento remoto sem revisão.

Uma tarefa autossupervisionada sempre contém conhecimento humano, ainda que nenhum rótulo de classe apareça. Aqui ele mora em $\mathcal{T}$.

3. NT-Xent, símbolo por símbolo

Normalizamos $z_i$ e medimos similaridade de cosseno:

\[s_{ij}= \frac{z_i^\top z_j}{\lVert z_i\rVert_2\lVert z_j\rVert_2}.\]

Para uma âncora $i$ e seu positivo $j$, a perda é

\[\ell_{i,j} =-\log \frac{\exp(s_{ij}/\tau)} {\sum_{k=0}^{2B-1}\mathbf{1}_{[k\ne i]}\exp(s_{ik}/\tau)},\]

na qual $\tau>0$ é a temperatura. O denominador contém um positivo e $2B-2$ negativos. A perda final mede as duas direções de cada par.

Essa é a NT-Xent, de normalized temperature-scaled cross entropy (entropia cruzada normalizada e escalada por temperatura), uma forma de InfoNCE. A derivação de InfoNCE aplicada a texto e o laboratório de geometria vivem em Do Cosseno à Borda. Aqui a proprietária é a tarefa visual: aumentos, duas views e custo do lote.

4. Temperatura transforma margem em pressão

Considere similaridade positiva $s_+=0{,}7$, negativos com $s_-=0{,}2$, lote $B=64$ e $\tau=0{,}1$. A razão entre a exponencial positiva e cada negativa é

\[\exp\left(\frac{s_+-s_-}{\tau}\right)=e^5\approx148.\]

Parece confortável, mas existem $2B-2=126$ negativos. Sob a simplificação de que todos possuem o mesmo $s_-$, a probabilidade do positivo é

\[p_+=\frac{e^{s_+/\tau}} {e^{s_+/\tau}+126e^{s_-/\tau}} \approx0{,}54,\]

e a perda permanece perto de $0{,}62$. Um único negativo é fraco; uma multidão soma.

Temperatura baixa concentra gradiente nos negativos difíceis. Baixá-la demais pode tornar a otimização sensível a pequenas diferenças e falsos negativos.

5. O custo quadrático

As $2B$ representações formam uma matriz de similaridades

\[S=ZZ^\top\in\mathbb{R}^{2B\times2B}.\]

Ela contém $4B^2$ entradas. Com $B=4096$, são $8192^2=67\,108\,864$ similaridades. Em FP32, somente essa matriz ocupa cerca de $256$ MiB, antes de gradientes, ativações e comunicação entre dispositivos.

A GEMM custa aproximadamente

\[2(2B)^2D=8B^2D\]

FLOPs para representações de dimensão $D$. Distribuir o lote exige reunir negativos entre GPUs ou usar mecanismos alternativos, como fila e momentum encoder no MoCo. O SimCLR simplifica a arquitetura, mas paga em lote e duração de treino.

6. Falsos negativos

O denominador presume que outras imagens são incompatíveis. Duas fotografias de cães diferentes podem compartilhar semântica útil e ainda serem afastadas. Esse é um falso negativo.

O problema não significa que a perda falha sempre. Em lotes grandes e dados diversos, a pressão global ainda pode organizar boas representações. Significa que a supervisão criada pelo lote contém erros estruturais e que aumentar $B$ oferece mais negativos e mais oportunidades de incluir parentes semânticos.

O contraste com negative sampling no SkipGram também merece precisão. Ambos amostram eventos negativos, mas os objetos, distribuições e objetivos são diferentes. No SimCLR, as outras views do lote entram numa classificação contrastiva por âncora.

7. NT-Xent em C++23

O programa calcula a perda de uma âncora. Os vetores já estão normalizados; por isso, o produto interno é o cosseno.

#include <algorithm>
#include <array>
#include <cmath>
#include <cstddef>
#include <iostream>
#include <span>
#include <stdexcept>
#include <vector>

double dot(
    const std::span<const double> a,
    const std::span<const double> b) {
    if (a.size() != b.size()) {
        throw std::invalid_argument("dimensões incompatíveis");
    }

    double result = 0.0;
    for (std::size_t d = 0; d < a.size(); ++d) {
        result += a[d] * b[d];
    }
    return result;
}

double ntxent_anchor(
    const std::span<const std::array<double, 2>> embeddings,
    const std::size_t anchor,
    const std::size_t positive,
    const double temperature) {
    if (embeddings.size() < 2 || anchor >= embeddings.size()
        || positive >= embeddings.size() || anchor == positive
        || temperature <= 0.0) {
        throw std::invalid_argument("par contrastivo inválido");
    }

    std::vector<double> logits(embeddings.size());
    for (std::size_t i = 0; i < embeddings.size(); ++i) {
        logits[i] = i == anchor
            ? -1e30
            : dot(embeddings[anchor], embeddings[i]) / temperature;
    }
    const double maximum =
        *std::max_element(logits.begin(), logits.end());
    double denominator = 0.0;
    for (const double logit : logits) {
        denominator += std::exp(logit - maximum);
    }
    return -(logits[positive] - maximum - std::log(denominator));
}

int main() {
    const std::array<std::array<double, 2>, 4> z{{
        {1.0, 0.0}, {0.8, 0.6}, {-1.0, 0.0}, {-0.8, -0.6}
    }};
    const double forward = ntxent_anchor(z, 0, 1, 0.1);
    const double reverse = ntxent_anchor(z, 1, 0, 0.1);
    std::cout << "perda simétrica do primeiro par="
              << 0.5 * (forward + reverse) << '\n';
}

Em produção, normalizamos uma matriz inteira, calculamos $ZZ^\top$ por GEMM e aplicamos uma entropia cruzada com os índices dos positivos. O código escalar serve para verificar o índice excluído e a simetria, dois lugares onde implementações erradas continuam produzindo perdas que diminuem com grande serenidade.

No MSVC 19.51, compilamos com cl /std:c++latest /permissive- /W4 /EHsc /utf-8 /O2 simclr.cpp. A saída é aproximadamente 1.27765e-07. Ela é tão pequena porque o positivo possui cosseno $0{,}8$, enquanto os dois negativos possuem $-1$ e $-0{,}8$; com $\tau=0{,}1$, a separação é enorme. O exemplo verifica a função. A Seção 4, com 126 negativos moderados, mostra por que um lote real raramente oferece esse sossego.

8. Laboratório: a multidão no denominador

Altere lote, temperatura e similaridades. A barra verde é a probabilidade do positivo; a vermelha agrega todos os negativos. Observe que aumentar $B$ pode elevar a perda sem mudar a geometria de nenhum par.

9. O que fica quando retiramos os negativos

SimCLR mostra que uma tarefa de comparação simples, aumentos fortes e um cabeçalho não linear aprendem representações competitivas. Também deixa duas contas: $O(B^2)$ em similaridades e uma dependência forte da transformação que define o positivo.

O próximo artigo retirará os negativos. O BYOL manterá duas views, mas colocará uma rede online diante de um alvo lento e pedirá que um preditor case suas representações. A perda ficará simples; o problema do colapso, não.

Os negativos impedem que todos ocupem o mesmo ponto. Retirá-los exige outra razão para o espaço permanecer aberto.

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

CHEN, T.; KORNBLITH, S.; NOROUZI, M.; HINTON, G. A Simple Framework for Contrastive Learning of Visual Representations. ICML, 2020. Disponível em: https://proceedings.mlr.press/v119/chen20j.html. Acesso em: 28 jul. 2026.

HE, K.; FAN, H.; WU, Y.; XIE, S.; GIRSHICK, R. Momentum Contrast for Unsupervised Visual Representation Learning. CVPR, 2020. Disponível em: https://openaccess.thecvf.com/content_CVPR_2020/html/He_Momentum_Contrast_for_Unsupervised_Visual_Representation_Learning_CVPR_2020_paper.html. Acesso em: 28 jul. 2026.

OORD, A. van den; LI, Y.; VINYALS, O. Representation Learning with Contrastive Predictive Coding. 2018. Disponível em: https://arxiv.org/abs/1807.03748. Acesso em: 28 jul. 2026.

(Updated: )