35.3 Perturbáció és adversarial példa

Ebben az alfejezetben azt a kérdést vizsgáljuk, hogy egy már tanított modell bemenetéhez hozzáadott, emberi szemmel alig észrevehető változás miként változtathatja meg a predikciót. A jelenséget először fenyegetési modellként (threat model) formalizáljuk, majd levezetjük az elsőrendű gradiensinformációból építkező FGSM (Fast Gradient Sign Method) lépést. A labor kizárólag saját, szintetikus GlyphLab-modellünkön mutat be kis, ellenőrzött perturbációt; külső rendszert nem támadunk.

Induló becslés: ha egy 24×2424\times24-es kép minden pixelét legfeljebb ε=0,05\varepsilon=0{,}05 értékkel változtathatjuk meg, vajon megfordul-e az osztályozás? A kérdésre csak a konkrét modell és a konkrét kép ismeretében adható válasz, ezért előbb a fogalmakat rögzítjük.

35.3.1 Fenyegetési modell és megengedett változás

Egy perturbációs vizsgálat tudományos állításként csak akkor értékelhető, ha megmondjuk, ki mit tud, mit módosíthat, és milyen céllal. Ezt a hármast nevezzük fenyegetési modellnek (threat model).

Definíció (white-box perturbációs támadó). Az osztályozó fθ:ℝd→{0,…,K−1}f_\theta:\mathbb R^d\to\{0,\dots,K-1\} predikciót ad. A white-box támadó ismeri θ\theta-t, a bemenet xx gradiensét és a yy címkét. Célja olyan xadv=x+δx_{adv}=x+\delta előállítása, amelyre fθ(xadv)≠yf_\theta(x_{adv})\neq y, miközben a perturbáció δ\delta egy előre rögzített norm budget (norma költségvetés) korláton belül marad. A támadó nem fér hozzá a tanításhoz, a súlyokat nem módosítja, és az adatfelosztást nem ismeri — csak a kész modellt és az aktuális bemenetet.

A leggyakoribb budget az ℓ∞\ell_\infty-norma:

∥δ∥∞=max1≤i≤d|δi|≤ε.\|\delta\|_\infty=\max_{1\le i\le d}|\delta_i|\le\varepsilon.

Képeknél ez azt jelenti, hogy egyetlen pixel intenzitása sem változhat ε\varepsilon-nál többel; a GlyphLab képek a [0,1][0,1] tartományban vannak, ezért ε=0,05\varepsilon=0{,}05 legfeljebb 5%5\% intenzitásváltozást enged pixelenként. Az ℓ2\ell_2-budget, ∥δ∥2≤ε\|\delta\|_2\le\varepsilon, ugyanakkora teljes energiájú, de térben simább perturbációt enged meg; a kettő nem felcserélhető, mert más támadóerőt jelent.

Három adattípust különböztetünk meg, mert más-más tudományos kérdésre válaszolnak:

A corrupt és az adversarial közötti határ a szándék és a modellinformáció felhasználása: a corrupt zaj nem a döntési határra irányul, az adversarial igen.

35.3.2 Az FGSM levezetése elsőrendű közelítésből

A levezetéshez egyetlen megfigyelésre van szükség: ha a veszteségfüggvény differenciálható, akkor kis perturbáció mellett a veszteség változását az elsőrendű Taylor-közelítés uralja.

Legyen L:ℝd→ℝL:\mathbb R^d\to\mathbb R a veszteségfüggvény (például egyetlen mintára vett cross-entropy), és g=∇xL(x)∈ℝdg=\nabla_x L(x)\in\mathbb R^d a bemenet szerinti gradiens. A gradiens alakja megegyezik xx alakjával; képeknél NCHW tensorként is ∇XL\nabla_X L jelöli, de az absztrakt levezetésben oszlopvektorként kezeljük. A Taylor-közelítés:

L(x+δ)=L(x)+g⊤δ+o(∥δ∥).L(x+\delta)=L(x)+g^\top\delta+o(\|\delta\|).

A támadó a g⊤δg^\top\delta lineáris tagot akarja maximalizálni a ∥δ∥∞≤ε\|\delta\|_\infty\le\varepsilon feltétel mellett. Mivel a korlát koordinátánként független, a feladat szétesik:

g⊤δ=∑i=1dgiδi,|δi|≤ε.g^\top\delta=\sum_{i=1}^d g_i\delta_i,\qquad |\delta_i|\le\varepsilon.

