tahamajs's picture
download
raw
3.8 kB
from typing import Tuple, Optional
import numpy as np
import joblib
import os
import librosa
from tensorflow.keras.models import load_model
def load_artifacts(models_dir: str):
artifacts = {}
scaler_path = os.path.join(models_dir, "scaler.joblib")
le_path = os.path.join(models_dir, "label_encoder.joblib")
knn_path = os.path.join(models_dir, "knn.joblib")
svm_path = os.path.join(models_dir, "svm.joblib")
rf_path = os.path.join(models_dir, "rf.joblib")
lstm_path = os.path.join(models_dir, "lstm_model.h5")
if os.path.exists(scaler_path):
artifacts["scaler"] = joblib.load(scaler_path)
if os.path.exists(le_path):
artifacts["label_encoder"] = joblib.load(le_path)
if os.path.exists(knn_path):
artifacts["knn"] = joblib.load(knn_path)
if os.path.exists(svm_path):
artifacts["svm"] = joblib.load(svm_path)
if os.path.exists(rf_path):
artifacts["rf"] = joblib.load(rf_path)
if os.path.exists(lstm_path):
artifacts["lstm"] = load_model(lstm_path)
return artifacts
def extract_classic_features(file_path: str, sample_rate: int = 22050, duration: int = 30, n_mfcc: int = 13):
y, sr = librosa.load(file_path, sr=sample_rate, duration=duration)
mfccs = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=n_mfcc)
mfccs_mean = np.mean(mfccs.T, axis=0)
mfccs_std = np.std(mfccs.T, axis=0)
zcr = np.array([np.mean(librosa.feature.zero_crossing_rate(y))])
return np.hstack([mfccs_mean, mfccs_std, zcr])
def extract_sequential(file_path: str, sample_rate: int = 22050, duration: int = 30, n_mfcc: int = 13, max_len: int = 1300):
y, sr = librosa.load(file_path, sr=sample_rate, duration=duration)
mfccs = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=n_mfcc)
mfccs = mfccs.T
if len(mfccs) < max_len:
pad_width = max_len - len(mfccs)
mfccs = np.pad(mfccs, ((0, pad_width), (0, 0)), mode="constant")
else:
mfccs = mfccs[:max_len, :]
return mfccs
def predict_file(file_path: str, models_dir: str, prefer: Optional[str] = "knn") -> Tuple[str, dict]:
artifacts = load_artifacts(models_dir)
classic = extract_classic_features(file_path)
seq = extract_sequential(file_path)
probs = {}
pred_labels = {}
le = artifacts.get("label_encoder", None)
# Classic models
scaler = artifacts.get("scaler", None)
if scaler is not None:
classic_scaled = scaler.transform(classic.reshape(1, -1))
else:
classic_scaled = classic.reshape(1, -1)
for name in ("knn", "svm", "rf"):
model = artifacts.get(name, None)
if model is None:
continue
try:
if hasattr(model, "predict_proba"):
p = model.predict_proba(classic_scaled)[0]
else:
p = np.zeros(len(le.classes_))
p[model.predict(classic_scaled)[0]] = 1.0
probs[name] = p
pred_labels[name] = model.predict(classic_scaled)[0]
except Exception:
continue
# LSTM
if "lstm" in artifacts:
try:
lstm = artifacts["lstm"]
seq_in = seq.reshape(1, seq.shape[0], seq.shape[1])
p_l = lstm.predict(seq_in)[0]
probs["lstm"] = p_l
pred_labels["lstm"] = int(p_l.argmax())
except Exception:
pass
# Choose preferred
chosen = None
if prefer and prefer in pred_labels:
chosen = pred_labels[prefer]
elif pred_labels:
# majority vote
vals = list(pred_labels.values())
chosen = max(set(vals), key=vals.count)
label_str = le.inverse_transform([chosen])[0] if (le is not None and chosen is not None) else str(chosen)
return label_str, {"preds": pred_labels, "probs": probs}

Xet Storage Details

Size:
3.8 kB
·
Xet hash:
26f0c357e8ef578ea4b2cc64bd07f32797bcdfb77a3cc9cf831c0f18745acd4a

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.