Defining evaluation metrics for adversarial robustness

1) Why robustness metrics need to be different from “normal” ML metrics

Standard ML evaluation answers: “How accurate is the model on clean data?”
Adversarial robustness evaluation answers: “How does the model behave under worst-case, attacker-controlled inputs?”

A model can have 99% clean accuracy and 0–10% adversarial accuracy under a strong attack.
So robustness metrics must capture:

  • performance under attack
  • attacker success rate
  • robustness–accuracy trade-offs
  • stability and confidence behavior under perturbations
  • (optionally) provable guarantees (certified metrics)

2) Always define the evaluation setup (or the metric is meaningless)

Before you report any robustness metric, log these parameters:

Threat Model

  • Norm: L∞, L2, etc.
  • Budget: ε
  • Input constraints: valid ranges, feature constraints

Attack Details

  • Attack type: FGSM / PGD / C&W / etc.
  • Steps, step size, restarts
  • Targeted vs untargeted
  • White-box vs black-box
  • Query budget (if black-box)

Model Context

  • preprocessing pipeline (must match training/inference)
  • stochastic transforms (require EOT-style evaluation)
  • random seeds and averaging strategy

Rule: No robustness metric should be reported without its threat model + attack config.

3) Core robustness metrics (the essentials)

Metric A — Robust Accuracy (Empirical Robust Accuracy)

Definition: Accuracy on adversarially perturbed inputs generated by a specified attack under a specified ε.

Interpretation:

  • higher is better
  • compare across ε values (robustness curve)

Metric B — Attack Success Rate (ASR)

Definition (untargeted): fraction of inputs where attacker causes misclassification.

Relation:

ASR=1−RobustAcc(only if all samples are correctly classified cleanly and counted equally)

Better practice: compute ASR over clean-correct samples only (see Metric C).

Metric C — Conditional Robust Accuracy (on Clean-Correct Subset)

Many robustness papers report robustness only for samples the model got right originally.

Let:

Why it’s important:
Otherwise, models with poor clean accuracy can look “robust” just because they’re already wrong.

Metric D — Robustness Degradation / Robustness Gap

Measures how much performance drops under attack:

Interpretation: smaller gap = better stability.

Metric E — Worst-Case Robust Accuracy (Attack Suite)

Instead of one attack, evaluate with a suite and take worst-case:

Why: prevents “robust to FGSM only” illusions.

4) Advanced but very useful metrics

Metric F — Minimum Perturbation Needed to Fool (Distortion / Margin Proxy)

For each sample, estimate smallest ε where attack succeeds (or approximation):

  • “How far must an attacker push input before it breaks?”

  • Report median/mean minimal distortion

Useful for comparing models when a single ε is too arbitrary.

Metric G — Robustness Curve + AUC

Evaluate robust accuracy at multiple ε values:

ε ∈ {0.0, 0.05, 0.1, 0.2, 0.3}

Plot RobustAcc(ε) and compute area under curve (AUC).
This summarizes robustness across budgets.

Metric H — Calibration Under Attack (Confidence Reliability)

Even if accuracy drops, a safe model should not be overconfident on adversarial inputs.

Track:

  • Expected Calibration Error (ECE) on clean vs adversarial data

  • average max softmax probability under attack

Metric I — Certified Metrics

For certified defenses:

  • Certified radius per sample

  • Certified accuracy at ε:
    % of samples that are both correct and provably robust within ε

5) Recommended reporting template (ELMS-ready)

Robustness Report (minimum)

  • Clean Accuracy: __

  • Threat model: norm = __, ε = __

  • Attack: PGD (steps=, step size=, restarts=__)

  • Robust Accuracy (PGD): __

  • Robust Accuracy (FGSM): __

  • Worst-case Robust Accuracy (suite): __

  • Robustness Gap: __

Optional

  • Robustness curve AUC: __

  • Confidence metrics (ECE / avg confidence) under attack: __

  • Certified accuracy (if applicable): __

6) Code: Compute clean acc, robust acc, ASR, robustness gap (TF2 + CleverHans)

Assumes you already have:

  • model (logits output)

  • x_test, y_test_oh

import numpy as np
import tensorflow as tf
from cleverhans.tf2.attacks.fast_gradient_method import fast_gradient_method
from cleverhans.tf2.attacks.projected_gradient_descent import projected_gradient_descent

def accuracy(model, x, y_onehot):
return float(model.evaluate(x, y_onehot, verbose=0)[1])

def evaluate_robustness(model, x, y_onehot,
fgsm_eps=0.2,
pgd_eps=0.3, pgd_eps_iter=0.03, pgd_steps=20):
# Clean accuracy
clean_acc = accuracy(model, x, y_onehot)

# FGSM adversarial accuracy
x_fgsm = fast_gradient_method(model_fn=model, x=x, eps=fgsm_eps, norm=np.inf)
fgsm_acc = accuracy(model, x_fgsm, y_onehot)

# PGD adversarial accuracy
x_pgd = projected_gradient_descent(model_fn=model, x=x,
eps=pgd_eps, eps_iter=pgd_eps_iter, nb_iter=pgd_steps,
norm=np.inf, targeted=False)
pgd_acc = accuracy(model, x_pgd, y_onehot)

# Robustness gap (using PGD as main attack)
gap = clean_acc - pgd_acc

# Attack Success Rate (ASR) (untargeted)
pgd_asr = 1.0 - pgd_acc

return {
"clean_acc": clean_acc,
"fgsm_acc": fgsm_acc,
"pgd_acc": pgd_acc,
"pgd_asr": pgd_asr,
"robustness_gap_clean_minus_pgd": gap,
"params": {
"fgsm_eps": fgsm_eps,
"pgd_eps": pgd_eps,
"pgd_eps_iter": pgd_eps_iter,
"pgd_steps": pgd_steps,
"norm": "Linf"
}
}

# Example:
# results = evaluate_robustness(model, x_test, y_test_oh)
# print(results)

7) Code: Conditional robust accuracy (only on clean-correct samples)

def conditional_robust_accuracy(model, x, y_onehot, attack_fn):
# clean predictions
logits = model(x, training=False)
y_true = tf.argmax(y_onehot, axis=1)
y_pred = tf.argmax(logits, axis=1)

mask = tf.equal(y_pred, y_true) # clean-correct subset
x_cc = tf.boolean_mask(x, mask)
y_cc = tf.boolean_mask(y_onehot, mask)

if x_cc.shape[0] == 0:
return 0.0

x_adv = attack_fn(x_cc)
return accuracy(model, x_adv, y_cc)

# Example usage:
# pgd_attack = lambda x_in: projected_gradient_descent(model, x_in, eps=0.3, eps_iter=0.03, nb_iter=20,
# norm=np.inf, targeted=False)
# cra = conditional_robust_accuracy(model, x_test, y_test_oh, pgd_attack)
# print("Conditional robust accuracy (PGD):", cra)

Comments are closed.

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}
FREEDOM TO LEARN • 10% OFF All Courses & Workshops • Use Code: NANOINDIA10 • ⏳ Offer Ends In: Loading... • Learn Today. Lead Tomorrow. • Explore Programs →
FREEDOM TO LEARN • 10% OFF All Courses & Workshops • Use Code: NANOINDIA10 • ⏳ Offer Ends In: Loading... • Learn Today. Lead Tomorrow. • Explore Programs →
Support