Out-of-Distribution Detection Anomaly Likelihood Confidence Estimation

# Out-of-Distribution Detection: Anomaly Likelihood & Confidence Estimation

## Introduction & Motivation

OOD detection identifies when inputs differ from training distribution. Likelihood-based: lower density → OOD. Confidence-based: low model confidence → OOD. Distance-based: Mahalanobis distance in feature space. Critical for safe deployment, adversarial robustness.

Motivation: Models confident on OOD examples; dangerous in production. Detect and reject uncertain inputs or flag for human review.

Applications: Autonomous driving safety, medical imaging, fraud detection, adversarial robustness.

---

## Core Concepts & Theory

### Density-Based OOD

Estimate P(x); threshold on log-likelihood.

### Confidence-Based OOD

Use softmax entropy; high entropy → OOD.

### Distance-Based OOD

Mahalanobis distance in learned representation.

---

## Mathematical Formulation

Log-likelihood threshold:
$$ ext{OOD if } \log p(x) < au$$

Entropy-based:
$$H(\hat{p}) = -\sum_c \hat{p}_c \log \hat{p}_c$$
$$ ext{OOD if } H(\hat{p}) > au$$

Mahalanobis distance:
$$D_M(x) = \sqrt{(f(x) - \mu)^T \Sigma^{-1} (f(x) - \mu)}$$

where f(x) = feature representation, μ, Σ = class statistics.

---

## Advanced Theory & Extensions

### Energy-Based OOD Detection

Use unnormalized scores; more stable than softmax.

### Outlier Exposure

Train discriminator between ID and diverse OOD samples.

### ODIN (Temperature Scaling + Gradient)

Input perturbation; amplifies model confidence gap.

---

## Computational Considerations

Likelihood computation: O(d) for Gaussian; O(d³) for covariance.

Mahalanobis: O(d²) per-class; O(cd) total.

Online adaptation: Update μ, Σ incrementally.

---

## Practical Implementation Strategies

### Calibration

Train OOD detector threshold on validation OOD samples.

### Baseline Diversity

Use multiple baseline methods; ensemble for robustness.

### Computational Efficiency

Use efficient covariance estimates (diagonal, low-rank).

---

## Benchmark Datasets & Evaluation

ImageNet vs SVHN/Texture: Standard OOD benchmark.

MNIST vs Fashion-MNIST: Classic anomaly detection.

Metrics: AUROC, AUPR, FPR@95%TPR.

---

## Key Challenges & Limitations

### Diverse OOD

Single threshold doesn't work for all OOD types.

### Computational Cost

Mahalanobis requires O(d²) storage; scalability issues.

### Training-Test Mismatch

OOD characteristics differ at test time.

---

## Hyperparameter Tuning

Threshold τ: Grid search on validation OOD.

Temperature T: 0.1-5.0; higher = flatter probabilities.

Gaussian parameters: Diagonal vs. full covariance.

---

## Real-World Applications & Case Studies

Autonomous Driving: Detect unfamiliar road conditions; fallback to human.

Medical: Reject images outside training distribution; avoid errors.

Finance: Flag unusual transactions; prevent fraud.

---

## Integration with Other Methods

OOD + Uncertainty → epistemic vs. aleatoric uncertainty.

OOD + Active Learning → query unusual examples for labeling.

---

## Summary & Key Takeaways

OOD detection uses likelihood, confidence, or distance-based methods to identify inputs outside training distribution.

Principles:
1. Density-based: threshold on log-likelihood.
2. Confidence-based: softmax entropy or energy scores.
3. Distance-based: Mahalanobis in feature space.
4. Calibration essential; validate on diverse OOD.
5. Ensemble multiple methods for robustness.

---

---

## Appendix: Practical Labs

### Lab 1: Gaussian Likelihood OOD Detection

import numpy as np
from scipy.stats import multivariate_normal

def gaussian_likelihood_ood(X_train, X_test, threshold=None):
 """Fit Gaussian to train; score test samples"""
 mean = X_train.mean(axis=0)
 cov = np.cov(X_train.T)
 
 dist = multivariate_normal(mean=mean, cov=cov)
 log_probs = dist.logpdf(X_test)
 
 if threshold is None:
 threshold = np.percentile(dist.logpdf(X_train), 5)
 
 ood_scores = -log_probs
 return ood_scores, threshold

# Data
np.random.seed(42)
X_train = np.random.randn(100, 5)
X_id_test = np.random.randn(20, 5)
X_ood_test = np.random.randn(20, 5) * 3 # Shifted

scores_id, threshold = gaussian_likelihood_ood(X_train, X_id_test)
scores_ood, _ = gaussian_likelihood_ood(X_train, X_ood_test, threshold)

id_detected = (scores_id < threshold).sum()
ood_detected = (scores_ood > threshold).sum()

