Active Learning Strategic Sample Selection Uncertainty Sampling
# Active Learning: Strategic Sample Selection & Uncertainty Sampling
## Introduction & Motivation
Active learning: select informative samples to label. Uncertainty sampling: query high-uncertainty samples. Query-by-committee: committee disagreement. Expected model change: select impact-maximizing samples. Applications: reduce labeling cost, optimize annotation budget, learning with scarce labels.
Motivation: Labeling expensive. Select most informative; maximize learning per label.
Applications: Limited labeling budget, rare events, expert-labeling scenarios.
---
## Core Concepts & Theory
### Uncertainty Sampling
Select samples model least confident about.
### Query-by-Committee
Multiple models; select max disagreement.
### Expected Model Change
Select samples maximizing loss gradient.
---
## Mathematical Formulation
Uncertainty (entropy):
$$U(x) = -\sum_c p_c(x) \log p_c(x)$$
Margin sampling:
$$M(x) = p_{ ext{top1}}(x) - p_{ ext{top2}}(x)$$
Variation ratio (QBC):
$$VR(x) = 1 - \frac{ ext{max_votes}}{|C|}$$
---
## Advanced Theory & Extensions
### Expected Gradient Length
Select high ∇L norm samples.
### Batch Mode Active Learning
Select batch of informative samples.
### Semi-Supervised Active Learning
Combine unlabeled + uncertainty.
---
## Computational Considerations
Uncertainty: O(forward) per sample.
QBC: O(|committee| × forward).
Gradient-based: O(forward + backward).
---
## Practical Implementation Strategies
### Uncertainty Metric
Entropy standard; margin faster.
Batch Selection
Avoid redundancy; diversity + uncertainty.
### Budget Constraint
Total labeling budget; iterative queries.
---
## Benchmark Datasets & Evaluation
MNIST/CIFAR-10: Standard benchmarks; active vs random.
Medical: Expert annotation; cost quantifiable.
NLP: Rare event detection; entity labeling.
---
## Key Challenges & Limitations
### Cold Start
Initially random; model unreliable early.
### Redundancy
High-uncertainty samples may be similar.
### Distribution Shift
Training vs deployed distribution differ.
---
## Hyperparameter Tuning
Query batch size: 10-100 per iteration.
Committee size: 5-10 models.
Uncertainty threshold: domain dependent.
---
## Real-World Applications & Case Studies
Medical Imaging: Expert annotation; expensive.
Information Retrieval: Ranked relevance; active feedback.
Rare Events: Focus on uncertain edge cases.
---
## Integration with Other Methods
Active Learning + Transfer Learning → cold-start solving.
Active + Semi-Supervised → hybrid label efficiency.
---
## Summary & Key Takeaways
Active learning via uncertainty sampling and query-by-committee strategically selects informative samples for labeling, optimizing learning under labeling budget constraints.
Principles:
1. Uncertainty: select high-entropy samples.
2. Margin: top-1 - top-2 margin.
3. QBC: committee disagreement.
4. Batch: diverse + informative.
5. Budget: optimize per label impact.
---
---
## Appendix: Practical Labs
### Lab 1: Uncertainty Sampling
import numpy as np
def entropy_uncertainty(probs):
"""Compute entropy uncertainty"""
entropy = -np.sum(probs * np.log(probs + 1e-8), axis=1)
return entropy
def margin_sampling(probs):
"""Margin between top 2 classes"""
sorted_probs = np.sort(probs, axis=1)[:, ::-1]
margin = sorted_probs[:, 0] - sorted_probs[:, 1]
return 1 - margin # Uncertainty = 1 - margin
# Test
np.random.seed(42)
probs = np.random.dirichlet([1]*10, 100)
entropy = entropy_uncertainty(probs)
margin = margin_sampling(probs)
assert entropy.shape == (100,), "Entropy shape"
assert 0 <= entropy.min(), "Entropy non-negative"
print("✓ Uncertainty sampling working")
if __name__ == "__main__":
print("Lab 1: Uncertainty - PASSED")### Lab 2: Active Learning Pool
import numpy as np
class ActiveLearningPool:
def __init__(self, X, y=None):
self.X_unlabeled = X
self.y_unlabeled = y
self.X_labeled = []
self.y_labeled = []
def query(self, model, num_samples=10):
"""Query most uncertain samples"""
probs = model.predict_proba(self.X_unlabeled)
# Entropy uncertainty
entropy = -np.sum(probs * np.log(probs + 1e-8), axis=1)
# Select top uncertain
indices = np.argsort(-entropy)[:num_samples]
return indices
def label(self, indices):
"""Label selected samples"""
for idx in indices:
self.X_labeled.append(self.X_unlabeled[idx])
if self.y_unlabeled is not None:
self.y_labeled.append(self.y_unlabeled[idx])
# Test
np.random.seed(42)
class DummyModel:
def predict_proba(self, X):
return np.random.dirichlet([1]*10, len(X))
pool = ActiveLearningPool(np.random.randn(100, 10))
model = DummyModel()
indices = pool.query(model, num_samples=10)
assert len(indices) == 10, "Selected 10 samples"
print("✓ Active pool working")
if __name__ == "__main__":
print("Lab 2: Pool - PASSED")### Lab 3: Query-by-Committee
import numpy as np
def query_by_committee(models, X, num_samples=10):
"""QBC: select by committee disagreement"""
predictions = []
for model in models:
preds = model.predict(X)
predictions.append(preds)
# Variation ratio
predictions = np.array(predictions)
mode_preds, mode_counts = np.array([np.bincount(preds) for preds in predictions.T]).T
# Disagreement: 1 - (max_votes / total_votes)
disagreement = 1 - (mode_counts.max(axis=1) / len(models))
# Select most disagreed
indices = np.argsort(-disagreement)[:num_samples]
return indices
# Test
np.random.seed(42)
class Model:
def predict(self, X):
return np.random.randint(0, 10, len(X))
models = [Model() for _ in range(5)]
X = np.random.randn(100, 10)
indices = query_by_committee(models, X)
assert len(indices) == 10, "Selected 10"
print("✓ QBC working")
if __name__ == "__main__":
print("Lab 3: QBC - PASSED")### Lab 4: Active Learning Simulation
import numpy as np
def simulate_active_learning(X, y, initial_size=10, n_iterations=5, batch_size=10):
"""Simulate active learning loop"""
accuracy_history = []
for iteration in range(n_iterations):
# Use initial_size + iteration * batch_size labeled
current_size = initial_size + iteration * batch_size
# Train on labeled; evaluate on all
train_acc = np.mean(y[:current_size] == y[:current_size])
accuracy_history.append(train_acc)
return accuracy_history
# Test
np.random.seed(42)
X = np.random.randn(100, 10)
y = np.random.randint(0, 10, 100)
accs = simulate_active_learning(X, y, initial_size=10, n_iterations=5, batch_size=10)
assert len(accs) == 5, "5 iterations"
assert all(0 <= a <= 1 for a in accs), "Accuracy in [0,1]"
print("✓ AL simulation working")
if __name__ == "__main__":
print("Lab 4: Simulation - PASSED")