PsalmsJava commited on
Commit
9bd70eb
·
verified ·
1 Parent(s): 212a909

Update app/model.py

Browse files
Files changed (1) hide show
  1. app/model.py +53 -45
app/model.py CHANGED
@@ -1,53 +1,61 @@
1
- import torch
2
- from transformers import Wav2Vec2FeatureExtractor, Wav2Vec2Model
3
  import numpy as np
 
 
4
 
5
- from app.features import extract_features
6
- from app.classifier import simple_rule_classifier
7
-
8
- device = "cpu"
9
-
10
  model = None
11
- feature_extractor = None
12
-
13
- def load_models():
14
- global model, feature_extractor
15
-
16
- if model is None:
17
- feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(
18
- "superb/wav2vec2-base-superb-er"
19
- )
20
-
21
- model = Wav2Vec2Model.from_pretrained(
22
- "superb/wav2vec2-base-superb-er"
23
- ).to(device)
24
-
25
-
26
- def predict(audio):
27
- # ---- Tone features ----
28
- tone_features = extract_features(audio)
29
-
30
- # ---- Deep embeddings ----
31
- inputs = feature_extractor(
32
- audio,
33
- sampling_rate=16000,
34
- return_tensors="pt",
35
- padding=True
36
- )
37
-
38
- with torch.no_grad():
39
- outputs = model(**inputs)
40
-
41
- embeddings = outputs.last_hidden_state.mean(dim=1).numpy()[0]
42
-
43
- # ---- Combine ----
44
- combined = np.hstack([tone_features, embeddings])
45
-
46
- # ---- Classify ----
47
- emotion, confidence = simple_rule_classifier(tone_features)
 
 
 
 
 
 
 
 
 
 
48
 
49
  return {
50
- "emotion_label": emotion,
51
  "confidence": confidence,
52
  "note": "Tone-based prediction (less text bias)"
53
  }
 
1
+ # app/model.py
2
+ import joblib
3
  import numpy as np
4
+ import librosa
5
+ import os
6
 
7
+ # Global placeholders
 
 
 
 
8
  model = None
9
+ scaler = None
10
+
11
+ # ==========================
12
+ # Load Model and Scaler
13
+ # ==========================
14
+ def load_models(model_path="emotion_model.pkl", scaler_path="scaler.pkl"):
15
+ global model, scaler
16
+ if not os.path.exists(model_path) or not os.path.exists(scaler_path):
17
+ raise FileNotFoundError("Model or scaler .pkl files not found. Upload them to the app directory.")
18
+ model = joblib.load(model_path)
19
+ scaler = joblib.load(scaler_path)
20
+ print("✅ Tone-based emotion model loaded successfully.")
21
+
22
+ # ==========================
23
+ # Feature extraction
24
+ # ==========================
25
+ def extract_features(audio_path):
26
+ """
27
+ Extract tone-based features from audio:
28
+ - MFCC
29
+ - Pitch
30
+ - Energy
31
+ """
32
+ audio, sr = librosa.load(audio_path, sr=16000)
33
+ mfcc = librosa.feature.mfcc(y=audio, sr=sr, n_mfcc=13)
34
+ mfcc_mean = np.mean(mfcc, axis=1)
35
+ pitches, magnitudes = librosa.piptrack(y=audio, sr=sr)
36
+ pitch = np.mean(pitches[pitches > 0]) if np.any(pitches > 0) else 0
37
+ energy = np.mean(librosa.feature.rms(y=audio))
38
+ return np.hstack([mfcc_mean, pitch, energy])
39
+
40
+ # ==========================
41
+ # Predict Emotion
42
+ # ==========================
43
+ def predict_tone(audio_path):
44
+ global model, scaler
45
+ if model is None or scaler is None:
46
+ raise RuntimeError("Model and scaler must be loaded first.")
47
+
48
+ features = extract_features(audio_path).reshape(1, -1)
49
+ features_scaled = scaler.transform(features)
50
+ pred_label = model.predict(features_scaled)[0]
51
+ pred_proba = model.predict_proba(features_scaled)[0]
52
+
53
+ # Confidence of the predicted class
54
+ pred_index = np.argmax(pred_proba)
55
+ confidence = float(pred_proba[pred_index])
56
 
57
  return {
58
+ "emotion_label": pred_label,
59
  "confidence": confidence,
60
  "note": "Tone-based prediction (less text bias)"
61
  }