# Quick Mitigation Options for Class B Bias This document outlines immediate workarounds for the Class B bias while you retrain the model. ## Option 1: Logit-Bias Correction (Inference-Time Hack) Add this function to `main.py` in the `/analyze` endpoint before softmax: ```python def apply_logit_bias_correction(logits, bias_correction=None): """ Apply bias correction to logits before softmax. This temporarily mitigates the Class B overprediction. Args: logits: Raw model output (before softmax) bias_correction: Dict with per-class bias adjustments Returns: Adjusted logits """ if bias_correction is None: # DEFAULT: Reduce Class B, boost others bias_correction = { 0: +0.3, # Adenocarcinoma: slight boost 1: -1.2, # Small Cell: heavy penalty 2: +0.3, # Large Cell: slight boost 3: +0.3, # Squamous Cell: slight boost } for class_idx, bias in bias_correction.items(): logits[class_idx] += bias return logits ``` **Usage in classification code:** ```python # in the /analyze endpoint, after model inference: with torch.no_grad(): logits = model(input_tensor) # Raw output logits_corrected = apply_logit_bias_correction(logits[0]) # Apply correction probs = torch.softmax(logits_corrected, dim=0) # Then softmax ``` ## Option 2: Confidence-Based Filtering Add confidence thresholds per-class: ```python CONFIDENCE_THRESHOLDS = { 0: 0.30, # Adenocarcinoma: accept if >= 30% 1: 0.60, # Small Cell: require higher confidence (70%+) 2: 0.25, # Large Cell: accept lower confidence 3: 0.25, # Squamous Cell: accept lower confidence } if confidence < CONFIDENCE_THRESHOLDS[class_idx]: logger.warning(f"LOW CONFIDENCE: {class_idx} at {confidence*100:.1f}% (threshold: {CONFIDENCE_THRESHOLDS[class_idx]*100}%)") # Optionally flag as uncertain ``` ## Option 3: Report Confidence Scores Return all confidence scores to the frontend and let the UI handle the ambiguity: **API Response Structure:** ```json { "success": true, "detections": [ { "tumor_id": 1, "prediction": "Small Cell (Class B)", "confidence": 75.97, "all_confidences": { "Adenocarcinoma": 3.5, "Small Cell": 75.97, "Large Cell": 6.89, "Squamous Cell": 13.64 }, "confidence_status": "UNCERTAIN", // NEW: Add this "note": "Low confidence in this prediction. Multiple classes viable." } ] } ``` Then in Flutter UI: ```dart // Show warning if confidence is borderline if (allConfidences.values.any((c) => c > 20 && c != maxConfidence)) { showConfidenceWarning("Multiple classes possible. Review with specialist."); } ``` ## Option 4: Ensemble Multiple Models If you have other trained models: ```python def ensemble_predict(input_tensor, models_list): """Average predictions from multiple models""" all_probs = [] for model in models_list: with torch.no_grad(): probs = torch.softmax(model(input_tensor), dim=1)[0] all_probs.append(probs) ensemble_probs = torch.stack(all_probs).mean(dim=0) return ensemble_probs ``` ## Comparison of Options | Option | Ease | Effectiveness | Drawbacks | |--------|------|---------------|-----------| | **Logit Bias Correction** | ⭐⭐⭐ Easy | ⭐⭐ Moderate | Doesn't fix root issue; magic numbers | | **Confidence Filtering** | ⭐⭐⭐ Easy | ⭐⭐ Moderate | Still wrong predictions, just flagged | | **Report All Scores** | ⭐⭐⭐ Easy | ⭐⭐ Moderate | Defers to human; adds complexity | | **Ensemble Models** | ⭐⭐ Medium | ⭐⭐⭐ Good | Need multiple models | | **Retrain with Weights** | ⭐ Hard | ⭐⭐⭐⭐⭐ Excellent | Takes time; need training data | ## ⚠️ Recommendation **Use Option 3 (Report All Scores) + Option 1 (Logit Correction) as SHORT-TERM fix** - Apply light logit correction to reduce Class B dominance - Return all confidence scores to frontend - Show warnings when confidence is low (< 60%) - **Plan to retrain model properly** (highest priority) **Then retrain the model** (Option 5 - see `retrain_with_balanced_weights.py`) ## Testing Your Fix After implementing mitigation: ```bash # Test with images from each class LABELS=("Class_A" "Class_B" "Class_E" "Class_E") for label in "${LABELS[@]}"; do img=$(ls test-images/${label}_*.png | head -1) echo "Testing: $img" curl -X POST -F "file=@$img" http://localhost:5001/analyze | grep -A 10 '"prediction"' done ``` Expected results after fix: ``` Class A image → Mostly Class A (not Class B) Class B image → Mostly Class B (correct) Class E image → Mix of E and others (not all B) Class G image → Mix of G and others (not all B) ```