Saliency och attribution
Kunna beräkna gradientbaserad attribution och känna till dess brister.
Förkunskaper
Intuition
Attribution svarar på: vilka delar av indata påverkade utdata mest?
| Metod | Idé | Problem |
|---|---|---|
| Vanilla saliency | ∂output/∂input | |
| Input × Gradient | gradienten viktad med indata | fortfarande brusig |
| Integrated Gradients | integrera gradienten längs en väg från en baslinje | kräver val av baslinje |
| Grad-CAM | vikta sista faltningslagrets aktiveringskartor | bara för CNN, grov upplösning |
| SHAP | Shapley-värden, axiomatiskt grundade | dyrt, approximeras i praktiken |
Integrated Gradients är ofta förstahandsvalet för att den uppfyller två rimliga axiom: completeness (attributionerna summerar till skillnaden mot baslinjen) och sensitivity.
Formellt
där är en baslinje (svart bild, nollvektor, genomsnittlig indata). Integralen approximeras med 20–300 steg.
Baslinjevalet är inte neutralt: en svart bild ger noll attribution åt svarta pixlar — som därmed osynliggörs. För text används ofta en sekvens av padding-tokens, vilket har samma problem.
Sanity checks (Adebayo m.fl. 2018) — kör alltid dessa:
- Modellrandomisering: slumpa modellens vikter lager för lager. En giltig attributionsmetod ska ge helt annorlunda kartor. Flera populära metoder gör inte det — de producerar i princip kantdetektion oavsett modell.
- Etikettrandomisering: träna om modellen på slumpmässiga etiketter. Attributionerna ska förändras.
En metod som klarar båda är åtminstone kopplad till modellen. En som inte gör det visar något om bilden, inte om beslutet.
Praktisk konsekvens: använd attribution för att generera hypoteser («modellen verkar titta på bakgrunden»), och verifiera sedan med intervention («maskera bakgrunden och mät»). Aldrig som slutgiltig förklaring — och aldrig som juridiskt underlag.
Kod
import torch
def integrated_gradients(modell, x, target, baslinje=None, steg=64):
baslinje = torch.zeros_like(x) if baslinje is None else baslinje
alfas = torch.linspace(0, 1, steg).view(-1, *([1] * x.dim()))
vag = baslinje + alfas * (x - baslinje) # (steg, ...)
vag.requires_grad_(True)
ut = modell(vag)[:, target].sum()
grad = torch.autograd.grad(ut, vag)[0]
medelgrad = grad.mean(dim=0)
ig = (x - baslinje) * medelgrad
# completeness-kontroll: summan ska ≈ f(x) − f(baslinje)
with torch.no_grad():
diff = (modell(x[None])[0, target] - modell(baslinje[None])[0, target]).item()
return ig, {"summa_ig": ig.sum().item(), "f_diff": diff}
ig, kontroll = integrated_gradients(modell, bild, target=klass)
print(kontroll) # {'summa_ig': 3.81, 'f_diff': 3.94} ← nära = approximationen räcker
Completeness-kontrollen är gratis och avslöjar direkt om antalet steg är för litet.
Behärskning innebär
- Beräknar gradientbaserad attribution
- Känner till metodernas brister
- Använder sanity checks
Logga in för att göra övningarna och bygga upp din behärskning.
Källor
- arXiv — Axiomatic Attribution for Deep Networks (Integrated Gradients) — arXiv (öppen åtkomst; licens per artikel)
- arXiv — Sanity Checks for Saliency Maps — arXiv (öppen åtkomst; licens per artikel)