Minden egyes tagra a maximumot a gradiens előjelét követő lépés adja: ha gi>0g_i>0, akkor δi=ε\delta_i=\varepsilon; ha gi<0g_i<0, akkor δi=−ε\delta_i=-\varepsilon; ha gi=0g_i=0, a tag minden megengedett δi\delta_i mellett nulla. Így a maximalizáló perturbáció elemenként:

δi*=εsign(gi),sign(0):=0.\delta_i^*=\varepsilon\,\mathrm{sign}(g_i),\qquad \mathrm{sign}(0):=0.

Az sign(0)=0\mathrm{sign}(0)=0 itt konvenció, nem a ReLU-féle törésponti döntés; a gradiens pontosan nulla koordinátáinál a perturbáció nem változtatja az elsőrendű közelítést.

Lemma (FGSM irány elsőrendű optimalitása). Legyen L:ℝd→ℝL:\mathbb R^d\to\mathbb R differenciálható az xx pontban, és legyen g=∇xL(x)g=\nabla_x L(x). Ha ∥δ∥∞≤ε\|\delta\|_\infty\le\varepsilon, akkor

g⊤δ≤ε∥g∥1=ε∑i=1d|gi|.g^\top\delta\le\varepsilon\|g\|_1=\varepsilon\sum_{i=1}^d|g_i|.

Egyenlőség akkor és csak akkor áll fenn, ha δi=εsign(gi)\delta_i=\varepsilon\,\mathrm{sign}(g_i) minden olyan ii-re, ahol gi≠0g_i\neq0; a nulla gradiensű koordinátákon a perturbáció tetszőleges lehet. Ha g=0g=0, akkor minden megengedett δ\delta azonos, nulla elsőrendű növekedést ad.

Bizonyítás. Minden ii-re giδi≤|gi||δi|≤ε|gi|g_i\delta_i\le|g_i|\,|\delta_i|\le\varepsilon|g_i|, mert |δi|≤ε|\delta_i|\le\varepsilon. Összegzés után g⊤δ≤ε∥g∥1g^\top\delta\le\varepsilon\|g\|_1. A felső korlát elérése: δi=εsign(gi)\delta_i=\varepsilon\,\mathrm{sign}(g_i) esetén giδi=ε|gi|g_i\delta_i=\varepsilon|g_i|, tehát az összeg egyenlő az ε∥g∥1\varepsilon\|g\|_1 értékkel. A megfordítás: ha egy gi≠0g_i\neq0 koordinátán δi\delta_i nem az előjelirány, akkor giδi<ε|gi|g_i\delta_i<\varepsilon|g_i|, ezért az összeg szigorúan kisebb. Ha g=0g=0, akkor ∥g∥1=0\|g\|_1=0 és minden tag nulla. ▫\square

A lemma azt mondja ki, hogy az elsőrendű közelítésben az ℓ∞\ell_\infty-budget mellett a veszteséget leggyorsabban növelő irány a gradiens előjele. Ebből kapjuk az FGSM lépést:

xadv=x+εsign(∇xL(x)).x_{adv}=x+\varepsilon\,\mathrm{sign}(\nabla_x L(x)).

Képeknél, ahol a bemenet a [0,1][0,1] tartományra korlátozott, a perturbált képet visszavágjuk: xadv=clip(x+εsign(∇xL(x)),0,1)x_{adv}=\mathrm{clip}(x+\varepsilon\,\mathrm{sign}(\nabla_x L(x)),0,1). A clip\mathrm{clip} a megengedett képtartomány betartását szolgálja, és nem része az elsőrendű irány levezetésének.

Fontos korlát: a lemma nem állítja, hogy az FGSM lépés globálisan maximalizálja a veszteséget, csak azt, hogy az elsőrendű közelítést maximalizálja. Ha a veszteségfelület erősen görbült, a gradiens előjele félrevezető lehet; erre a 31.3. Diffúziós zajmodell és CNN-denoiser alfejezetben látott diffúziós zajmodell is példa, ahol a zajpredikciós cél felülete nem lineáris.

35.3.3 Eredeti kézi példa

Legyen a modell egy affin osztályozó ℝ3\mathbb R^3-ból két logitba:

W=(10−0,50,2−10,4),b=(0,1,−0,2)⊤.W=\begin{pmatrix}1&0&-0{,}5\\0{,}2&-1&0{,}4\end{pmatrix},\qquad b=(0{,}1,-0{,}2)^\top.

