Mapas de Saliência

Visão geral

Mapas de saliência (saliency maps) são uma família de técnicas de atribuição (attribution) que visualizam quais partes de uma entrada mais influenciam a predição de um modelo. Para um classificador de imagens (image classifier), um mapa de saliência normalmente destaca pixels ou regiões influentes; para um classificador de processamento de linguagem natural (NLP), ele destaca tokens (ou pedaços de subpalavras (subword pieces)) influentes; para modelos tabulares (tabular models), ele destaca características (features) influentes.

A maioria dos métodos de saliência se enquadra em duas grandes categorias:

  • Baseados em gradiente (gradient-based): usam derivadas (derivatives) da saída de um modelo em relação à sua entrada (ou a ativações intermediárias (intermediate activations)).
  • Baseados em perturbação (perturbation-based): medem como as predições mudam quando partes da entrada são modificadas, mascaradas (masked) ou removidas.

Mapas de saliência são amplamente usados para depuração de modelos (model debugging), detecção de viés e de correlações espúrias (spurious-correlation detection) e comunicação do comportamento do modelo, mas têm ressalvas importantes: saturação (saturation), ruído (noise) e artefatos de fidelidade (faithfulness artifacts) podem fazer explicações parecerem plausíveis sem refletir o raciocínio real do modelo.

Este artigo foca em variantes comuns — gradientes básicos (vanilla gradients), suavização de gradientes (SmoothGrad), gradientes integrados (Integrated Gradients) e mapeamento de ativação de classe ponderado por gradiente (Grad-CAM) — e em como gerá-las, lê-las e avaliá-las na prática. Para um contexto mais amplo, veja Métodos de Atribuição e Pesquisa em Interpretabilidade.

Fundamentação teórica: por que gradientes indicam “importância”

Considere um modelo diferenciável (f(x)) que produz uma pontuação escalar para uma classe-alvo (c), frequentemente escrita (S_c(x)) (por exemplo, um logit antes da função softmax (softmax)). Uma aproximação de Taylor de primeira ordem em torno de uma entrada (x) fornece:

[ S_c(x + \Delta x) \approx S_c(x) + \nabla_x S_c(x)^\top \Delta x ]

O gradiente (\nabla_x S_c(x)) indica quão sensível a pontuação é a pequenas mudanças em cada dimensão de entrada. Intuitivamente:

  • uma magnitude grande (|\partial S_c / \partial x_i|) sugere que a dimensão (i) tem forte influência local,
  • o sinal indica se aumentar aquela entrada aumenta ou diminui a pontuação da classe (quando a entrada é significativa nessa direção).

Essa visão de “sensibilidade local” é poderosa, mas limitada: gradientes podem ser enganosos quando o modelo está saturado (saída quase plana), descontínuo na prática (por exemplo, linear por partes) ou quando “pequenas mudanças” não correspondem a mudanças semanticamente significativas (especialmente para entradas discretas como texto).

Duas grandes famílias de métodos de saliência

Atribuição baseada em gradiente

Esses métodos computam um mapa de atribuição a partir de derivadas, como:

  • Gradiente básico: (\text{attr}(x) = \nabla_x S_c(x)) (frequentemente visualizado como magnitude).
  • Gradiente × Entrada (Gradient × Input): (\text{attr}(x) = x \odot \nabla_x S_c(x)), o que às vezes reflete melhor a contribuição sob uma aproximação linear.
  • Gradientes integrados: integra gradientes ao longo de um caminho desde uma linha de base (baseline) até a entrada.

Métodos baseados em gradiente são rápidos (uma ou poucas passagens reversas (backward passes)) e escalam bem para modelos grandes.

Atribuição baseada em perturbação

Esses métodos medem mudanças na predição quando partes da entrada são modificadas:

  • Oclusão (occlusion) / mascaramento (masking) de patches em imagens
  • Remoção ou substituição de tokens em texto
  • Ablação de características (feature ablation) em modelos tabulares

Métodos por perturbação podem ser mais fundamentados semanticamente (eles “testam” o modelo), mas muitas vezes são mais lentos porque exigem muitas passagens diretas (forward passes) e uma escolha cuidadosa de perturbação que permaneça dentro da distribuição (on-distribution).

Variantes comuns de mapas de saliência

Gradientes básicos (saliência básica)

Definição

Dada uma pontuação de classe-alvo (S_c(x)), o mapa de saliência é:

