KasaHealth / predict_user_file.py
78anand's picture
Upload folder using huggingface_hub
4fcfef4 verified
import os
import sys
import numpy as np
import librosa
import tensorflow as tf
from tensorflow.keras.models import load_model
# Ensure we can import utils
sys.path.append(os.getcwd())
try:
from utils.hear_extractor import HeARExtractor
from utils.audio_preprocessor import advanced_preprocess
except ImportError:
sys.path.append(os.path.dirname(os.getcwd()))
from utils.hear_extractor import HeARExtractor
from utils.audio_preprocessor import advanced_preprocess
# Configuration
MODEL_PATH = r"c:\Users\ASUS\lung_ai_project\models\hear_classifier_advanced.h5"
CLASSES_PATH = r"c:\Users\ASUS\lung_ai_project\models\hear_classes_advanced.npy"
USER_FILE = r"C:\Users\ASUS\Downloads\WhatsApp Audio 2026-02-23 at 6.09.14 PM.wav"
def predict_single_file(file_path):
print(f"\n--- Analyzing Audio: {os.path.basename(file_path)} ---")
if not os.path.exists(file_path):
print(f"Error: File not found at {file_path}")
return
# 1. Initialize Extractor
print("Initializing HeAR Extractor...")
try:
extractor = HeARExtractor()
except Exception as e:
print(f"Failed to load HeAR model: {e}")
return
# 2. Load Evaluation Model
print(f"Loading Model from {MODEL_PATH}...")
try:
model = load_model(MODEL_PATH, compile=False)
classes = np.load(CLASSES_PATH)
print(f"Classes: {classes}")
except Exception as e:
print(f"Error loading model: {e}")
return
# 3. Process & Predict
try:
# Load Audio
print("Loading and preprocessing audio...")
y, sr = librosa.load(file_path, sr=16000, duration=5.0)
# --- NEW: Audio Validation (Gatekeeper) ---
from utils.audio_validator import validate_audio_is_cough
is_valid_cough, reason, val_conf = validate_audio_is_cough(y, sr)
if not is_valid_cough:
print("\n" + "="*50)
print(f"REJECTED: Audio Validation Failed!")
print(f"REASON: {reason}")
print(f"RECOMMENDATION: Please record a clear, loud cough in a quiet room.")
print("="*50)
return
# Apply Advanced Preprocessing (Critical for correct result!)
y_clean = advanced_preprocess(y, sr)
# Extract Embedding
print("Extracting features...")
emb = extractor.extract(y_clean)
if emb is not None:
# 4. Predict
print("Step 4: Running Inference...")
try:
X = emb[np.newaxis, ...]
preds = model.predict(X, verbose=0)
pred_idx = np.argmax(preds[0])
raw_label = classes[pred_idx]
confidence = preds[0][pred_idx]
# --- Reliability Guard ---
THRESHOLD = 0.70
if raw_label == "sick" and confidence < THRESHOLD:
print(f"DEBUG: Borderline result ({confidence:.2f}). Applying reliability guard.")
final_label = "healthy"
is_inconclusive = True
else:
final_label = raw_label
is_inconclusive = False
except Exception as e:
print(f"Error during inference: {e}")
return
print("\n" + "="*50)
if is_inconclusive:
print(f"RESULT: HEALTHY (Normal Pattern)")
print(f"NOTE: Prediction was borderline ({confidence*100:.1f}%).")
print("Reliability guard applied: No strong abnormal indicators found.")
else:
print(f"RESULT: {final_label.upper()}")
print(f"CONFIDENCE: {confidence*100:.2f}%")
print("="*50)
# Simple interpretation
if final_label == "sick":
print("Recommendation: Potential respiratory symptoms detected. Consider medical consultation.")
else:
if is_inconclusive:
print("Recommendation: Recording had minor artifacts but appears normal. Re-record in a quiet room for better accuracy.")
else:
print("Recommendation: Acoustic pattern appears healthy. Continue monitoring if symptoms persist.")
else:
print("Error: Could not extract features from audio.")
except Exception as e:
print(f"Detailed Error: {e}")
if __name__ == "__main__":
predict_single_file(USER_FILE)