A bemenet x=(0,5,0,2,−0,3)⊤x=(0{,}5,0{,}2,-0{,}3)^\top, a helyes osztály y=0y=0, a perturbációs budget ε=0,1\varepsilon=0{,}1. A logitok:

z=Wx+b=(0,75,−0,42)⊤.z=Wx+b=(0{,}75,\,-0{,}42)^\top.

A softmax valószínűségek:

p1=e0,75e0,75+e−0,42≈0,7632,p2≈0,2368.p_1=\frac{e^{0{,}75}}{e^{0{,}75}+e^{-0{,}42}}\approx0{,}7632,\qquad p_2\approx0{,}2368.

A cross-entropy veszteség egyetlen mintára: L=−zy+log∑jezj≈−0,75+log(2,774)≈0,2707L=-z_y+\log\sum_j e^{z_j}\approx-0{,}75+\log(2{,}774)\approx0{,}2707. A bemenet szerinti gradiens — a 7.2. Softmax és többosztályos cross-entropy alfejezetben levezetett softmax-láncszabályból — g=W⊤(p−ey)g=W^\top(p-e_y), ahol ey=(1,0)⊤e_y=(1,0)^\top:

g=W⊤(−0,23680,2368)≈(−0,1894,−0,2368,0,2131)⊤.g=W^\top\begin{pmatrix}-0{,}2368\\0{,}2368\end{pmatrix}\approx(-0{,}1894,\,-0{,}2368,\,0{,}2131)^\top.

Az FGSM perturbáció: δ=0,1⋅sign(g)=(−0,1,−0,1,0,1)⊤\delta=0{,}1\cdot\mathrm{sign}(g)=(-0{,}1,\,-0{,}1,\,0{,}1)^\top, tehát

xadv=(0,4,0,1,−0,2)⊤.x_{adv}=(0{,}4,\,0{,}1,\,-0{,}2)^\top.

Az új logitok zadv=(0,6,−0,30)⊤z_{adv}=(0{,}6,\,-0{,}30)^\top, az új veszteség Ladv≈0,3413L_{adv}\approx0{,}3413. A veszteség nőtt, de a predikció még mindig a 00 osztály, mert a margó 0,90{,}9 maradt. Az elsőrendű közelítés jósolta növekedés ε∥g∥1≈0,1⋅0,6393=0,0639\varepsilon\|g\|_1\approx0{,}1\cdot0{,}6393=0{,}0639; a tényleges növekedés 0,07060{,}0706, ami a magasabb rendű tagok hatását mutatja.

A következő kód ugyanezt a számítást ellenőrzi float64 pontossággal:

# lab/n139/manual_fgsm.py
import numpy as np

x = np.array([0.5, 0.2, -0.3], dtype=np.float64)
W = np.array([[1.0, 0.0, -0.5],
              [0.2, -1.0, 0.4]], dtype=np.float64)
b = np.array([0.1, -0.2], dtype=np.float64)
y = 0
eps = 0.1

def softmax(z):
    e = np.exp(z - z.max())
    return e / e.sum()

def ce_loss(z, y):
    return -z[y] + np.log(np.exp(z).sum())

z = W @ x + b
p = softmax(z)
g = W.T @ (p - np.eye(2)[y])
delta = eps * np.sign(g)
x_adv = x + delta
z_adv = W @ x_adv + b

print("z      =", z)
print("L      =", ce_loss(z, y))
print("g      =", g)
print("delta  =", delta)
print("x_adv  =", x_adv)
print("z_adv  =", z_adv)
print("L_adv  =", ce_loss(z_adv, y))
print("eps*||g||_1 =", eps * np.abs(g).sum())

35.3.4 Labor: kontrollperturbáció saját GlyphLab-modellen

Az alábbi labor kizárólag a saját, szintetikus GlyphLab-adatunkon mutat be FGSM-et. A modell egy kis CNN, amelyet a laborban röviden tanítunk a train spliten; a demonstrációhoz a test split első képét használjuk. A kimenetet ez a kézirat számított példaként közli, nem rögzített futásként; a tényleges futás a laborban ellenőrizhető.

Futtatási környezet: CPU, float32, seed 2026102020261020, munkakönyvtár lab/n139/. Az adatfájlok a szerződés szerint lab/data/ alatt vannak, ezért a relatív út ../data/.

