Perda de Entropia Cruzada

O que é a perda de entropia cruzada (e por que ela é usada)

Perda de entropia cruzada (cross-entropy loss) mede quão bem a distribuição de probabilidades prevista por um modelo corresponde à distribuição verdadeira dos rótulos. Ela é a perda padrão para classificação probabilística (probabilistic classification) e também é o objetivo central em modelagem de linguagem (language modeling) (predição do próximo token (token)).

Intuitivamente:

  • Se o modelo atribui alta probabilidade ao rótulo correto, a perda é pequena.
  • Se ele atribui baixa probabilidade ao rótulo correto, a perda cresce rapidamente (logaritmicamente), penalizando fortemente erros confiantes.

A entropia cruzada está fortemente conectada a:

  • Log-verossimilhança negativa (negative log-likelihood, NLL): a entropia cruzada é NLL quando o alvo é um rótulo one-hot.
  • Estimação de máxima verossimilhança (maximum likelihood estimation, MLE): minimizar a entropia cruzada é equivalente a maximizar a verossimilhança dos dados observados.
  • Divergência de Kullback–Leibler (KL divergence): a entropia cruzada difere da divergência KL apenas por uma constante que não depende do modelo.

Essas conexões são o que tornam a entropia cruzada o objetivo “padrão” em muitas configurações de treinamento de redes neurais usando Descida do Gradiente (Gradient Descent) e Retropropagação (Backpropagation).

Fundamentos teóricos

Entropia e entropia cruzada

Seja (p(y)) a distribuição verdadeira sobre rótulos (y), e (q(y)) a distribuição prevista pelo modelo.

  • Entropia de (p): [ H(p) = -\sum_y p(y)\log p(y) ]

  • Entropia cruzada de (p) em relação a (q): [ H(p, q) = -\sum_y p(y)\log q(y) ]

A entropia cruzada pergunta: quantos “nats” (ou bits) seriam necessários para codificar amostras de (p) usando um código otimizado para (q)? Quanto melhor (q) corresponder a (p), menor a entropia cruzada.

Relação com a divergência KL

A divergência KL de (p) para (q) é: [ D_{\mathrm{KL}}(p|q) = \sum_y p(y)\log\frac{p(y)}{q(y)} ]

Uma identidade fundamental: [ H(p, q) = H(p) + D_{\mathrm{KL}}(p|q) ]

Como (H(p)) não depende do modelo (q), minimizar a entropia cruzada (H(p, q)) é equivalente a minimizar (D_{\mathrm{KL}}(p|q)). Em outras palavras, treinar com entropia cruzada empurra a distribuição do modelo na direção da distribuição-alvo.

Essa visão de “correspondência de distribuições” é especialmente útil para entender a entropia cruzada com alvos suaves (soft targets) (por exemplo, suavização de rótulos, destilação), não apenas rótulos one-hot.

Entropia cruzada como log-verossimilhança negativa (NLL)

Em classificação supervisionada, normalmente tratamos rótulos como amostras de uma distribuição categórica (categorical distribution).

Se o rótulo de verdade é uma única classe (y) (e não uma distribuição completa), a distribuição-alvo é one-hot (one-hot):