print(f"ID correctly detected as ID: {id_detected}/20")
print(f"OOD correctly detected as OOD: {ood_detected}/20")
assert id_detected > 5, "Should detect some ID samples"
assert ood_detected > 5, "Should detect some OOD samples"
print("✓ Gaussian likelihood OOD working")

if __name__ == "__main__":
 print("Lab 1: Gaussian Likelihood - PASSED")

### Lab 2: Entropy-Based OOD

import numpy as np

def entropy_ood(probs, threshold=None):
 """Detect OOD via softmax entropy"""
 entropy = -np.sum(probs * np.log(probs + 1e-8), axis=1)
 
 if threshold is None:
 threshold = np.mean(entropy)
 
 is_ood = entropy > threshold
 return entropy, threshold, is_ood

# Data: ID is confident, OOD is uncertain
np.random.seed(42)
probs_id = np.random.dirichlet([10, 1, 1], 20) # Confident
probs_ood = np.random.dirichlet([1, 1, 1], 20) # Uniform

entropy_id, threshold, _ = entropy_ood(probs_id)
entropy_ood_val, _, is_ood_detected = entropy_ood(probs_ood, threshold)

print(f"ID entropy: {entropy_id.mean():.4f}")
print(f"OOD entropy: {entropy_ood_val.mean():.4f}")
print(f"OOD detected: {is_ood_detected.sum()}/20")
assert entropy_id.mean() < entropy_ood_val.mean(), "OOD should have higher entropy"
print("✓ Entropy-based OOD working")

if __name__ == "__main__":
 print("Lab 2: Entropy OOD - PASSED")

### Lab 3: Mahalanobis Distance OOD

import numpy as np
from scipy.spatial.distance import mahalanobis

def mahalanobis_ood(X_train, X_test, y_train=None):
 """Compute Mahalanobis distance; lower = ID, higher = OOD"""
 if y_train is not None:
 # Per-class statistics
 classes = np.unique(y_train)
 min_distances = []
 for x in X_test:
 dists = []
 for c in classes:
 X_c = X_train[y_train == c]
 mu_c = X_c.mean(axis=0)
 cov_c = np.cov(X_c.T)
 d = mahalanobis(x, mu_c, np.linalg.inv(cov_c + np.eye(X_c.shape[1])*1e-6))
 dists.append(d)
 min_distances.append(min(dists))
 else:
 mu = X_train.mean(axis=0)
 cov = np.cov(X_train.T)
 cov_inv = np.linalg.inv(cov + np.eye(X_train.shape[1])*1e-6)
 min_distances = [mahalanobis(x, mu, cov_inv) for x in X_test]
 
 return np.array(min_distances)

# Data
np.random.seed(42)
X_train = np.random.randn(100, 5)
y_train = np.random.randint(0, 2, 100)
X_test_id = np.random.randn(20, 5)
X_test_ood = np.random.randn(20, 5) * 5

dist_id = mahalanobis_ood(X_train, X_test_id, y_train)
dist_ood = mahalanobis_ood(X_train, X_test_ood, y_train)

print(f"ID Mahalanobis: {dist_id.mean():.3f}")
print(f"OOD Mahalanobis: {dist_ood.mean():.3f}")
assert dist_id.mean() < dist_ood.mean(), "OOD should have larger distance"
print("✓ Mahalanobis OOD working")

if __name__ == "__main__":
 print("Lab 3: Mahalanobis - PASSED")

### Lab 4: OOD Detection Evaluation

import numpy as np
from sklearn.metrics import roc_auc_score, roc_curve

def evaluate_ood_detection(scores_id, scores_ood):
 """AUROC: higher score = OOD"""
 y_true = np.concatenate([np.zeros(len(scores_id)), np.ones(len(scores_ood))])
 scores = np.concatenate([scores_id, scores_ood])
 
 auroc = roc_auc_score(y_true, scores)
 fpr, tpr, _ = roc_curve(y_true, scores)
 
 # FPR@95%TPR
 idx_95 = np.argmin(np.abs(tpr - 0.95))
 fpr_95 = fpr[idx_95]
 
 return auroc, fpr_95

# Data
np.random.seed(42)
scores_id = np.random.randn(100) * 0.5
scores_ood = np.random.randn(100) * 0.5 + 2 # Higher scores

auroc, fpr95 = evaluate_ood_detection(scores_id, scores_ood)
print(f"AUROC: {auroc:.4f}, FPR@95TPR: {fpr95:.4f}")
assert 0 <= auroc <= 1, "AUROC should be in [0,1]"
assert 0 <= fpr95 <= 1, "FPR should be in [0,1]"
print("✓ OOD evaluation working")

if __name__ == "__main__":
 print("Lab 4: Evaluation - PASSED")

Go deeper with CFSGPT

Get AI-powered deep-dives, save terms, and run advanced simulations — free account.

Create Free Account