# lab/n139/fgsm_demo.py
"""FGSM demonstráció a GlyphLab egy képén. Nem támad külső rendszert."""
import numpy as np
import torch
import torch.nn as nn

SEED = 20261020
torch.manual_seed(SEED)
np.random.seed(SEED)
DTYPE = torch.float32
DEVICE = torch.device("cpu")

# --- GlyphLab betöltés a manifest szerződése alapján ---
data_dir = "../data"
images = np.load(f"{data_dir}/images.npy")   # (360,1,24,24) float32
labels = np.load(f"{data_dir}/labels.npy")   # (360,) int64
# A manifest szerint a train az első 240, a test az utolsó 60 kép;
# a metadata.csv split oszlopa ugyanezt a felosztást rögzíti.
X_train = torch.from_numpy(images[:240]).to(DEVICE).to(DTYPE)
y_train = torch.from_numpy(labels[:240]).to(DEVICE)
x_test = torch.from_numpy(images[300:301]).to(DEVICE).to(DTYPE)
y_test = torch.tensor([labels[300]], device=DEVICE)

class MiniCNN(nn.Module):
    def __init__(self):
        super().__init__()
        self.net = nn.Sequential(
            nn.Conv2d(1, 8, 3, padding=1), nn.ReLU(),
            nn.AdaptiveAvgPool2d(4),
            nn.Flatten(),
            nn.Linear(8 * 4 * 4, 3)
        )
    def forward(self, x):
        return self.net(x)

model = MiniCNN().to(DEVICE).to(DTYPE)
loss_fn = nn.CrossEntropyLoss()
opt = torch.optim.Adam(model.parameters(), lr=1e-3)

B = 32
for epoch in range(2):
    perm = torch.randperm(X_train.shape[0])
    for i in range(0, X_train.shape[0], B):
        idx = perm[i:i+B]
        xb, yb = X_train[idx], y_train[idx]
        opt.zero_grad()
        loss = loss_fn(model(xb), yb)
        loss.backward()
        opt.step()

def fgsm_perturbation(model, x, y, eps):
    x = x.clone().detach().requires_grad_(True)
    logits = model(x)
    loss = loss_fn(logits, y)
    model.zero_grad()
    loss.backward()
    grad = x.grad.detach()
    delta = eps * torch.sign(grad)
    x_adv = torch.clamp(x.detach() + delta, 0.0, 1.0)
    return x_adv, delta, loss.item()

eps = 0.05
model.eval()
with torch.no_grad():
    clean_logits = model(x_test)
    clean_pred = clean_logits.argmax(dim=1).item()

x_adv, delta, clean_loss = fgsm_perturbation(model, x_test, y_test, eps)
with torch.no_grad():
    adv_logits = model(x_adv)
    adv_pred = adv_logits.argmax(dim=1).item()
    adv_loss = loss_fn(adv_logits, y_test).item()

# Kontroll 1: véletlen perturbáció azonos L∞ budgettel
torch.manual_seed(SEED + 1)
rnd = torch.empty_like(x_test).uniform_(-eps, eps)
x_rnd = torch.clamp(x_test + rnd, 0.0, 1.0)
with torch.no_grad():
    rnd_pred = model(x_rnd).argmax(dim=1).item()

# Kontroll 2: ellentétes gradiensirány (veszteségcsökkentő lépés)
x_neg = torch.clamp(x_test - delta, 0.0, 1.0)
with torch.no_grad():
    neg_pred = model(x_neg).argmax(dim=1).item()

print(f"clean pred={clean_pred}  loss={clean_loss:.4f}")
print(f"adv   pred={adv_pred}  loss={adv_loss:.4f}")
print(f"random pred={rnd_pred}")
print(f"neg   pred={neg_pred}")
print(f"||delta||_inf={delta.abs().max().item():.4f}")

Várt viselkedés (számított példa, nem rögzített mérés): a rövid tanítás után a modell a kiválasztott test képen jellemzően helyesen osztályoz; az FGSM a veszteséget növeli, és gyakran, de nem garantáltan megfordítja a predikciót. A véletlen perturbáció azonos budget mellett általában nem változtatja meg a döntést, mert nem a döntési határra irányul. Az ellentétes gradiensirány csökkenti a veszteséget. A ||delta||_inf értéknek 0,050{,}05-nek kell lennie, kivéve ha a clip beavatkozott a [0,1][0,1] határoknál.

35.3.5 Robusztusság és mérési korlátok

