Part XIX — Alignment, Mechanistic Interpretability, Safety & Red-Teaming · Chapter 2

Adversarial attacks & robustness (FGSM & PGD)

Hook

A model can be perfectly accurate on every image you'd ever show it and still fail catastrophically on one an attacker built on purpose. The failure doesn't need a strange-looking input — it needs a change too small to see.

Intuition
0.60.60.60.60.60.60.60.60.6
input, each pixel nudged by 0.00

Drag epsilon. Every one of the 9 pixels shifts by the exact same tiny amount — nothing in the grid looks obviously different — yet the confidence score falls steadily, and eventually crosses the decision boundary entirely.

Formalize

FGSM (Fast Gradient Sign Method) perturbs every input dimension by a fixed budget ϵ\epsilon, in whichever direction most decreases the classifier's score — for a linear model, that direction is just the negative sign of each weight:

xi=xiϵsign(wi),Δ(wx)=ϵiwix'_i = x_i - \epsilon \cdot \text{sign}(w_i), \qquad \Delta(w \cdot x) = -\epsilon \sum_i |w_i|
  • xix_i — the original value of the ii-th input dimension (one pixel).
  • xix'_i — that same dimension's value after the perturbation is applied.
  • ϵ\epsilon — the fixed perturbation budget applied to every dimension.
  • wiw_i — the classifier's weight on dimension ii.
  • Δ(wx)\Delta(w \cdot x) — the resulting shift in the classifier's weighted sum (its score) once every dimension has been nudged.
  1. Each dimension's change is imperceptibly small

    Every individual xixi|x'_i - x_i| is bounded by ϵ\epsilon — small, imperceptible on its own.

  2. The total shift scales with dimension count, not epsilon alone

    The shift in the dot product the classifier actually uses scales with the number of dimensions. A perturbation invisible in any single pixel becomes a large, deliberate shift once summed across all of them.

Play

Confidence falls steadily as epsilon grows — not a single dramatic jump, a gradual decline that eventually crosses 0.5. The classifier isn't confused about any individual pixel; it's just adding up nine small, coordinated pushes in exactly the wrong direction.

Worked example

9 pixels at 0.6, weights all 1, bias 4.5-4.5:

  1. Before any perturbation

    wx+b=9(0.6)4.5=0.9w \cdot x + b = 9(0.6) - 4.5 = 0.9. σ(0.9)=11+e0.9\sigma(0.9) = \frac{1}{1+e^{-0.9}}: e0.90.4066e^{-0.9}\approx0.4066, so σ(0.9)11.40660.711\sigma(0.9)\approx\frac{1}{1.4066}\approx0.711 — confidently positive.

  2. At epsilon = 0.1

    Every pixel drops to 0.50.5. wx+b=9(0.5)4.5=0w \cdot x + b = 9(0.5) - 4.5 = 0. σ(0)=1/(1+e0)=1/2=0.5\sigma(0) = 1/(1+e^0) = 1/2 = 0.5 — sitting exactly on the boundary.

  3. At epsilon = 0.15

    Every pixel drops to 0.450.45 — barely different from 0.50.5. wx+b=9(0.45)4.5=0.45w \cdot x + b = 9(0.45) - 4.5 = -0.45. σ(0.45)=11+e0.45\sigma(-0.45) = \frac{1}{1+e^{0.45}}: e0.451.568e^{0.45}\approx1.568, so σ(0.45)12.5680.389\sigma(-0.45)\approx\frac{1}{2.568}\approx0.389 — now confidently classified in the other class.

Checkpoint

Find the smallest epsilon, among the candidates, that actually flips the classification.

Pick an epsilon to try it
Summary
x=xϵsign(w),Δ(wx)=ϵiwix' = x - \epsilon \cdot \text{sign}(w), \qquad \Delta(w\cdot x) = -\epsilon\sum_i |w_i|

This chapter's classifier was linear and its weights were visible — real adversarial attacks on deep networks use the same sign-of-gradient idea, computed via backpropagation through the whole network instead of read directly off a weight vector, which is exactly why adversarial examples generalize across architectures the attacker never even saw. Robustness training (adding perturbed examples like these directly into the training set) is one real defense; it trades some clean accuracy for resistance to exactly this kind of engineered nudge. The next chapter looks at a related but distinct failure: not a classifier fooled by pixels, but a language model talked past its own safety training by phrasing alone.