project_banglore / validation_phase3.py
V1ShAl1613's picture
v1.0.0-stable: Voice AI Detection API - Ready for Submission
5b38c66
Raw History Blame Contribute Delete
5.35 kB
import os
import sys
import glob
import random
import joblib
import numpy as np
# Add parent to path for imports
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from app.audio.features import extract_features
print("=" * 60)
print("PHASE 3: OFFLINE PREDICTION CONSISTENCY")
print("=" * 60)
# Load model
model_path = "app/ml/voice_auth_model.pkl"
model = joblib.load(model_path)
print(f"✅ Model loaded from {model_path}")
# Set random seed for reproducibility
random.seed(42)
# Select test files
human_files = []
ai_files = []
for lang in ["tamil", "english", "hindi", "malayalam", "telugu"]:
human_lang = glob.glob(f"dataset/human/{lang}/*.wav") + glob.glob(f"dataset/human/{lang}/*.mp3")
ai_lang = glob.glob(f"dataset/ai_generated/{lang}/*.wav") + glob.glob(f"dataset/ai_generated/{lang}/*.mp3")
human_files.extend(human_lang)
ai_files.extend(ai_lang)
# Sample 5 from each
if len(human_files) < 5:
print(f"⚠️ Only {len(human_files)} human files available (need 5)")
human_sample = human_files
else:
human_sample = random.sample(human_files, 5)
if len(ai_files) < 5:
print(f"⚠️ Only {len(ai_files)} AI files available (need 5)")
ai_sample = ai_files
else:
ai_sample = random.sample(ai_files, 5)
print(f"\nTesting with {len(human_sample)} human + {len(ai_sample)} AI samples")
# Default threshold
THRESHOLD = 0.5
# Test predictions
results = []
print("\n" + "-" * 60)
print("HUMAN SAMPLES")
print("-" * 60)
for i, file_path in enumerate(human_sample, 1):
try:
features = extract_features(file_path)
features_array = np.array(features).reshape(1, -1)
# Get probability of being AI (class 1)
proba = model.predict_proba(features_array)[0]
ai_score = proba[1]
prediction = model.predict(features_array)[0]
correct = (prediction == 0) # 0 = human
filename = os.path.basename(file_path)
print(f"{i}. {filename[:40]:40s} | AI Score: {ai_score:.4f} | {'✅ CORRECT' if correct else '❌ WRONG'}")
results.append({
'file': filename,
'true_label': 'human',
'ai_score': ai_score,
'predicted': 'ai' if prediction == 1 else 'human',
'correct': correct
})
except Exception as e:
print(f"{i}. {os.path.basename(file_path):40s} | ❌ ERROR: {e}")
print("\n" + "-" * 60)
print("AI-GENERATED SAMPLES")
print("-" * 60)
for i, file_path in enumerate(ai_sample, 1):
try:
features = extract_features(file_path)
features_array = np.array(features).reshape(1, -1)
# Get probability of being AI (class 1)
proba = model.predict_proba(features_array)[0]
ai_score = proba[1]
prediction = model.predict(features_array)[0]
correct = (prediction == 1) # 1 = AI
filename = os.path.basename(file_path)
print(f"{i}. {filename[:40]:40s} | AI Score: {ai_score:.4f} | {'✅ CORRECT' if correct else '❌ WRONG'}")
results.append({
'file': filename,
'true_label': 'ai',
'ai_score': ai_score,
'predicted': 'ai' if prediction == 1 else 'human',
'correct': correct
})
except Exception as e:
print(f"{i}. {os.path.basename(file_path):40s} | ❌ ERROR: {e}")
# Calculate metrics
total = len(results)
correct = sum(1 for r in results if r['correct'])
accuracy = (correct / total * 100) if total > 0 else 0
human_scores = [r['ai_score'] for r in results if r['true_label'] == 'human']
ai_scores = [r['ai_score'] for r in results if r['true_label'] == 'ai']
print("\n" + "=" * 60)
print("RESULTS")
print("=" * 60)
print(f"Accuracy: {correct}/{total} ({accuracy:.1f}%)")
print(f"Human AI scores (should be < 0.5): {[f'{s:.3f}' for s in human_scores]}")
print(f"AI AI scores (should be > 0.5): {[f'{s:.3f}' for s in ai_scores]}")
# Check if predictions are random
all_scores = [r['ai_score'] for r in results]
avg_score = np.mean(all_scores)
std_score = np.std(all_scores)
print(f"\nScore statistics:")
print(f" Mean: {avg_score:.4f}")
print(f" Std Dev: {std_score:.4f}")
# Validation checks
issues = []
if accuracy < 80:
issues.append(f"❌ Accuracy too low: {accuracy:.1f}% < 80%")
if std_score < 0.1:
issues.append(f"⚠️ Low variance in scores ({std_score:.4f}) - may indicate random predictions")
if 0.45 <= avg_score <= 0.55 and std_score < 0.15:
issues.append("⚠️ Scores clustered around 0.5 - model may not be trained")
if len(human_scores) > 0:
avg_human = np.mean(human_scores)
if avg_human > THRESHOLD:
issues.append(f"⚠️ Human samples have high average AI score: {avg_human:.3f}")
if len(ai_scores) > 0:
avg_ai = np.mean(ai_scores)
if avg_ai < THRESHOLD:
issues.append(f"⚠️ AI samples have low average AI score: {avg_ai:.3f}")
if issues:
print("\n❌ ISSUES DETECTED:")
for issue in issues:
print(f" {issue}")
if accuracy < 80:
print("\n❌ PHASE 3 FAILED: MODEL BEHAVIOR INVALID – LIKELY NOT TRAINED")
sys.exit(1)
else:
print("\n⚠️ PHASE 3 PASSED WITH WARNINGS")
else:
print("\n✅ PHASE 3 PASSED: Model predictions are consistent and accurate")