Definíció (pontonkénti ε\varepsilon-robusztusság). Az fθf_\theta osztályozó az (x,y)(x,y) ponton ε\varepsilon-robusztus az ℓ∞\ell_\infty-normában, ha minden olyan δ\delta mellett, amelyre ∥δ∥∞≤ε\|\delta\|_\infty\le\varepsilon, teljesül fθ(x+δ)=yf_\theta(x+\delta)=y. A modell adversarial accuracy-ja egy TT teszthalmazon az ε\varepsilon-budgetű támadóval szemben:

Accadv(T,ε)=1|T|∑(x,y)∈T𝟏{fθ(xadv(x))=y},\mathrm{Acc}_{adv}(T,\varepsilon)=\frac{1}{|T|}\sum_{(x,y)\in T}\mathbf 1\{f_\theta(x_{adv}(x))=y\},

ahol xadv(x)x_{adv}(x) az adott támadó által előállított perturbált bemenet. Ez a mérőszám attól a konkrét támadóalgoritmustól függ, amellyel xadvx_{adv}-et előállítjuk; ezért az FGSM-mel mért adversarial accuracy és a PGD-vel mért érték nem ugyanazt a robusztusságot méri.

A három tesztfajta összehasonlítása páros szerkezetű: a GlyphLab clean, corrupt és adversarial tesztje ugyanazokra a jelenet/nézet párokra épül, ezért az accuracy-k különbsége páros összehasonlításként értékelhető. A bizonytalanság számításához a 23.3. Páros összehasonlítás és csoportszintű intervallum alfejezetben bevezetett class-stratified scene bootstrap a helyes eljárás, nem a képenkénti független mintavétel.

35.3.6 Feladatok

F1 (fogalmi, nehézség 1). Magyarázd el, mi a különbség a clean, corrupt és adversarial tesztadatok között a GlyphLab keretében. Mindegyikre adj egy konkrét példát, és mondd meg, melyik milyen tudományos kérdésre válaszol. Elvárt átadandó eredmény: legfeljebb fél oldalas, három bekezdésből álló magyarázat, mindhárom esetre explicit példával.

F2 (levezetési, nehézség 2). Bizonyítsd be az ℓ2\ell_2-normás változatot: ha ∥δ∥2≤ε\|\delta\|_2\le\varepsilon és g=∇xL(x)≠0g=\nabla_x L(x)\neq0, akkor az elsőrendű g⊤δg^\top\delta tagot a δ*=εg/∥g∥2\delta^*=\varepsilon g/\|g\|_2 perturbáció maximalizálja, és a maximum ε∥g∥2\varepsilon\|g\|_2. Mi történik, ha g=0g=0? Elvárt átadandó eredmény: teljes levezetés a Cauchy–Schwarz-egyenlőtlenség alkalmazásával, az egyenlőség feltételének indoklásával.

F3 (implementációs, nehézség 1). Írj Python függvényt fgsm_affine(W, b, x, y, eps) néven, amely a fenti affin osztályozón kiszámítja az FGSM perturbációt, és visszaadja az (x_adv, loss_orig, loss_adv, grad) négyest. Ellenőrizd a kézi példán a megadott paraméterekkel; a numerikus tolerancia 10−410^{-4}. Elvárt átadandó eredmény: futtatható kód, amely kiírja a négy értéket, és az ellenőrzés sikerét jelzi.

F4 (hibakeresési, nehézség 2). Az alábbi kódrészlet egy hibát tartalmaz:

x_adv = x.clone().detach().requires_grad_(True)
loss = loss_fn(model(x_adv), y)
loss.backward()
delta = eps * torch.sign(x_adv.grad)
x_final = torch.clamp(x_adv + delta, 0.0, 1.0)

Itt x az eredeti, nem perturbált kép. Mi a hiba, mi a következménye, és hogyan javítanád? Elvárt átadandó eredmény: a hiba lokalizálása, a következmény leírása egy-két mondatban, és a javított kódrészlet.

F5 (kísérleti, nehézség 3). Tervezz kísérletet a GlyphLab-on, amely összehasonlítja a clean accuracy-t, az FGSM-perturbált teszt accuracy-ját és a corrupt teszt accuracy-ját. Add meg: a kutatási kérdést, a splitet, a modellt, a baseline-t, a változó tényezőt, a metrikát, a futtatási erőforrást és a következtetés korlátait. Elvárt átadandó eredmény: protokollterv az 1.2. Szakmailag megalapozott modellezési állítások alfejezetben bevezetett kísérleti napló szerkezetében, legalább egy explicit érvényességi korláttal.