[ \text{saliency}(x) = \left|\frac{\partial S_c(x)}{\partial x}\right| ]

Para imagens com canais, reduções comuns incluem:

  • máximo sobre canais: (\max_{ch} |\partial S/\partial x_{ch}|)
  • soma sobre canais: (\sum_{ch} |\partial S/\partial x_{ch}|)
  • norma L2 (L2 norm) sobre canais

Pontos fortes

  • Muito rápido: tipicamente uma passagem reversa
  • Fácil de implementar com Retropropagação

Pontos fracos

  • Frequentemente ruidoso e com aspecto de bordas
  • Pode falhar sob saturação: se a saída é plana em torno de (x), os gradientes podem ficar próximos de zero mesmo para características importantes
  • Sensível à escala de entrada e ao pré-processamento (normalização importa)

Suavização de gradientes (reduzir ruído do gradiente por média)

Ideia

Gradientes básicos podem ter alta variância. A suavização de gradientes calcula a média da saliência em cópias ruidosas da entrada:

[ \text{SmoothGrad}(x) = \frac{1}{N}\sum_{i=1}^N \left|\nabla_x S_c(x + \epsilon_i)\right|,\quad \epsilon_i \sim \mathcal{N}(0, \sigma^2) ]

Pontos fortes

  • Frequentemente produz mapas visualmente mais limpos
  • Ainda relativamente barato ((N) passagens reversas)

Pontos fracos

  • Mais suave não significa necessariamente mais fiel
  • A escolha da escala de ruído (\sigma) e do número de amostras (N) afeta os resultados

Gradientes integrados (lidar com saturação via integração ao longo de um caminho)

Motivação

