kxrthik05 commited on
Commit
dcf0cb1
·
verified ·
1 Parent(s): 9ad51f8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +201 -86
app.py CHANGED
@@ -1,12 +1,12 @@
1
  # app.py
2
- # Accent Detection + Cuisine Recommendation (MFCC + HuBERT)
3
 
4
  import os
5
  from pathlib import Path
6
  import pickle
7
  import numpy as np
8
  import librosa
9
- import soundfile as sf # imported so soundfile is available if needed
10
 
11
  from sklearn.preprocessing import StandardScaler, LabelEncoder
12
  from sklearn.linear_model import LogisticRegression # noqa: F401
@@ -23,96 +23,209 @@ except Exception:
23
  DEFAULT_SR = 16000
24
  CHECKPOINT_DIR = Path("checkpoints")
25
 
26
- # ---------- Cuisine mapping ----------
 
 
27
 
28
  CUISINE_MAP = {
29
- "hindi": {
30
- "region": "North India",
31
- "starters_veg": ["Paneer Tikka", "Veg Samosa"],
32
- "starters_nonveg": ["Chicken 65", "Mutton Seekh Kebab"],
33
- "main_veg": ["Paneer Butter Masala", "Dal Makhani", "Aloo Paratha"],
34
- "main_nonveg": ["Butter Chicken", "Rogan Josh", "Mutton Biryani"],
35
- "desserts": ["Gulab Jamun", "Kheer"],
36
- },
37
- "telugu": {
38
- "region": "Andhra Pradesh / Telangana",
39
- "starters_veg": ["Mirchi Bajji", "Pesarattu"],
40
- "starters_nonveg": ["Gongura Chicken Fry", "Fish Fry"],
41
- "main_veg": ["Pappu with Rice", "Gutti Vankaya", "Pulihora"],
42
- "main_nonveg": ["Andhra Chicken Biryani", "Kodi Pulusu"],
43
- "desserts": ["Bobbatlu", "Pootharekulu"],
44
- },
45
- "tamil": {
46
- "region": "Tamil Nadu",
47
- "starters_veg": ["Medu Vada", "Sundal"],
48
- "starters_nonveg": ["Chicken 65 (TN style)", "Fish Fry"],
49
- "main_veg": ["Idli & Sambar", "Masala Dosa", "Rasam Rice"],
50
- "main_nonveg": ["Chettinad Chicken", "Fish Curry (Meen Kuzhambu)"],
51
- "desserts": ["Payasam", "Kesari"],
52
  },
 
53
  "kerala": {
54
  "region": "Kerala",
55
- "starters_veg": ["Banana Chips", "Uzhunnu Vada"],
56
- "starters_nonveg": ["Kerala Fish Fry", "Chicken 65 (Kerala Style)"],
57
- "main_veg": ["Appam with Veg Stew", "Puttu with Kadala Curry"],
58
- "main_nonveg": ["Kerala Fish Curry", "Beef Ularthiyathu", "Chicken Stew"],
59
- "desserts": ["Palada Payasam", "Ada Pradhaman"],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  },
61
- "kannada": {
62
- "region": "Karnataka",
63
- "starters_veg": ["Maddur Vada", "Bonda"],
64
- "starters_nonveg": ["Kheema Cutlet"],
65
- "main_veg": ["Bisi Bele Bath", "Ragi Mudde", "Akki Roti"],
66
- "main_nonveg": ["Mangalorean Chicken Curry", "Neer Dosa with Fish Curry"],
67
- "desserts": ["Mysore Pak", "Kesari"],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  },
69
- "bengali": {
70
- "region": "West Bengal",
71
- "starters_veg": ["Vegetable Chop"],
72
- "starters_nonveg": ["Fish Kabiraji", "Chicken Pakora"],
73
- "main_veg": ["Shukto", "Cholar Dal with Luchi"],
74
- "main_nonveg": ["Machher Jhol", "Ilish Bhapa"],
75
- "desserts": ["Mishti Doi", "Rasgulla"],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  "default": {
78
  "region": "Unknown / Other",
79
  "starters_veg": ["Local vegetarian starters"],
80
- "starters_nonveg": ["Local non-veg starters"],
81
  "main_veg": ["Local vegetarian mains"],
82
- "main_nonveg": ["Local non-veg mains"],
83
  "desserts": ["Local desserts"],
84
  },
85
  }
86
 
87
- # Map various predicted labels / codes to cuisine keys
 
 
 
88
  LABEL_ALIAS = {
89
- # Hindi
90
- "hi": "hindi",
91
- "hindi": "hindi",
92
- "hindi_india": "hindi",
93
- # Telugu
94
- "te": "telugu",
95
- "telugu": "telugu",
96
- "telugu_india": "telugu",
97
- # Tamil
98
- "ta": "tamil",
99
- "tamil": "tamil",
100
- "tamil_india": "tamil",
101
- # Bengali
102
- "bn": "bengali",
103
- "bengali": "bengali",
104
- "bengali_india": "bengali",
105
- # Kannada
106
- "kn": "kannada",
107
- "kannada": "kannada",
108
- "kannada_india": "kannada",
109
- # Malayalam / Kerala
110
  "ml": "kerala",
111
  "malayalam": "kerala",
112
- "kerala": "kerala",
113
  "kerala_malayalam": "kerala",
114
- }
115
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
 
117
  def format_cuisine_output(pred_label: str) -> str:
118
  # Normalise raw predicted label and map through alias
@@ -131,8 +244,9 @@ def format_cuisine_output(pred_label: str) -> str:
131
  lines.append("Desserts: " + ", ".join(info["desserts"]))
132
  return "\n".join(lines)
133
 
134
-
135
- # ---------- Audio & feature helpers ----------
 
136
 
137
  def normalize_audio_path(audio):
138
  if audio is None:
@@ -160,7 +274,7 @@ _hf_model = None
160
 
161
  def get_hubert_layer_embedding(path: str, layer_idx: int = 11) -> np.ndarray:
162
  """
163
- Uses facebook/hubert-large-ll60k (hidden size 1024, matching your scaler_hubert.pkl).
164
  Returns a 1024‑dim vector: mean‑pooled over time from the chosen layer.
165
  """
166
  global _hf_feat, _hf_model
@@ -180,7 +294,7 @@ def get_hubert_layer_embedding(path: str, layer_idx: int = 11) -> np.ndarray:
180
  with torch.no_grad():
181
  out = _hf_model(**inputs)
182
 
183
- hidden_states = out.hidden_states # list[Tensor(batch,time,dim)]
184
  hs = hidden_states[layer_idx] # (batch, time, dim)
185
 
186
  if hs.ndim == 3:
@@ -189,14 +303,14 @@ def get_hubert_layer_embedding(path: str, layer_idx: int = 11) -> np.ndarray:
189
  vec = hs.mean(dim=0).cpu().numpy()
190
  return vec
191
 
192
-
193
- # ---------- Load models from checkpoints ----------
 
194
 
195
  app_state = {"models": {}}
196
 
197
-
198
  def load_models():
199
- # MFCC
200
  try:
201
  with open(CHECKPOINT_DIR / "clf_mfcc.pkl", "rb") as f:
202
  clf_mfcc = pickle.load(f)
@@ -213,7 +327,7 @@ def load_models():
213
  except Exception as e:
214
  print("Could not load MFCC model:", e)
215
 
216
- # HuBERT
217
  try:
218
  with open(CHECKPOINT_DIR / "clf_hubert.pkl", "rb") as f:
219
  clf_h = pickle.load(f)
@@ -236,11 +350,11 @@ def load_models():
236
  except Exception as e:
237
  print("Could not load HuBERT model:", e)
238
 
239
-
240
  load_models()
241
 
242
-
243
- # ---------- Prediction logic ----------
 
244
 
245
  def predict_accent_and_cuisine(audio_file, feature_choice, hubert_layer_idx, use_trained):
246
  audio_path = normalize_audio_path(audio_file)
@@ -269,7 +383,7 @@ def predict_accent_and_cuisine(audio_file, feature_choice, hubert_layer_idx, use
269
  if feat == "mfcc":
270
  x = extract_mfcc_pooled(audio_path)
271
  else:
272
- # use trained HuBERT layer if saved, otherwise slider value
273
  trained_layer = model_info.get("layer", hubert_layer_idx)
274
  x = get_hubert_layer_embedding(audio_path, layer_idx=trained_layer)
275
  except Exception as e:
@@ -286,8 +400,9 @@ def predict_accent_and_cuisine(audio_file, feature_choice, hubert_layer_idx, use
286
  cuisine_text = format_cuisine_output(pred_label)
287
  return pred_label, cuisine_text
288
 
289
-
290
- # ---------- Gradio UI ----------
 
291
 
292
  with gr.Blocks() as demo:
293
  gr.Markdown("# Accent Detection & Cuisine Recommendation")
 
1
  # app.py
2
+ # Accent Detection + Regional Cuisine Recommendation (MFCC + HuBERT)
3
 
4
  import os
5
  from pathlib import Path
6
  import pickle
7
  import numpy as np
8
  import librosa
9
+ import soundfile as sf # noqa: F401
10
 
11
  from sklearn.preprocessing import StandardScaler, LabelEncoder
12
  from sklearn.linear_model import LogisticRegression # noqa: F401
 
23
  DEFAULT_SR = 16000
24
  CHECKPOINT_DIR = Path("checkpoints")
25
 
26
+ # ---------------------------------------------------------------------
27
+ # 1. CUISINE MAP (based on your exact dishes)
28
+ # ---------------------------------------------------------------------
29
 
30
  CUISINE_MAP = {
31
+ "andhra_pradesh": {
32
+ "region": "Andhra Pradesh",
33
+ "starters_veg": [
34
+ "Pesarattu (green gram dosa)"
35
+ ],
36
+ "starters_nonveg": [
37
+ "Kodi Vepudu (Andhra chicken fry)",
38
+ "Royyala Vepudu (prawn fry)"
39
+ ],
40
+ "main_veg": [
41
+ "Pulihora",
42
+ "Ulava Charu with Rice"
43
+ ],
44
+ "main_nonveg": [
45
+ "Gongura Mutton",
46
+ "Andhra Chicken Curry / Kodi Kura"
47
+ ],
48
+ "desserts": [
49
+ "Bobbatlu (Puran Poli)",
50
+ "Pootharekulu",
51
+ "Paramannam (rice kheer)"
52
+ ],
 
53
  },
54
+
55
  "kerala": {
56
  "region": "Kerala",
57
+ "starters_veg": [
58
+ "Banana Chips"
59
+ ],
60
+ "starters_nonveg": [
61
+ "Erachi Fry (Beef Fry)",
62
+ "Fish Cutlets"
63
+ ],
64
+ "main_veg": [
65
+ "Puttu & Kadala Curry",
66
+ "Appam with Veg Stew",
67
+ "Kerala Sadya"
68
+ ],
69
+ "main_nonveg": [
70
+ "Karimeen Pollichathu",
71
+ "Kerala Fish Curry"
72
+ ],
73
+ "desserts": [
74
+ "Palada Payasam",
75
+ "Ada Pradhaman",
76
+ "Elaneer Payasam"
77
+ ],
78
  },
79
+
80
+ "gujarat": {
81
+ "region": "Gujarat",
82
+ "starters_veg": [
83
+ "Dhokla",
84
+ "Khandvi",
85
+ "Sev Khamani"
86
+ ],
87
+ "starters_nonveg": [
88
+ "Local non‑veg starters (rare in traditional cuisine)"
89
+ ],
90
+ "main_veg": [
91
+ "Undhiyu",
92
+ "Thepla",
93
+ "Dal Dhokli",
94
+ "Sev Tameta Nu Shaak"
95
+ ],
96
+ "main_nonveg": [
97
+ "Local non‑veg mains (if available)"
98
+ ],
99
+ "desserts": [
100
+ "Basundi",
101
+ "Shrikhand",
102
+ "Mohanthal"
103
+ ],
104
+ },
105
+
106
+ "jharkhand": {
107
+ "region": "Jharkhand",
108
+ "starters_veg": [
109
+ "Dhuska",
110
+ "Chilka Roti",
111
+ "Rugra Fry (mushroom fry)"
112
+ ],
113
+ "starters_nonveg": [
114
+ "Local non‑veg starters"
115
+ ],
116
+ "main_veg": [
117
+ "Bamboo Shoot Curry",
118
+ "Kadho (local dal curry)",
119
+ "Litti‑Chokha"
120
+ ],
121
+ "main_nonveg": [
122
+ "Local non‑veg curries",
123
+ "Handia (served with meals)"
124
+ ],
125
+ "desserts": [
126
+ "Thekua",
127
+ "Tilkut",
128
+ "Malpua (Jharkhand style)"
129
+ ],
130
  },
131
+
132
+ "tamil_nadu": {
133
+ "region": "Tamil Nadu",
134
+ "starters_veg": [
135
+ "Medu Vada",
136
+ "Masala Vadai"
137
+ ],
138
+ "starters_nonveg": [
139
+ "Chicken 65"
140
+ ],
141
+ "main_veg": [
142
+ "Sambar Rice",
143
+ "Pongal"
144
+ ],
145
+ "main_nonveg": [
146
+ "Chettinad Chicken Curry",
147
+ "Kothu Parotta"
148
+ ],
149
+ "desserts": [
150
+ "Payasam",
151
+ "Kesari",
152
+ "Jigarthanda (Madurai)"
153
+ ],
154
  },
155
+
156
+ "karnataka": {
157
+ "region": "Karnataka",
158
+ "starters_veg": [
159
+ "Maddur Vada",
160
+ "Goli Baje"
161
+ ],
162
+ "starters_nonveg": [
163
+ "Mangalore Chicken Ghee Roast"
164
+ ],
165
+ "main_veg": [
166
+ "Bisi Bele Bath",
167
+ "Neer Dosa",
168
+ "Ragi Mudde with Sambar"
169
+ ],
170
+ "main_nonveg": [
171
+ "Coorg Pandi Curry"
172
+ ],
173
+ "desserts": [
174
+ "Mysore Pak",
175
+ "Kesari Bath",
176
+ "Obbattu / Holige"
177
+ ],
178
+ },
179
+
180
+ # Fallback if something isn't mapped yet
181
  "default": {
182
  "region": "Unknown / Other",
183
  "starters_veg": ["Local vegetarian starters"],
184
+ "starters_nonveg": ["Local nonveg starters"],
185
  "main_veg": ["Local vegetarian mains"],
186
+ "main_nonveg": ["Local nonveg mains"],
187
  "desserts": ["Local desserts"],
188
  },
189
  }
190
 
191
+ # ---------------------------------------------------------------------
192
+ # 2. LABEL ALIAS MAP (so HuBERT/MFCC labels map to these keys)
193
+ # ---------------------------------------------------------------------
194
+
195
  LABEL_ALIAS = {
196
+ # Andhra / Telugu-ish labels
197
+ "andhra": "andhra_pradesh",
198
+ "andhra_pradesh": "andhra_pradesh",
199
+ "ap": "andhra_pradesh",
200
+ "telugu": "andhra_pradesh",
201
+ "telugu_andhra": "andhra_pradesh",
202
+ "telugu_india": "andhra_pradesh",
203
+
204
+ # Kerala / Malayalam
205
+ "kerala": "kerala",
 
 
 
 
 
 
 
 
 
 
 
206
  "ml": "kerala",
207
  "malayalam": "kerala",
 
208
  "kerala_malayalam": "kerala",
 
209
 
210
+ # Gujarat
211
+ "gujarat": "gujarat",
212
+ "gj": "gujarat",
213
+ "gujarati": "gujarat",
214
+
215
+ # Jharkhand
216
+ "jharkhand": "jharkhand",
217
+ "jh": "jharkhand",
218
+
219
+ # Tamil Nadu
220
+ "tamil_nadu": "tamil_nadu",
221
+ "tamil": "tamil_nadu",
222
+ "tn": "tamil_nadu",
223
+
224
+ # Karnataka
225
+ "karnataka": "karnataka",
226
+ "ka": "karnataka",
227
+ "kannada": "karnataka",
228
+ }
229
 
230
  def format_cuisine_output(pred_label: str) -> str:
231
  # Normalise raw predicted label and map through alias
 
244
  lines.append("Desserts: " + ", ".join(info["desserts"]))
245
  return "\n".join(lines)
246
 
247
+ # ---------------------------------------------------------------------
248
+ # 3. Audio & Feature helpers
249
+ # ---------------------------------------------------------------------
250
 
251
  def normalize_audio_path(audio):
252
  if audio is None:
 
274
 
275
  def get_hubert_layer_embedding(path: str, layer_idx: int = 11) -> np.ndarray:
276
  """
277
+ Uses facebook/hubert-large-ll60k (hidden size 1024, matching a 1024‑dim scaler).
278
  Returns a 1024‑dim vector: mean‑pooled over time from the chosen layer.
279
  """
280
  global _hf_feat, _hf_model
 
294
  with torch.no_grad():
295
  out = _hf_model(**inputs)
296
 
297
+ hidden_states = out.hidden_states # list[Tensor(batch, time, dim)]
298
  hs = hidden_states[layer_idx] # (batch, time, dim)
299
 
300
  if hs.ndim == 3:
 
303
  vec = hs.mean(dim=0).cpu().numpy()
304
  return vec
305
 
306
+ # ---------------------------------------------------------------------
307
+ # 4. Load models from checkpoints
308
+ # ---------------------------------------------------------------------
309
 
310
  app_state = {"models": {}}
311
 
 
312
  def load_models():
313
+ # MFCC model
314
  try:
315
  with open(CHECKPOINT_DIR / "clf_mfcc.pkl", "rb") as f:
316
  clf_mfcc = pickle.load(f)
 
327
  except Exception as e:
328
  print("Could not load MFCC model:", e)
329
 
330
+ # HuBERT model
331
  try:
332
  with open(CHECKPOINT_DIR / "clf_hubert.pkl", "rb") as f:
333
  clf_h = pickle.load(f)
 
350
  except Exception as e:
351
  print("Could not load HuBERT model:", e)
352
 
 
353
  load_models()
354
 
355
+ # ---------------------------------------------------------------------
356
+ # 5. Prediction logic
357
+ # ---------------------------------------------------------------------
358
 
359
  def predict_accent_and_cuisine(audio_file, feature_choice, hubert_layer_idx, use_trained):
360
  audio_path = normalize_audio_path(audio_file)
 
383
  if feat == "mfcc":
384
  x = extract_mfcc_pooled(audio_path)
385
  else:
386
+ # Use stored trained layer if available; otherwise the slider value
387
  trained_layer = model_info.get("layer", hubert_layer_idx)
388
  x = get_hubert_layer_embedding(audio_path, layer_idx=trained_layer)
389
  except Exception as e:
 
400
  cuisine_text = format_cuisine_output(pred_label)
401
  return pred_label, cuisine_text
402
 
403
+ # ---------------------------------------------------------------------
404
+ # 6. Gradio UI
405
+ # ---------------------------------------------------------------------
406
 
407
  with gr.Blocks() as demo:
408
  gr.Markdown("# Accent Detection & Cuisine Recommendation")