35.3.7 Megoldások és indoklás

M1. A clean adat az eredeti, módosítatlan tesztbemenet; például a data/images.npy test splitjének első képe. Azt a kérdést válaszolja meg, hogy a modell általában milyen pontosan osztályoz. A corrupt adat természetes, nem ellenséges romlást tartalmaz; a GlyphLab corrupted_test.npy fájlja zajt és fényességgradienst ad ugyanazokhoz a jelenet/nézet párokhoz. Azt vizsgálja, hogy a modell mennyire érzékeny a fizikai jellegű képromlásra. Az adversarial adat a modell gradiensét felhasználva, a hibázás céljával készült perturbáció; például a fenti FGSM-mel generált xadvx_{adv}. Azt vizsgálja, hogy egy white-box támadó milyen könnyen tudja megváltoztatni a döntést. A három mérés három különböző kockázatot jellemez, ezért nem helyettesíthetik egymást.

M2. A Cauchy–Schwarz-egyenlőtlenséggel g⊤δ≤∥g∥2∥δ∥2≤ε∥g∥2g^\top\delta\le\|g\|_2\|\delta\|_2\le\varepsilon\|g\|_2. Az egyenlőség feltétele, hogy gg és δ\delta párhuzamosak és azonos irányúak; mivel ∥δ∥2=ε\|\delta\|_2=\varepsilon, a δ=εg/∥g∥2\delta=\varepsilon g/\|g\|_2 választás eléri a korlátot, és valóban g⊤δ=ε∥g∥2g^\top\delta=\varepsilon\|g\|_2. Ha g=0g=0, akkor a felső korlát nulla, és minden megengedett δ\delta nulla elsőrendű növekedést ad; a másodrendű tagok dönthetik el, melyik irány növeli a veszteséget.

M3. A megoldás a kézi példát közvetlenül újrahasznosítja:

import numpy as np

def fgsm_affine(W, b, x, y, eps):
    x = np.asarray(x, dtype=np.float64)
    W = np.asarray(W, dtype=np.float64)
    b = np.asarray(b, dtype=np.float64)
    def softmax(z):
        e = np.exp(z - z.max())
        return e / e.sum()
    def ce(z, y):
        return -z[y] + np.log(np.exp(z).sum())
    z = W @ x + b
    p = softmax(z)
    g = W.T @ (p - np.eye(W.shape[0])[y])
    delta = eps * np.sign(g)
    x_adv = x + delta
    return x_adv, ce(z, y), ce(W @ x_adv + b, y), g

W = np.array([[1.0, 0.0, -0.5], [0.2, -1.0, 0.4]])
b = np.array([0.1, -0.2])
x = np.array([0.5, 0.2, -0.3])
y = 0
eps = 0.1
x_adv, L0, L1, g = fgsm_affine(W, b, x, y, eps)
print(x_adv, L0, L1, g)
# Ellenőrzés: L1 > L0 és ||x_adv - x||_inf <= eps + 1e-12
assert L1 > L0
assert np.abs(x_adv - x).max() <= eps + 1e-12

Az x_adv várható értéke (0,4,0,1,−0,2)(0{,}4,0{,}1,-0{,}2), a veszteségek 0,27070{,}2707 és 0,34130{,}3413 körül, a gradiens (−0,1894,−0,2368,0,2131)(-0{,}1894,-0{,}2368,0{,}2131) körül, a tolerancia 10−410^{-4}.

M4. A hiba az, hogy a gradiens a perturbált xadvx_{adv} ponton készül, miközben a perturbációt is xadvx_{adv}-re alkalmazzák. Az eredmény egy kétlépéses, második lépésében már eltérített irány, nem pedig az eredeti xx ponton vett FGSM. Következmény: az irány már nem az xx-beli veszteség növelésére irányul, ezért a veszteség növekedése kisebb lehet, és a támadás hatékonysága romlik. A javítás: a gradienset az eredeti xx-en kell kiszámítani, majd azonnal perturbálni:

x_grad = x.clone().detach().requires_grad_(True)
loss = loss_fn(model(x_grad), y)
loss.backward()
delta = eps * torch.sign(x_grad.grad)
x_adv = torch.clamp(x + delta, 0.0, 1.0)