[ p(y'=k)=\mathbb{1}[k=y] ]

Então a entropia cruzada se torna: [ H(p,q) = -\log q(y) ]

Isso é exatamente a log-verossimilhança negativa (NLL) da classe correta sob o modelo. Fazendo a média em um conjunto de dados (dataset) ({(x_i, y_i)}):

[ \mathcal{L} = -\frac{1}{N}\sum_{i=1}^N \log q_\theta(y_i \mid x_i) ]

É por isso que muitas bibliotecas chamam a perda de classificação de “entropia cruzada”, enquanto o cálculo subjacente é “NLL”.

Entropia cruzada e treinamento por máxima verossimilhança (MLE)

Minimizar a entropia cruzada corresponde à estimação de máxima verossimilhança:

  • Verossimilhança do conjunto de dados: [ \prod_{i=1}^N q_\theta(y_i\mid x_i) ]

  • Log-verossimilhança: [ \sum_{i=1}^N \log q_\theta(y_i\mid x_i) ]

  • Log-verossimilhança negativa (para minimizar): [ -\sum_{i=1}^N \log q_\theta(y_i\mid x_i) ]

Assim, treinar um classificador com entropia cruzada é “apenas” treinamento por máxima verossimilhança de um modelo probabilístico condicional.

Esse enquadramento se torna importante em cenários como:

  • probabilidades calibradas (calibrated probabilities)
  • estimação de incerteza (uncertainty estimation)
  • modelagem de linguagem (verossimilhança do texto sob o modelo)

Variantes comuns

Entropia cruzada binária (binary cross-entropy, BCE)

Use entropia cruzada binária para:

  • classificação binária (duas classes)
  • classificação multirrótulo (multi-label) (sim/não independentes por rótulo)

Seja (y\in{0,1}) e o modelo prevê a probabilidade (p = q(y=1\mid x)). A BCE é:

[ \mathcal{L}_{\text{BCE}}(y,p) = -\left[y\log p + (1-y)\log(1-p)\right] ]

Comumente, (p = \sigma(z)) onde (z) é um logit (logit) (escore de valor real) e (\sigma) é a Função Sigmoide (Sigmoid Function).

Nota prática: multirrótulo vs multiclasse (multiclass)

  • Multirrótulo: múltiplos rótulos podem ser 1 simultaneamente → use BCE independentemente por rótulo.
  • Multiclasse: exatamente uma classe é correta entre (K) → use entropia cruzada com softmax (abaixo).

Entropia cruzada multiclasse (softmax)

Use entropia cruzada com softmax (softmax cross-entropy) para classificação de rótulo único em (K) classes.

Dado um vetor de logits (z \in \mathbb{R}^K), a distribuição do modelo é:

[ q(k\mid x)=\text{softmax}(z)k = \frac{e^{z_k}}{\sum{j=1}^K e^{z_j}} ]

Para um rótulo one-hot (y), a perda é: [ \mathcal{L} = -\log q(y\mid x) ]

Isso costuma ser implementado como log-softmax + NLL, porque é numericamente estável e conveniente.

Um pequeno exemplo numérico (multiclasse)

Suponha 3 classes e que o modelo produza probabilidades:

  • (q = [0.70, 0.20, 0.10])

Se a classe verdadeira é a classe 0:

  • perda (= -\log(0.70) \approx 0.357)

Se a classe verdadeira é a classe 2:

  • perda (= -\log(0.10) \approx 2.303)

O modelo é penalizado muito mais quando atribui baixa probabilidade à classe verdadeira.

Gradientes: por que “softmax + entropia cruzada” é tão comum

Um grande motivo prático para a ubiquidade da entropia cruzada é que o gradiente é limpo.

Seja (p = \text{softmax}(z)) e seja (y) um vetor one-hot. O gradiente da perda em relação aos logits é:

[ \frac{\partial \mathcal{L}}{\partial z} = p - y ]

Essa forma simples é numericamente estável e funciona bem com Retropropagação, especialmente em Redes Neurais (Neural Networks) profundas. Ela também ajuda a explicar a dinâmica do treinamento: o modelo aumenta o logit da classe correta e diminui os demais proporcionalmente às suas probabilidades previstas.

Detalhes de implementação que importam na prática

Logits vs probabilidades

A maioria dos frameworks (frameworks) modernos espera logits, não probabilidades, em funções de entropia cruzada.

Por que logits?

  • Evita calcular softmax/sigmoide explicitamente e depois tirar log (o que pode causar subfluxo).
  • Permite implementações fundidas e estáveis usando o truque log-soma-exp (log-sum-exp trick).

Padrões comuns:

  • Multiclasse: passe logits para uma CrossEntropyLoss que internamente faz log_softmax + NLL.
  • Binária/multirrótulo: passe logits para uma BCEWithLogitsLoss que internamente faz sigmoide + BCE estável.

Estabilidade numérica: truque log-soma-exp

Calcular ingenuamente: [ \log\left(\sum_j e^{z_j}\right) ] pode estourar se alguns (z_j) forem grandes.

Uma abordagem estável: [ \log\left(\sum_j e^{z_j}\right) = m + \log\left(\sum_j e^{z_j - m}\right), \quad m=\max_j z_j ]

Então: [ -\log \text{softmax}(z)_y = -z_y + \log\left(\sum_j e^{z_j}\right) ] é computado de forma estável.

Exemplos práticos de código

PyTorch: entropia cruzada multiclasse (logits entram, índice de classe sai)

import torch
import torch.nn.functional as F

logits = torch.tensor([[2.0, 0.5, -1.0]])  # shape: [batch, classes]
targets = torch.tensor([0])                # class indices

loss = F.cross_entropy(logits, targets)    # stable: log_softmax + NLL
loss.backward()

Notas:

  • targets são índices inteiros de classe, não vetores one-hot (a menos que você use opções especiais).
  • F.cross_entropy espera logits não normalizados.

PyTorch: BCE binária / multirrótulo com logits

import torch
import torch.nn.functional as F

logits = torch.tensor([[1.2, -0.7, 0.1]])      # [batch, labels]
targets = torch.tensor([[1.0, 0.0, 1.0]])      # multi-label targets in {0,1}

loss = F.binary_cross_entropy_with_logits(logits, targets)
loss.backward()

Esta é a escolha padrão para classificação multirrótulo em que cada rótulo é uma Bernoulli independente.

Redução, mascaramento e preenchimento

Funções de perda geralmente permitem controlar como as perdas por exemplo são agregadas:

  • mean: média sobre o lote (padrão comum)
  • sum: soma sobre o lote (útil quando você mesmo faz a normalização)
  • none: retorna a perda por item (útil para ponderação/mascaramento)

Em modelos de sequência (por exemplo, modelagem de linguagem), normalmente você precisa ignorar tokens de preenchimento (padding tokens):

  • frameworks frequentemente fornecem ignore_index (por exemplo, -100) para que posições preenchidas não contribuam para a perda.

Desbalanceamento de classes e ponderação

A entropia cruzada pode ser adaptada para conjuntos de dados com desbalanceamento de classes (class imbalance):

  • pesos de classe (class weights) em CE multiclasse (aumenta o peso de classes raras)
  • ponderação da classe positiva (positive class weighting) em BCE (pos_weight no PyTorch) para aumentar o peso dos positivos

Essas são baselines simples, mas eficazes, antes de migrar para perdas especializadas (por exemplo, perda focal).

Suavização de rótulos

Suavização de rótulos (label smoothing) substitui alvos one-hot por uma distribuição levemente suavizada, por exemplo:

  • classe correta: (1-\varepsilon)
  • demais: (\varepsilon/(K-1))

Isso pode melhorar a generalização e a calibração ao desencorajar previsões excessivamente confiantes. Conceitualmente, transforma o treinamento em minimizar a entropia cruzada contra uma distribuição-alvo não degenerada, tornando a interpretação via divergência KL especialmente relevante.

(Ver também: Suavização de Rótulos.)

Usos típicos

Classificação

A entropia cruzada é o padrão para:

  • classificação de imagens (CE com softmax)
  • classificação de texto (CE com softmax)
  • classificação binária (BCE)
  • rotulagem multirrótulo (BCE)

Ela combina naturalmente com:

Modelagem de linguagem e predição do próximo token

Modelos de linguagem modernos normalmente são treinados minimizando a entropia cruzada em nível de token (token-level cross-entropy):

Dada uma sequência de tokens (x_1, x_2, \dots, x_T), o modelo prevê: [ q(x_t \mid x_{<t}) ] e o treinamento minimiza: [ -\sum_{t=1}^T \log q(x_t \mid x_{<t}) ] (normalmente com média sobre tokens e lotes, excluindo preenchimento).

Uma métrica derivada comum é a perplexidade (perplexity), definida como: [ \text{ppl} = \exp(\text{average cross-entropy}) ] A perplexidade é interpretável como o “fator efetivo de ramificação”: quanto menor, melhor.

Ver também: Modelagem de Linguagem.

Quando a entropia cruzada *não* é a escolha certa

A entropia cruzada assume que seu modelo produz uma distribuição de probabilidade e que você quer fazê-la corresponder a rótulos/distribuições-alvo. Alternativas podem ser melhores quando:

  • você se importa com métricas de ranqueamento (por exemplo, recuperação) em vez de probabilidades calibradas
  • as saídas são contínuas (use perdas de regressão)
  • desbalanceamento extremo de classes (considere perdas ponderadas ou perda focal)
  • predição estruturada (structured prediction) com restrições complexas (pode usar campos aleatórios condicionais (conditional random fields, CRFs) ou objetivos em nível de sequência (sequence-level objectives))

Ainda assim, a entropia cruzada costuma ser o ponto de partida porque é fundamentada (MLE/KL) e fácil de otimizar.

Armadilhas comuns e boas práticas

  • Use funções de perda baseadas em logits (CrossEntropyLoss, BCEWithLogitsLoss) em vez de aplicar softmax/sigmoide por conta própria.
  • Garanta que o formato do alvo corresponde à perda:
    • CE multiclasse: índice inteiro de classe (ou alvos suaves devidamente normalizados)
    • BCE: alvos float em ([0,1]) por rótulo
  • Masque tokens de preenchimento em tarefas de sequência para evitar treinar em posições sem significado.
  • Fique atento ao desbalanceamento de classes; adicione pesos se necessário.
  • Interprete a magnitude corretamente: entropia cruzada está em “nats” (log na base (e)) a menos que você use log na base 2 (bits). Frameworks tipicamente usam logaritmos naturais.

Resumo

A perda de entropia cruzada é o objetivo padrão para classificação probabilística e modelagem de linguagem porque tem uma base teórica limpa e excelente comportamento prático:

  • Ela é o valor esperado da log-probabilidade negativa atribuída aos rótulos verdadeiros.
  • Para rótulos one-hot, ela equivale à log-verossimilhança negativa, então minimizá-la é treinamento por máxima verossimilhança.
  • Ela se decompõe em entropia + divergência KL, então minimizá-la alinha a distribuição do modelo com a distribuição-alvo.
  • Na prática, ela é implementada sobre logits usando operações numericamente estáveis (log-soma-exp), e funciona especialmente bem com saídas softmax/sigmoide.

Para a maioria dos problemas de classificação em aprendizado profundo (deep learning), a entropia cruzada é a primeira perda a tentar — e muitas vezes é a última de que você precisa.