Why Coreset Sampling?
Without subsampling, the memory requirements would be prohibitive:Example: For a dataset with 200 training images at 224×224 resolution:
- Patches per image: 56 × 56 = 3,136
- Total patches: 200 × 3,136 = 627,200 patches
- With 1024-dim features: ~2.4 GB of memory
- Sampled patches: ~62,720 patches
- Memory: ~240 MB (10× reduction)
Sampling Strategies
PatchCore provides three sampling strategies:Identity Sampler
No sampling - uses all features
Random Sampler
Random subset selection
Greedy Coreset
Intelligent diversity-based selection
IdentitySampler
The simplest sampler that returns all features unchanged:sampler.py
Use
IdentitySampler for small datasets or when memory is not a constraint.RandomSampler
Randomly selects a percentage of features:sampler.py
GreedyCoresetSampler
The recommended sampling strategy that selects a diverse subset using a greedy farthest-point algorithm:sampler.py
Dimensionality Reduction for Speed
To accelerate distance computations, features are projected to a lower dimension:sampler.py
Core Algorithm
The greedy coreset selection algorithm:sampler.py
Algorithm Breakdown
1
Initialize
Compute full pairwise distance matrix between all features
2
Select Farthest Point
Choose the point with maximum distance to already selected points (initially, maximum norm)
3
Update Distances
For each remaining point, compute its distance to the newly selected point and update minimum distances
4
Repeat
Continue until desired number of samples is reached
Distance Computation
Efficient batched Euclidean distance calculation:sampler.py
This uses the identity: ||a - b||² = ||a||² + ||b||² - 2⟨a,b⟩ for efficient computation
ApproximateGreedyCoresetSampler
For very large feature sets, the approximate version trades some optimality for memory efficiency:sampler.py
Approximate Algorithm
sampler.py
Key Differences
Memory Efficiency
Memory Efficiency
Instead of computing the full N×N distance matrix, it:
- Starts with distances to a small random subset
- Computes distances incrementally as new points are selected
- Memory: O(N × k) instead of O(N²) where k = number of selected samples
Time Complexity
Time Complexity
- GreedyCoresetSampler: O(N²) distance computation + O(N × k) selection
- ApproximateGreedyCoresetSampler: O(N × k²) for incremental distance updates
Quality Trade-off
Quality Trade-off
The approximate version uses mean distances to random starting points for initialization, which may not find the globally optimal coreset but works well in practice.
Usage in PatchCore
Coreset sampling is applied during the training phase:patchcore.py
Configuration Examples
- Standard (Recommended)
- High Performance
- No Sampling
- Random Baseline
- Percentage: 10% (0.1)
- Method: Approximate greedy coreset
- Best for: Most use cases with >50k patches
Performance vs. Sampling Rate
Finding: Greedy coreset at 10% typically loses less than 0.1% AUROC while providing 10× speedup!
Visualization: Coreset Coverage
The greedy algorithm ensures good coverage of the feature space:Implementation Tips
Next Steps
Anomaly Scoring
Learn how the coreset memory bank is used for scoring
PatchCore Algorithm
See how coreset fits into the full pipeline