Se os gradientes estão próximos de zero na entrada devido à saturação, olhar apenas para (\nabla_x S_c(x)) pode deixar de capturar características importantes. Gradientes integrados integra gradientes ao longo de um caminho de uma linha de base (x') (por exemplo, imagem preta, tokens de padding) até a entrada (x):

[ \text{IG}_i(x) = (x_i - x'i)\int{\alpha=0}^{1} \frac{\partial S_c(x' + \alpha(x-x'))}{\partial x_i}, d\alpha ]

Na prática, aproxime a integral com uma soma de Riemann (Riemann sum) em (m) passos.

Propriedade-chave: completude (completeness) Gradientes integrados satisfaz (sob condições típicas):

[ \sum_i \text{IG}_i(x) \approx S_c(x) - S_c(x') ]

Assim, as atribuições “somam” a mudança na pontuação desde a linha de base.

Pontos fortes

  • Frequentemente mais estável e significativo do que gradientes básicos
  • Mitiga alguns problemas de saturação
  • Tem um conjunto útil de axiomas teóricos (sensibilidade, invariância de implementação)

Pontos fracos

  • Exige escolher uma linha de base (pode mudar fortemente os resultados)
  • Custa múltiplas passagens reversas ((m) passos)
  • Linhas de base para texto e entradas de alta dimensionalidade podem ser difíceis e podem introduzir artefatos

Mapeamento de ativação de classe ponderado por gradiente (localização discriminativa por classe via mapas de características)

Gradientes básicos produzem mapas no espaço de pixels, mas podem ser ruidosos. O mapeamento de ativação de classe ponderado por gradiente gera um mapa de calor grosseiro usando gradientes que fluem para uma camada convolucional (convolutional layer) (ou qualquer camada de mapas espaciais de características).

Seja (A^k) o (k)-ésimo mapa de características (feature map) (formato (H \times W)) de uma camada convolucional escolhida. Calcule os pesos:

[ \alpha_k^c = \frac{1}{HW}\sum_{i=1}^H\sum_{j=1}^W \frac{\partial S_c}{\partial A^k_{ij}} ]

Então, o mapa é:

[ L^c_{\text{Grad-CAM}} = \text{ReLU}\left(\sum_k \alpha_k^c A^k\right) ]

A função ReLU (ReLU) mantém apenas características que influenciam positivamente a classe-alvo.

Pontos fortes

  • Frequentemente destaca regiões semanticamente significativas
  • Menos ruidoso do que gradientes em nível de pixel
  • Funciona bem para modelos de visão baseados em redes neurais convolucionais (CNNs)

Pontos fracos

  • Resolução mais baixa (vinculada ao tamanho do mapa de características)
  • Depende da escolha da camada
  • Não é diretamente definido para arquiteturas não convolucionais (embora existam variantes)

Relacionado: o mapeamento de ativação de classe ponderado por gradiente++ (Grad-CAM++) ajusta a ponderação para lidar melhor com múltiplas instâncias; o mapeamento de ativação de classe ponderado por gradiente guiado (guided Grad-CAM) combina o método com detalhes de alta frequência ao estilo de retropropagação guiada (guided backprop) (mas métodos guiados têm suas próprias preocupações de fidelidade).

Como gerar mapas de saliência na prática

Passo 1: escolher a saída-alvo

Decida o que você está explicando:

  • Classe predita no topo: explique “por que o modelo previu isso”
  • Classe específica: explique “evidência para a classe c”
  • Diferença de pontuações: às vezes é mais significativo (por exemplo, (S_c - S_{c'}))

Usar pontuações logit (logits) (pré-softmax) é comum porque probabilidades de softmax podem saturar e reduzir os gradientes.

Passo 2: escolher a representação de entrada

  • Imagens: tensor de pixels brutos após o pré-processamento; garanta requires_grad=True.
  • Texto: gradientes em relação a embeddings de tokens (token embeddings) (não IDs inteiros de token). Muitas bibliotecas computam gradientes nas saídas da camada de embeddings.

Passo 3: computar a atribuição e pós-processar

Etapas comuns de pós-processamento:

  • tomar valor absoluto ou separar atribuições positivas vs negativas
  • normalizar para [0, 1] para exibição (cuidado: a normalização pode ocultar diferenças de escala)
  • para imagens: sobrepor como um mapa de calor (heatmap) sobre a imagem original
  • para texto: colorir tokens pela magnitude da atribuição

Exemplo prático: saliência básica e suavização de gradientes (PyTorch, imagens)

Abaixo está um esboço mínimo para um classificador de imagens. Ele assume que você já tem um tensor de entrada x com formato [1, 3, H, W] e um modelo que produz logits.

import torch

def vanilla_saliency(model, x, class_idx=None):
    model.eval()
    x = x.clone().detach().requires_grad_(True)

    logits = model(x)  # [1, num_classes]
    if class_idx is None:
        class_idx = logits.argmax(dim=1).item()

    score = logits[0, class_idx]
    model.zero_grad(set_to_none=True)
    score.backward()

    # x.grad: [1, 3, H, W]
    sal = x.grad.detach().abs()
    sal = sal.max(dim=1).values  # reduce channels -> [1, H, W]
    return sal, class_idx

@torch.no_grad()
def add_noise(x, sigma):
    return x + sigma * torch.randn_like(x)

def smoothgrad(model, x, class_idx=None, n=25, sigma=0.1):
    model.eval()
    acc = 0
    for _ in range(n):
        xn = add_noise(x, sigma)
        sal, class_idx = vanilla_saliency(model, xn, class_idx=class_idx)
        acc = acc + sal
    return acc / n, class_idx

Observações

  • Escolha sigma em relação à sua escala de entrada (após a normalização).
  • Use logits em vez de probabilidades quando possível.
  • Se você normaliza imagens (por exemplo, média/desvio padrão do ImageNet), mantenha isso consistente — saliência é muito sensível ao pré-processamento.

Exemplo prático: gradientes integrados (implementação conceitual)

Uma aproximação simples de gradientes integrados ao longo do caminho em linha reta da linha de base x0 até a entrada x:

import torch

def integrated_gradients(model, x, x0, class_idx=None, steps=50):
    model.eval()
    x = x.clone().detach()
    x0 = x0.clone().detach()

    # Decide target class using the real input
    with torch.no_grad():
        logits = model(x)
        if class_idx is None:
            class_idx = logits.argmax(dim=1).item()

    total_grad = torch.zeros_like(x)

    for s in range(1, steps + 1):
        alpha = s / steps
        xs = (x0 + alpha * (x - x0)).requires_grad_(True)
        score = model(xs)[0, class_idx]
        model.zero_grad(set_to_none=True)
        score.backward()
        total_grad += xs.grad.detach()

    avg_grad = total_grad / steps
    ig = (x - x0) * avg_grad  # elementwise
    return ig, class_idx

Escolhas de linha de base (importante)

  • Visão: imagem preta, imagem borrada, ou a média do conjunto de dados; cada uma tem semânticas diferentes.
  • Texto: tokens de padding, tudo-[MASK], ou uma frase de referência neutra; cada uma pode introduzir mudança de distribuição.

Exemplo prático: saliência de tokens para um classificador Transformer (alto nível)

Para um modelo de Arquitetura Transformer, IDs de token são discretos, então tipicamente você computa gradientes em relação aos vetores de embedding (embedding vectors). Muitos toolkits expõem “gradiente na saída do embedding”. Os passos são:

  1. Execute uma passagem direta com output_hidden_states=True (ou capture as saídas de embeddings).
  2. Retropropague a partir do logit-alvo até as saídas de embeddings.
  3. Reduza os gradientes na dimensão de embedding a um único escore por token (por exemplo, norma L2 ou soma dos valores absolutos).

Um escore comum de atribuição por token é:

[ \text{attr(token)} = \left|\frac{\partial S_c}{\partial \text{emb(token)}}\right| ]

A interpretação continua delicada: gradientes capturam sensibilidade local no espaço de embedding, não necessariamente “importância” em um sentido causal.

Como ler mapas de saliência

Pense em “sensibilidade”, não em “explicação causal”

A maioria dos mapas de saliência responde: Se eu mudasse um pouco esta característica de entrada, como a pontuação mudaria? Isso não é o mesmo que: O modelo baseou sua decisão nesta característica em uma cadeia de raciocínio semelhante à humana?

Saliência é melhor tratada como evidência sobre o comportamento do modelo, não como uma explicação definitiva.

Significado das cores: sinalizado vs magnitude

  • Mapas apenas de magnitude mostram onde o modelo é sensível.
  • Mapas com sinal podem mostrar características que apoiam vs se opõem a uma classe (contribuições positivas vs negativas), mas o sinal pode ser difícil de interpretar para entradas normalizadas.

Comparações podem ser enganosas

  • Normalizar cada mapa de calor de forma independente pode fazer atribuições fracas parecerem fortes.
  • Comparar saliência entre modelos diferentes ou pipelines de pré-processamento diferentes é arriscado, a menos que você mantenha as escalas consistentes.

Principais armadilhas e modos de falha

Saturação (gradientes que desaparecem perto da entrada)

Em regiões saturadas (por exemplo, sigmoide perto de 0/1, platôs de probabilidade de softmax), gradientes podem ficar próximos de zero mesmo que características tenham sido cruciais. Esta é uma razão pela qual gradientes integrados foram introduzidos: ele “coleta” sinal de gradiente ao longo de um caminho onde o modelo pode não estar saturado.

Observe também: “mascaramento de gradiente (gradient masking)” (acidental ou intencional) pode suprimir gradientes e fazer mapas de saliência parecerem pouco informativos ou enganosos.

Ruído e instabilidade

Gradientes básicos podem mudar significativamente sob:

  • perturbações minúsculas na entrada,
  • sementes aleatórias (random seeds) diferentes (com dropout (dropout) ou componentes estocásticos),
  • pequenas mudanças de pré-processamento.

A suavização de gradientes reduz ruído visual, mas também pode borrar e pode criar a ilusão de robustez sem aumentar a fidelidade.

Artefatos de fidelidade (explicações plausíveis, mas incorretas)

Um alerta clássico: alguns métodos de saliência podem produzir mapas com aparência semelhante mesmo quando os pesos do modelo são randomizados. Isso sugere que os mapas podem refletir vieses arquiteturais (por exemplo, tendências à detecção de bordas) em vez de raciocínio aprendido.

Uma abordagem amplamente citada é a ideia de verificações de sanidade (sanity checks): se você randomiza parâmetros do modelo ou rótulos e as explicações não mudam muito, o método de explicação pode não ser fiel.

Dependência da linha de base (gradientes integrados)

Gradientes integrados pode variar dramaticamente com base em (x'). Uma linha de base preta para imagens pode estar fora da distribuição; uma linha de base toda-[PAD] para texto pode criar um comportamento estranho de atenção/ativação. Se a linha de base for irrealista, gradientes integrados pode atribuir importância a características que “preenchem a lacuna” até uma referência não natural.

Mitigações práticas:

  • Teste múltiplas linhas de base e verifique estabilidade.
  • Use linhas de base que sejam semanticamente plausíveis para o seu domínio (por exemplo, imagem borrada, texto neutro).
  • Relate explicitamente a escolha de linha de base.

Incompatibilidade de resolução e escolha de camada (mapeamento de ativação de classe ponderado por gradiente)

O mapeamento de ativação de classe ponderado por gradiente destaca regiões na resolução espacial de um mapa de características escolhido; se esse mapa for (7 \times 7), o mapa de calor é inerentemente grosseiro. Diferentes escolhas de camada podem gerar explicações diferentes.

Entradas discretas e perturbações fora da variedade

Para texto, “pequenas mudanças” no espaço de embedding podem não corresponder a edições válidas. Para métodos baseados em perturbação, mascarar tokens pode criar entradas não naturais, e a resposta do modelo pode ser dominada por mudança de distribuição em vez da “remoção” pretendida de evidência.

Viés de confirmação humano

Mapas de calor são persuasivos. Pessoas tendem a confiar demais em destaques “com aparência razoável”, mesmo quando não estão causalmente ligados à predição. Trate saliência como um sinal de diagnóstico e corrobore com testes quantitativos.

Avaliando mapas de saliência (verificações de qualidade)

Mapas de saliência são fáceis de gerar, mas difíceis de validar. Abordagens comuns incluem:

  • Verificações de sanidade: verifique se as explicações mudam quando o modelo é randomizado ou treinado com rótulos aleatórios.
  • Métricas de deleção / inserção (deletion / insertion metrics): remova (mascare) os pixels/tokens mais salientes e veja quão rapidamente a confiança do modelo cai; ou adicione as partes salientes de volta e veja a confiança subir.
  • Testes de oclusão: para imagens, oclua sistematicamente patches e compare quedas preditas com a saliência.
  • Benchmarks de localização: quando existem regiões de verdade-terreno (por exemplo, caixas delimitadoras), meça sobreposição. Tenha cautela: “região correta” não garante o raciocínio interno correto.

Nenhuma métrica isolada é definitiva; combine inspeção qualitativa com pelo menos uma verificação quantitativa de fidelidade.

Aplicações práticas

Depuração de modelos e problemas no conjunto de dados

  • Detectar atalhos (por exemplo, o modelo focando em marcas d’água, bordas ou fundos em vez do objeto).
  • Identificar correlações espúrias e vazamento nos dados de treinamento.

Fluxos de trabalho de segurança e conformidade (com cautela)

Mapas de saliência podem apoiar processos internos de revisão, mas raramente são suficientes para garantias de alto risco. Use-os junto com:

  • avaliação robusta,
  • testes contrafactuais (counterfactual),
  • auditorias de viés,
  • e (quando apropriado) modelos substitutos interpretáveis (interpretable surrogate models).

Imagens científicas e médicas

Métodos no estilo de mapeamento de ativação de classe ponderado por gradiente são populares para destacar regiões em radiologia ou microscopia. No entanto, mudança de distribuição e confundimento são comuns; saliência deve ser acompanhada de validação rigorosa.

Prompting e análise em PLN

Saliência de tokens pode revelar quando um classificador depende de palavras-chave específicas, negações ou artefatos de formatação — útil para depurar injeção de prompt (prompt injection) e para análise de sensibilidade.

Quando usar mapas de saliência vs outras ferramentas de interpretabilidade

Mapas de saliência são uma boa opção quando você precisa de:

  • insight rápido, por exemplo individual,
  • uma localização aproximada de evidência em imagens,
  • uma ferramenta de depuração de primeira passada.

Considere alternativas ou complementos quando você precisa de:

  • entendimento global em um conjunto de dados (por exemplo, resumos de importância de características),
  • insight mecanístico sobre representações internas (veja Visualização de Características),
  • explicações causais ou contrafactuais (saliência por si só não é causal),
  • explicações para pipelines não diferenciáveis (métodos baseados em perturbação podem ser melhores).

Para uma taxonomia mais ampla e métodos relacionados, veja Métodos de Atribuição.

Resumo

  • Gradientes básicos são os mapas de saliência mais simples: rápidos, mas frequentemente ruidosos e propensos a problemas de saturação.
  • Suavização de gradientes calcula a média de gradientes em entradas ruidosas: visuais mais limpos, mas sem garantia de maior fidelidade.
  • Gradientes integrados integra gradientes a partir de uma linha de base: ajuda com saturação e tem axiomas úteis, mas a escolha da linha de base importa.
  • Mapeamento de ativação de classe ponderado por gradiente usa gradientes sobre mapas de características convolucionais: frequentemente produz regiões semanticamente significativas, mas é grosseiro e dependente da camada.
  • Mapas de saliência são melhor usados como diagnósticos, validados com verificações de sanidade e testes de fidelidade baseados em perturbação, e interpretados com cautela — especialmente em domínios de alto risco.