Adversariella exempel
Kunna generera adversariella störningar och förklara vad de avslöjar om modeller.
Förkunskaper
Intuition
Ta en bild som klassas som «panda» med 58 % säkerhet. Lägg till en störning som är osynlig för ögat — varje pixel ändras med högst 1/255. Nu klassas den som «gibbon» med 99 % säkerhet.
Det är inte ett fel i just den modellen. Det är en egenskap hos hur de flesta nät fungerar: beslutsgränserna ligger mycket nära datapunkterna i högdimensionella rum, och en liten förflyttning i rätt riktning räcker.
Riktningen hittas med gradienten — samma gradient som används för att träna, fast nu används den för att ändra bilden i stället för vikterna.
Formellt
FGSM (Goodfellow m.fl. 2014) — ett enda steg:
PGD — iterativt och mycket starkare: Projektionen håller störningen inom -bollen.
Vad det avslöjar: Ilyas m.fl. (2019) argumenterar att adversariella exempel utnyttjar icke-robusta features — mönster som faktiskt är prediktiva i datan men imperceptibla för människor. Modellen är alltså inte «dum»; den använder signaler vi inte ser.
Försvar och deras status:
| Försvar | Status |
|---|---|
| Adversarial training (träna på PGD-exempel) | fungerar, men kostar 3–30× träningstid och sänker ren träffsäkerhet |
| Certifierade försvar (randomized smoothing) | garantier, men bara för små ε |
| Gradient masking (obfuskering) | fungerar inte — bryts av starkare angrepp |
| Indatatransformationer | bryts oftast av adaptiva angrepp |
Regeln i fältet: ett försvar som bara testats mot FGSM är inte testat. Utvärdera alltid mot adaptiva angrepp som känner till försvaret.
Kod
import torch, torch.nn.functional as F
def fgsm(modell, x, y, eps=2/255):
x = x.clone().detach().requires_grad_(True)
loss = F.cross_entropy(modell(x), y)
loss.backward()
return (x + eps * x.grad.sign()).clamp(0, 1).detach()
def pgd(modell, x, y, eps=2/255, alpha=0.5/255, steg=20):
x_adv = (x + torch.empty_like(x).uniform_(-eps, eps)).clamp(0, 1).detach()
for _ in range(steg):
x_adv.requires_grad_(True)
loss = F.cross_entropy(modell(x_adv), y)
grad = torch.autograd.grad(loss, x_adv)[0]
x_adv = x_adv.detach() + alpha * grad.sign()
x_adv = (x + (x_adv - x).clamp(-eps, eps)).clamp(0, 1) # projicera
return x_adv.detach()
med = (modell(x).argmax(1) == y).float().mean()
adv = (modell(pgd(modell, x, y)).argmax(1) == y).float().mean()
print(f"ren {med:.2f} → adversariell {adv:.2f}") # ren 0.94 → adversariell 0.03
En otränad modells träffsäkerhet faller typiskt från 94 % till nära noll med ε = 2/255 — en störning som är omöjlig att se.
Behärskning innebär
- Genererar en adversariell störning med FGSM/PGD
- Förklarar vad fenomenet avslöjar om modeller
- Känner till försvar och deras begränsningar
Logga in för att göra övningarna och bygga upp din behärskning.
Källor
- arXiv — Explaining and Harnessing Adversarial Examples — arXiv (öppen åtkomst; licens per artikel)
- arXiv — Towards Deep Learning Models Resistant to Adversarial Attacks (PGD) — arXiv (öppen åtkomst; licens per artikel)
- arXiv — Adversarial Examples Are Not Bugs, They Are Features — arXiv (öppen åtkomst; licens per artikel)