188 lines
7.5 KiB
Markdown
188 lines
7.5 KiB
Markdown
# STORY-05: Classification & Confidence Aggregation
|
||
|
||
## Epic
|
||
**E1: Core Pipeline** — I can classify face crops and aggregate video confidence.
|
||
|
||
## Related Requirements
|
||
| ID | Requirement |
|
||
|----|------|
|
||
| FR-03 | Binary demographic classification of detected face crops: Outputs probability p ∈ [0,1] for target class |
|
||
| FR-04 | Video-level confidence aggregation & threshold routing: Aggregates frame-level scores → video confidence C; Routes to MATCH, REVIEW, or SKIP |
|
||
| NFR-01 | Throughput: ≥ 30 videos/hour/GPU |
|
||
| NFR-03 | GPU Memory Safety: ≤ 18GB per GPU sustained |
|
||
| NFR-04 | Determinism & Reproducibility: Config-seeded randomness, versioned models |
|
||
| TC-01 | Hardware: 2× Tesla P40 24GB (compute capability 5.2, PCIe 3.0, no Tensor Cores) |
|
||
| TC-02 | CUDA/Torch Compatibility: CUDA ≤ 11.8, PyTorch ≤ 2.1.0, FP32 inference only |
|
||
|
||
## Description
|
||
Implement demographic classification of detected face crops using a lightweight classifier (MobileNetV3 or equivalent). Apply temperature scaling for calibrated confidence scores. Aggregate frame-level confidence to video-level confidence using configurable aggregation logic. Route videos to MATCH, REVIEW, or SKIP based on threshold comparison.
|
||
|
||
## Scope
|
||
|
||
### In Scope
|
||
- MobileNetV3 (or equivalent) classification model via TensorRT FP32
|
||
- Temperature scaling for confidence calibration
|
||
- Frame-level confidence computation (softmax with temperature)
|
||
- Video-level confidence aggregation (max or weighted mean, configurable)
|
||
- Threshold-based routing (T_high, T_low)
|
||
- Routing decision assignment (MATCH, REVIEW, SKIP)
|
||
- Confidence score persistence to DB and output files
|
||
|
||
### Out of Scope
|
||
- Frame sampling (covered in STORY-03)
|
||
- Face detection (covered in STORY-04)
|
||
- Results export format (covered in STORY-06)
|
||
- Review UI (covered in STORY-07)
|
||
- Active learning / model retraining (covered in STORY-08)
|
||
|
||
## Deliverables
|
||
|
||
### 5.1 Classification Model
|
||
**File:** `models/classifier/`
|
||
|
||
Components:
|
||
- **Source Model:** MobileNetV3-small (or equivalent lightweight classifier)
|
||
- Trained on demographic dataset (fairness considerations documented)
|
||
- Binary classification: Black male subject (class 1) vs. not (class 0)
|
||
- **ONNX Export:** `classifier.onnx`
|
||
- Input: `[1, 3, 224, 224]` (RGB, resized face crop)
|
||
- Output: `[1, 2]` (logits for class 0 and class 1)
|
||
- **TensorRT Engine:** `classifier.trt` (FP32)
|
||
- Builder config: max_batch_size=32, max_workspace_size=2GB
|
||
- **Calibration Data:** Temperature parameter T stored with model
|
||
- **Model Metadata:** `model.json` with architecture, training dataset, validation metrics
|
||
|
||
### 5.2 Classification Runner
|
||
**File:** `src/classifier.py`
|
||
|
||
Core components:
|
||
- **Model Loader:** Load TensorRT engine at startup
|
||
```python
|
||
class FaceClassifier:
|
||
def __init__(self, engine_path, temperature=1.0, device='cuda'):
|
||
self.engine = load_trt_engine(engine_path)
|
||
self.context = self.engine.create_execution_context()
|
||
self.temperature = temperature
|
||
self.input_shape = (1, 3, 224, 224)
|
||
```
|
||
- **Preprocessing:** Convert face crop to model input
|
||
- Resize to 224×224
|
||
- Normalize (ImageNet statistics)
|
||
- Convert to tensor (NCHW format)
|
||
- **Inference:** Run classification on face crops
|
||
- Dynamic batching (shared with face detection batcher)
|
||
- Execute TensorRT engine
|
||
- Get raw logits output
|
||
- **Temperature Scaling:** Apply temperature to logits before softmax
|
||
```python
|
||
def calibrated_softmax(logits, temperature):
|
||
scaled_logits = logits / temperature
|
||
return softmax(scaled_logits, axis=-1)
|
||
```
|
||
- **Frame-level Confidence:** Extract probability for target class (class 1)
|
||
```python
|
||
p_i = calibrated_probs[:, 1] # probability of target class
|
||
```
|
||
|
||
### 5.3 Confidence Aggregation
|
||
**File:** `src/aggregator.py`
|
||
|
||
Features:
|
||
- **Aggregation Strategies (configurable):**
|
||
1. **Max:** `C = max(p_i)` — use highest confidence frame
|
||
2. **Weighted Mean:** `C = softmax(α·mean(p_i) + β·var(p_i))`
|
||
3. **Top-K Mean:** `C = mean(top_k(p_i))` — average of top K confidences
|
||
- **Default Strategy:** Max (most conservative, aligns with FR-04)
|
||
- **Parameter Configuration:** α, β, K configurable in config.yaml
|
||
- **Variance Calculation:** Compute variance of frame-level confidences (for uncertainty estimation)
|
||
|
||
### 5.4 Threshold Routing
|
||
**File:** `src/router.py`
|
||
|
||
Features:
|
||
- **Threshold Comparison:**
|
||
```python
|
||
if C >= T_high: # default 0.75
|
||
routing = 'MATCH'
|
||
elif C >= T_low: # default 0.45
|
||
routing = 'REVIEW'
|
||
else:
|
||
routing = 'SKIP'
|
||
```
|
||
- **Configurable Thresholds:** T_high and T_low in config.yaml
|
||
- **Routing Decision Logging:** Log routing decision with confidence score
|
||
- **Edge Case Handling:**
|
||
- No faces detected → routing = SKIP (with confidence = 0.0)
|
||
- All frames have same confidence → routing based on threshold comparison
|
||
- Confidence exactly at threshold → use >= comparison (inclusive)
|
||
|
||
### 5.5 Configuration Updates
|
||
**File:** `config.yaml` (updates)
|
||
|
||
New fields:
|
||
```yaml
|
||
classifier:
|
||
model: mobilenetv3-small
|
||
model_path: /models/classifier/classifier.trt
|
||
input_size: 224
|
||
temperature: 1.0 # calibration temperature
|
||
default_strategy: max # max, weighted_mean, top_k_mean
|
||
|
||
aggregation:
|
||
strategy: max
|
||
alpha: 1.0 # for weighted_mean
|
||
beta: 0.1 # for weighted_mean
|
||
top_k: 3 # for top_k_mean
|
||
|
||
routing:
|
||
T_high: 0.75
|
||
T_low: 0.45
|
||
no_faces_decision: SKIP
|
||
```
|
||
|
||
## Acceptance Criteria
|
||
|
||
### Functional
|
||
- [ ] MobileNetV3 model loads and runs inference via TensorRT FP32
|
||
- [ ] Classification outputs calibrated probability p ∈ [0,1] for target class
|
||
- [ ] Temperature scaling is applied correctly (verified on test set)
|
||
- [ ] Frame-level confidence scores are deterministic (same input → same output)
|
||
- [ ] Max aggregation produces C = max(p_i) correctly
|
||
- [ ] Weighted mean aggregation produces correct result with configurable α, β
|
||
- [ ] Threshold routing assigns exactly one of: MATCH, REVIEW, SKIP
|
||
- [ ] Videos with no detected faces are routed to SKIP with confidence 0.0
|
||
- [ ] Confidence exactly at threshold uses >= comparison (inclusive)
|
||
|
||
### Non-Functional
|
||
- [ ] Classification for 16 face crops (batched) completes in < 1 second on Tesla P40
|
||
- [ ] GPU memory usage stays ≤ 18GB per GPU during classification
|
||
- [ ] Aggregation computation is negligible (< 10ms per video)
|
||
- [ ] Temperature parameter is stored with model checkpoint
|
||
- [ ] All routing decisions are logged with confidence score and threshold values
|
||
|
||
### Technical Constraints
|
||
- [ ] TensorRT engine is FP32 only
|
||
- [ ] No Tensor Cores used (CC 5.2 constraint)
|
||
- [ ] CUDA 11.8 compatible
|
||
- [ ] ONNX model exports without errors
|
||
- [ ] Confidence scores are reproducible (deterministic inference)
|
||
- [ ] Aggregation strategy is configurable without code changes
|
||
|
||
## Dependencies
|
||
- **Prerequisites:** STORY-01 (Foundation), STORY-03 (Frame Sampling), STORY-04 (Face Detection — provides crops)
|
||
- **Depends on:** None (runs after face detection)
|
||
- **Enables:** STORY-06 (Results Persistence), STORY-07 (Review UI — provides routing decisions)
|
||
|
||
## Risks & Mitigations
|
||
| Risk | Mitigation |
|
||
|------|--|
|
||
| Temperature scaling parameters need tuning | Evaluate on held-out calibration set during training cycle |
|
||
| Max aggregation may be overly conservative | Offer weighted mean as alternative; allow per-job strategy selection |
|
||
| Model bias concerns with demographic classification | Document training dataset; audit fairness metrics; legal review required |
|
||
| TensorRT engine build time | Pre-build and cache engines; version control model files |
|
||
|
||
## Estimated Effort
|
||
- **Sprint:** 5-6 (second half)
|
||
- **Story Points:** 21
|
||
- **Dependencies:** STORY-01, STORY-03, STORY-04
|