M5. Lehetséges terv: Kérdés: mekkora a különbség a clean, corrupt és FGSM-perturbált test accuracy között a GlyphLab modellen? Split: a rögzített train/val/test; a modellt csak trainen tanítjuk, a val a korai leállításra, a test csak a végén kerül kiértékelésre — a corrupt és adversarial teszt ugyanazon a test spliten. Modell: a laborban használt MiniCNN. Baseline: a clean test accuracy. Változó tényező: a bemenet típusa (clean, corrupt, FGSM ε=0,05\varepsilon=0{,}05). Metrika: scene-egységen átlagolt accuracy, a bizonytalanságot class-stratified scene bootstrap adja. Erőforrás: CPU, float32, seed 2026102020261020. Következtetési korlát: az eredmény a szintetikus GlyphLab-eloszlásra és a választott FGSM-támadóra vonatkozik; nem állít semmit a természetes képek robusztusságáról, és egyetlen FGSM-eredmény nem bizonyítja a modell ellenállását erősebb, például iterált támadókkal szemben.

35.3.8 Tipikus tévedés és ellenpélda

A leggyakoribb tévedés: egy FGSM-teszten elért siker nem minden támadóval szembeni robusztussági bizonyítás. Az FGSM egyetlen lépést tesz a gradiens előjelirányában; ha a veszteségfelület nem lineáris, egy iterált, vetített gradiensű módszer (például PGD) ugyanazon budget mellett lényegesen nagyobb veszteségnövekedést találhat. Ellenpélda: tekintsük az L(x)=x12+100x22L(x)=x_1^2+100x_2^2 veszteségfüggvényt az x=(0,0)x=(0,0) pontban, ε=0,1\varepsilon=0{,}1 mellett. Itt g=(0,0)g=(0,0), tehát az FGSM perturbáció nulla, és a veszteség nem nő. Egy támadó azonban a x2=0,1x_2=0{,}1 irányt választva L=1L=1 veszteséget ér el. Az FGSM tehát nem találta meg a támadási irányt, miközben létezik hatékony perturbáció. A modell értékelésekor ezért mindig meg kell nevezni a támadóalgoritmust, és az egyetlen támadóval mért adversarial accuracy nem általános robusztussági garancia.

35.3.9 Önellenőrzés és visszahívás

Rövid önellenőrzés: (1) A gradiens alakja megegyezik-e a bemenet alakjával? (2) A perturbáció minden koordinátája legfeljebb ε\varepsilon abszolút értékű-e? (3) A clip után a kép a [0,1][0,1] tartományban marad-e? (4) A megfogalmazott állítás az elsőrendű közelítésre vagy a tényleges veszteségre vonatkozik? Visszahívás a 35.2. Magyarázat sanity check alfejezetből: a sanity check arra figyelmeztet, hogy a gradiensalapú jelzések akkor is változhatnak, ha a modell nem használja a címkét; az FGSM-nél ez azért fontos, mert a gradiens informatív voltát ugyanúgy ellenőrizni kell. A 34.3. Pruning és struktúra alfejezetből: a strukturált pruning megváltoztatja a döntési határt, ezért a perturbációs vizsgálatot mindig a végleges, nem pedig a közbenső modellen kell elvégezni.

35.3.10 Rövid összefoglaló

Az adversarial példa olyan bemenet, amelyet a modell hibázásának céljával, a megengedett perturbációs budgeten belül választottak. A white-box fenyegetési modell rögzíti, hogy a támadó ismeri a paramétereket és a gradienst. Az FGSM az elsőrendű Taylor-közelítésből vezethető le: az ℓ∞\ell_\infty-korlát mellett a veszteséget növelő irány a gradiens előjele, amelynek maximális elsőrendű növekedése ε∥∇xL∥1\varepsilon\|\nabla_x L\|_1. A kézi példa igazolta a lépést, a labor pedig saját GlyphLab-modellen mutatott kontrollperturbációt. A clean, corrupt és adversarial accuracy más kockázatot mér; egyetlen FGSM-eredmény nem bizonyít általános robusztusságot.

35.3.11 Következő alkalmazás

A 35.4. Korlátok, eredet és döntési felelősség egységben ezeket a perturbációs eredményeket a korlátok, az adateredet és a döntési felelősség keretébe helyezzük: milyen feltételek mellett lehet egy modellt magas tétű alkalmazásban használni, és mit kell dokumentálni az ismert támadási felületekről.

35.3.12 Források