Skip to content
Back to skills

Adversarial Ml Robustness

ASecurity

Use when implementing adversarial attacks and ML defenses.

  • 2 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 10, 2026
ai-agentspythontestinggitsecurity

Works with

  • cli

Security analysis

A100/100

Scanned September 10, 2026

npx -y skills add LoopyLuci/Skills --skill adversarial-ml-robustness --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Adversarial Ml Robustness?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Adversarial Ml Robustness
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/loopyluci-adversarial-ml-robustness/badge)](https://www.skillsdirectory.com/skills/loopyluci-adversarial-ml-robustness)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: adversarial-ml-robustness
description: "Use when implementing adversarial attacks and ML defenses."
version: 1.0.0
author: Hermes Agent
license: MIT
metadata:
  hermes:
    tags: [adversarial, robustness, attacks, defenses, security]
    related_skills: [agent-safety-alignment, differential-privacy-training, explainable-ai-xai-patterns]
---

# Adversarial ML — Attacks and Defenses

Implementing adversarial attacks to evaluate ML model robustness, and defenses to protect against them. Covers evasion, poisoning, extraction, and inference attacks.

## When to Use

- Testing model robustness before production deployment
- Building defenses against adversarial inputs
- Red-teaming ML systems for security vulnerabilities
- Researching new attack/defense methods
- Regulatory compliance for high-stakes ML (medical, finance, autonomous driving)

## Attack Taxonomy

```
Attacks
├── Evasion (perturb inputs at inference)
├── Poisoning (corrupt training data)
├── Extraction (steal model parameters)
└── Inference (leak training data membership)
    ├── Membership inference
    └── Attribute inference
```

## Evasion Attacks

### Fast Gradient Sign Method (FGSM)

```python
import torch
import torch.nn.functional as F

def fgsm_attack(model, x, y, epsilon=0.1):
    """Fast Gradient Sign Method: one-step adversarial attack."""
    x.requires_grad = True
    
    # Forward pass
    logits = model(x)
    loss = F.cross_entropy(logits, y)
    
    # Backward pass to get gradient
    model.zero_grad()
    loss.backward()
    
    # Create adversarial example
    x_adv = x + epsilon * x.grad.sign()
    x_adv = torch.clamp(x_adv, 0, 1)  # Keep in valid range
    
    return x_adv.detach()
```

### Projected Gradient Descent (PGD)

```python
def pgd_attack(model, x, y, epsilon=0.3, alpha=0.01, num_steps=40, random_start=True):
    """Projected Gradient Descent: iterative, stronger than FGSM."""
    x_adv = x.clone().detach()
    
    if random_start:
        x_adv = x_adv + torch.empty_like(x_adv).uniform_(-epsilon, epsilon)
    
    for _ in range(num_steps):
        x_adv.requires_grad = True
        
        logits = model(x_adv)
        loss = F.cross_entropy(logits, y)
        
        model.zero_grad()
        loss.backward()
        
        # Gradient ascent step
        with torch.no_grad():
            x_adv = x_adv + alpha * x_adv.grad.sign()
            
            # Project back to epsilon-ball around original x
            delta = torch.clamp(x_adv - x, -epsilon, epsilon)
            x_adv = torch.clamp(x + delta, 0, 1)
    
    return x_adv.detach()
```

### Carlini-Wagner (C&W) Attack

```python
def cw_attack(model, x, y, num_classes=10, confidence=0, lr=1e-2, max_iter=1000):
    """Carlini-Wagner L2 attack. Finds minimal perturbation."""
    x_adv = x.clone().detach().requires_grad_(True)
    optimizer = torch.optim.Adam([x_adv], lr=lr)
    
    # Convert labels to one-hot
    y_onehot = F.one_hot(y, num_classes).float()
    
    for i in range(max_iter):
        logits = model(x_adv)
        
        # CW loss: maximize logit of target class - max of others
        real = (logits * y_onehot).sum(dim=1)
        other = ((1 - y_onehot) * logits - (1 - y_onehot) * 1e9).max(dim=1)[0]
        loss = torch.max(real - other, -confidence + other - real).sum()
        
        # L2 regularization
        l2_loss = (x_adv - x).pow(2).sum()
        total_loss = loss + l2_loss
        
        optimizer.zero_grad()
        total_loss.backward()
        optimizer.step()
    
    return x_adv.detach()
```

## Poisoning Attacks

### Data Poisoning (Backdoor)

```python
def inject_backdoor(dataset, target_label=0, trigger_pattern="square", poison_ratio=0.1):
    """Inject backdoor triggers into training data."""
    poisoned_x, poisoned_y = [], []
    
    for i, (x, y) in enumerate(dataset):
        if random.random() < poison_ratio:
            # Apply trigger to input
            x_poisoned = apply_trigger(x, trigger_pattern)
            # Label flipping
            poisoned_x.append(x_poisoned)
            poisoned_y.append(target_label)
        else:
            poisoned_x.append(x)
            poisoned_y.append(y)
    
    return poisoned_x, poisoned_y

def apply_trigger(x, pattern="square"):
    """Add a trigger pattern to the image."""
    x_adv = x.clone()
    if pattern == "square":
        # White square in bottom-right corner
        x_adv[..., -5:, -5:] = 1.0
    elif pattern == "pixel":
        x_adv[..., 0, 0] = 1.0
    return x_adv
```

### Gradient Matching Poisoning

```python
def gradient_matching_poison(clean_model, target_example, target_label, 
                             n_poison=100, steps=100, lr=0.1):
    """Craft poisons that maximize loss on target example."""
    # Initialize poison data
    poison_data = torch.randn(n_poison, *clean_model.input_shape)
    poison_labels = torch.zeros(n_poison, dtype=torch.long)
    poison_data.requires_grad_(True)
    
    optimizer = torch.optim.SGD([poison_data], lr=lr)
    
    for _ in range(steps):
        # Train on poison data
        logits = clean_model(poison_data)
        train_loss = F.cross_entropy(logits, poison_labels)
        
        # Maximize loss on target
        target_logits = clean_model(target_example)
        target_loss = F.cross_entropy(target_logits, target_label)
        
        # Combined: minimize train loss, maximize target loss
        total_loss = train_loss - target_loss
        
        optimizer.zero_grad()
        total_loss.backward()
        optimizer.step()
        poison_data.data = torch.clamp(poison_data.data, 0, 1)
    
    return poison_data.detach(), poison_labels
```

## Defenses

### Adversarial Training

```python
def adversarial_training(model, train_loader, epochs=50, epsilon=0.1, alpha=0.01):
    """Train on adversarial examples to build robustness."""
    optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
    
    for epoch in range(epochs):
        total_loss = 0
        for x, y in train_loader:
            # Generate adversarial examples
            x_adv = pgd_attack(model, x, y, epsilon=epsilon, alpha=alpha, num_steps=7)
            
            # Train on both clean and adversarial examples
            logits_clean = model(x)
            logits_adv = model(x_adv)
            
            loss_clean = F.cross_entropy(logits_clean, y)
            loss_adv = F.cross_entropy(logits_adv, y)
            loss = (loss_clean + loss_adv) / 2
            
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            
            total_loss += loss.item()
        
        print(f"Epoch {epoch}, Loss: {total_loss/len(train_loader):.4f}")
```

### Gradient Masking (Not Recommended)

```python
# Note: gradient masking gives false sense of security
# Attacks often work around it via transfer or black-box methods
class GradientMaskedModel(nn.Module):
    """Shattered gradients defense (limited effectiveness)."""
    def forward(self, x):
        x = self.features(x)
        # Clip gradients during backward pass
        x.register_hook(lambda grad: torch.where(grad.abs() > 0.1, 
                                                   torch.zeros_like(grad), grad))
        return self.classifier(x)
```

### Certified Defenses (Randomized Smoothing)

```python
class RandomizedSmoothing:
    """Certified robustness via input noise.
    Provides provable radius within which prediction is robust."""
    
    def __init__(self, base_classifier, sigma=0.25, n_samples=100):
        self.base = base_classifier
        self.sigma = sigma
        self.n = n_samples
    
    def predict(self, x):
        """Smooth prediction: add Gaussian noise and aggregate."""
        counts = torch.zeros(x.shape[0], self.base.num_classes)
        
        for _ in range(self.n):
            noise = torch.randn_like(x) * self.sigma
            logits = self.base(x + noise)
            preds = logits.argmax(dim=1)
            for i in range(x.shape[0]):
                counts[i, preds[i]] += 1
        
        return counts.argmax(dim=1)
    
    def certify_radius(self, x, n0=100, n=10000, alpha=0.001):
        """Compute certified L2 radius."""
        # Two-step: select top class with n0 samples, then certify with n samples
        pass
```

## Evaluation

```python
def evaluate_robustness(model, test_loader, attack_fn=pgd_attack, **attack_kwargs):
    """Measure robust accuracy against an attack."""
    clean_correct = 0
    robust_correct = 0
    total = 0
    
    for x, y in test_loader:
        x_adv = attack_fn(model, x, y, **attack_kwargs)
        
        clean_pred = model(x).argmax(dim=1)
        robust_pred = model(x_adv).argmax(dim=1)
        
        clean_correct += (clean_pred == y).sum().item()
        robust_correct += (robust_pred == y).sum().item()
        total += y.shape[0]
    
    print(f"Clean accuracy: {clean_correct/total:.2%}")
    print(f"Robust accuracy: {robust_correct/total:.2%}")
    return clean_correct/total, robust_correct/total
```

## Common Pitfalls

1. **Gradient masking** — defending against one attack doesn't mean robustness; always evaluate with adaptive attacks
2. **Evaluation on same attack type** — adversarial training against PGD doesn't generalize to C&W attacks
3. **Perceptual vs. adversarial distance** — a perturbation that's small in L2 norm can be visually obvious; use LPIPS for vision
4. **Adaptive attacks** — white-box attacks that know your defense will often break it; test with transfer attacks
5. **False sense of security** — no defense is 100% effective; report both attack success rate and clean accuracy drop

## Verification Checklist

- [ ] Attack reproduces published results on standard model
- [ ] Adversarial examples are visually similar to originals (or within specified perturbation budget)
- [ ] Defense degrades clean accuracy by acceptable amount
- [ ] Robust accuracy reported against multiple attack types (FGSM, PGD, C&W)
- [ ] Adaptive attack considered (defense-aware attacker)
- [ ] Certified robustness radius computed (if using certified defense)

## See Also

- agent-safety-alignment — broader AI safety considerations
- differential-privacy-training — privacy-preserving ML
- explainable-ai-xai-patterns — understanding model decisions

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…