Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -3,6 +3,8 @@ import torch
|
|
| 3 |
from transformers import pipeline
|
| 4 |
import librosa
|
| 5 |
import numpy as np
|
|
|
|
|
|
|
| 6 |
|
| 7 |
print("🚀 Starting Hindi Speech Sentiment Analysis App...")
|
| 8 |
|
|
@@ -65,7 +67,7 @@ except Exception as e:
|
|
| 65 |
except Exception as e2:
|
| 66 |
print(f"❌ Error loading any ASR model: {e2}")
|
| 67 |
|
| 68 |
-
def predict(audio_filepath):
|
| 69 |
"""
|
| 70 |
Process audio and return sentiment analysis using Whisper + LondonStory
|
| 71 |
"""
|
|
@@ -109,36 +111,91 @@ def predict(audio_filepath):
|
|
| 109 |
print(f"❌ Whisper ASR Error: {asr_error}")
|
| 110 |
return {"ASR Error": 1.0}
|
| 111 |
|
| 112 |
-
# Perform sentiment analysis
|
| 113 |
-
print("💭 Analyzing sentiment with
|
| 114 |
try:
|
|
|
|
| 115 |
sentiment_results = sentiment_pipeline(transcription)
|
| 116 |
print(f"📊 Raw sentiment results: {sentiment_results}")
|
| 117 |
|
| 118 |
-
#
|
| 119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
|
| 121 |
-
#
|
| 122 |
-
|
| 123 |
label_mapping = {
|
| 124 |
'LABEL_0': 'Negative',
|
| 125 |
'LABEL_1': 'Neutral',
|
| 126 |
'LABEL_2': 'Positive'
|
| 127 |
}
|
| 128 |
|
| 129 |
-
|
| 130 |
-
for result in sentiment_results[0]:
|
| 131 |
raw_label = result['label']
|
| 132 |
score = result['score']
|
| 133 |
-
# Convert LABEL_X to actual sentiment name
|
| 134 |
sentiment_name = label_mapping.get(raw_label, raw_label)
|
| 135 |
result_dict[sentiment_name] = float(score)
|
| 136 |
|
|
|
|
|
|
|
|
|
|
| 137 |
# Log success details
|
| 138 |
print(f"✅ SUCCESS! Processing completed")
|
| 139 |
print(f"📝 Final transcription: '{transcription}'")
|
| 140 |
for label, score in result_dict.items():
|
| 141 |
-
|
|
|
|
| 142 |
print(f"{'='*50}\n")
|
| 143 |
|
| 144 |
return result_dict
|
|
@@ -151,7 +208,7 @@ def predict(audio_filepath):
|
|
| 151 |
print(f"❌ General Error: {str(e)}")
|
| 152 |
return {"Processing Error": 1.0}
|
| 153 |
|
| 154 |
-
# Create Gradio interface
|
| 155 |
demo = gr.Interface(
|
| 156 |
fn=predict,
|
| 157 |
inputs=gr.Audio(
|
|
@@ -161,33 +218,39 @@ demo = gr.Interface(
|
|
| 161 |
),
|
| 162 |
outputs=gr.Label(
|
| 163 |
label="🎭 Sentiment Analysis Results",
|
| 164 |
-
num_top_classes=
|
| 165 |
),
|
| 166 |
-
title="🎤 Hindi Speech Sentiment Analysis (
|
| 167 |
description="""
|
| 168 |
-
## 🇮🇳 Analyze sentiment from Hindi speech
|
| 169 |
|
| 170 |
### 🔄 How it works:
|
| 171 |
-
1. **🎤
|
| 172 |
-
2. **💭
|
|
|
|
| 173 |
|
| 174 |
### 🧪 Test Phrases (speak clearly):
|
| 175 |
- **😊 Happy**: "मैं बहुत खुश हूं" *(Main bahut khush hun)*
|
| 176 |
- **😠 Sad**: "मुझे दुख है" *(Mujhe dukh hai)*
|
| 177 |
-
- **😐 Neutral**: "
|
| 178 |
- **❤️ Love**: "मुझे यह पसंद है" *(Mujhe yeh pasand hai)*
|
| 179 |
-
-
|
| 180 |
|
| 181 |
### 📋 Instructions:
|
| 182 |
1. Click the microphone to record or upload an audio file
|
| 183 |
-
2. Speak clearly in Hindi for 3-
|
| 184 |
3. Click Submit and check results + logs below
|
| 185 |
|
| 186 |
-
### 🔍 Features:
|
| 187 |
-
- **
|
| 188 |
-
- **
|
| 189 |
-
- **
|
| 190 |
-
- **Supports various Hindi
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
""",
|
| 192 |
examples=None,
|
| 193 |
theme=gr.themes.Soft(),
|
|
|
|
| 3 |
from transformers import pipeline
|
| 4 |
import librosa
|
| 5 |
import numpy as np
|
| 6 |
+
import asyncio
|
| 7 |
+
import re
|
| 8 |
|
| 9 |
print("🚀 Starting Hindi Speech Sentiment Analysis App...")
|
| 10 |
|
|
|
|
| 67 |
except Exception as e2:
|
| 68 |
print(f"❌ Error loading any ASR model: {e2}")
|
| 69 |
|
| 70 |
+
async def predict(audio_filepath):
|
| 71 |
"""
|
| 72 |
Process audio and return sentiment analysis using Whisper + LondonStory
|
| 73 |
"""
|
|
|
|
| 111 |
print(f"❌ Whisper ASR Error: {asr_error}")
|
| 112 |
return {"ASR Error": 1.0}
|
| 113 |
|
| 114 |
+
# Perform enhanced sentiment analysis
|
| 115 |
+
print("💭 Analyzing sentiment with enhanced logic...")
|
| 116 |
try:
|
| 117 |
+
# Get raw sentiment results
|
| 118 |
sentiment_results = sentiment_pipeline(transcription)
|
| 119 |
print(f"📊 Raw sentiment results: {sentiment_results}")
|
| 120 |
|
| 121 |
+
# Enhanced sentiment analysis for complex emotional text
|
| 122 |
+
def enhance_sentiment_analysis(text, raw_results):
|
| 123 |
+
"""
|
| 124 |
+
Enhance sentiment analysis for mixed emotions and complex text
|
| 125 |
+
"""
|
| 126 |
+
# Check for mixed emotion indicators in Hindi
|
| 127 |
+
mixed_indicators = [
|
| 128 |
+
'कभी', 'कभीकभी', 'sometimes', 'कभी कभी', # sometimes
|
| 129 |
+
'लेकिन', 'पर', 'but', # but
|
| 130 |
+
'समझ नहीं आ रहा', 'confuse', 'confusion', # confused
|
| 131 |
+
'या', 'or', # or (indicates uncertainty)
|
| 132 |
+
'क्या', 'does', 'whether' # question words
|
| 133 |
+
]
|
| 134 |
+
|
| 135 |
+
# Check for contrasting emotions in same text
|
| 136 |
+
positive_words = ['खुश', 'प्यार', 'happy', 'love', 'अच्छा']
|
| 137 |
+
negative_words = ['रो', 'दुख', 'cry', 'sad', 'परेशान']
|
| 138 |
+
|
| 139 |
+
text_lower = text.lower()
|
| 140 |
+
has_mixed = any(indicator in text_lower for indicator in mixed_indicators)
|
| 141 |
+
has_positive = any(word in text_lower for word in positive_words)
|
| 142 |
+
has_negative = any(word in text_lower for word in negative_words)
|
| 143 |
+
|
| 144 |
+
# If text has mixed indicators or contrasting emotions
|
| 145 |
+
if has_mixed or (has_positive and has_negative):
|
| 146 |
+
print("🔄 Detected mixed emotions - adjusting sentiment scores...")
|
| 147 |
+
|
| 148 |
+
# Get original scores
|
| 149 |
+
original_scores = {result['label']: result['score'] for result in raw_results[0]}
|
| 150 |
+
|
| 151 |
+
# Boost neutral score for mixed emotions
|
| 152 |
+
neutral_boost = 0.3
|
| 153 |
+
negative_score = original_scores.get('LABEL_0', 0)
|
| 154 |
+
positive_score = original_scores.get('LABEL_2', 0)
|
| 155 |
+
neutral_score = original_scores.get('LABEL_1', 0)
|
| 156 |
+
|
| 157 |
+
# Redistribute scores to favor neutral
|
| 158 |
+
adjusted_scores = {
|
| 159 |
+
'LABEL_0': max(0.1, negative_score - neutral_boost/2),
|
| 160 |
+
'LABEL_1': min(0.8, neutral_score + neutral_boost),
|
| 161 |
+
'LABEL_2': max(0.1, positive_score - neutral_boost/2)
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
# Normalize to sum to 1
|
| 165 |
+
total = sum(adjusted_scores.values())
|
| 166 |
+
adjusted_scores = {k: v/total for k, v in adjusted_scores.items()}
|
| 167 |
+
|
| 168 |
+
print(f"🔧 Adjusted for mixed emotions: {adjusted_scores}")
|
| 169 |
+
return [{'label': k, 'score': v} for k, v in adjusted_scores.items()]
|
| 170 |
+
|
| 171 |
+
return raw_results[0]
|
| 172 |
+
|
| 173 |
+
# Apply enhanced sentiment analysis
|
| 174 |
+
enhanced_results = enhance_sentiment_analysis(transcription, sentiment_results)
|
| 175 |
|
| 176 |
+
# Format results for Gradio
|
| 177 |
+
result_dict = {}
|
| 178 |
label_mapping = {
|
| 179 |
'LABEL_0': 'Negative',
|
| 180 |
'LABEL_1': 'Neutral',
|
| 181 |
'LABEL_2': 'Positive'
|
| 182 |
}
|
| 183 |
|
| 184 |
+
for result in enhanced_results:
|
|
|
|
| 185 |
raw_label = result['label']
|
| 186 |
score = result['score']
|
|
|
|
| 187 |
sentiment_name = label_mapping.get(raw_label, raw_label)
|
| 188 |
result_dict[sentiment_name] = float(score)
|
| 189 |
|
| 190 |
+
# Add transcription to the visible results
|
| 191 |
+
result_dict['📝 Transcription'] = transcription
|
| 192 |
+
|
| 193 |
# Log success details
|
| 194 |
print(f"✅ SUCCESS! Processing completed")
|
| 195 |
print(f"📝 Final transcription: '{transcription}'")
|
| 196 |
for label, score in result_dict.items():
|
| 197 |
+
if label != '📝 Transcription': # Don't print transcription twice
|
| 198 |
+
print(f"📊 {label}: {score:.3f}")
|
| 199 |
print(f"{'='*50}\n")
|
| 200 |
|
| 201 |
return result_dict
|
|
|
|
| 208 |
print(f"❌ General Error: {str(e)}")
|
| 209 |
return {"Processing Error": 1.0}
|
| 210 |
|
| 211 |
+
# Create Gradio interface with async support
|
| 212 |
demo = gr.Interface(
|
| 213 |
fn=predict,
|
| 214 |
inputs=gr.Audio(
|
|
|
|
| 218 |
),
|
| 219 |
outputs=gr.Label(
|
| 220 |
label="🎭 Sentiment Analysis Results",
|
| 221 |
+
num_top_classes=6 # Increased to show transcription + 3 sentiments
|
| 222 |
),
|
| 223 |
+
title="🎤 Hindi Speech Sentiment Analysis (Enhanced + Async)",
|
| 224 |
description="""
|
| 225 |
+
## 🇮🇳 Analyze sentiment from Hindi speech with enhanced emotion detection
|
| 226 |
|
| 227 |
### 🔄 How it works:
|
| 228 |
+
1. **🎤 AI Speech Recognition** → Converts Hindi speech to Devanagari text
|
| 229 |
+
2. **💭 Enhanced Sentiment AI** → Analyzes emotions with mixed-emotion detection
|
| 230 |
+
3. **⚡ Async Processing** → Faster response times
|
| 231 |
|
| 232 |
### 🧪 Test Phrases (speak clearly):
|
| 233 |
- **😊 Happy**: "मैं बहुत खुश हूं" *(Main bahut khush hun)*
|
| 234 |
- **😠 Sad**: "मुझे दुख है" *(Mujhe dukh hai)*
|
| 235 |
+
- **😐 Neutral/Mixed**: "कभी खुश कभी उदास हूं" *(Sometimes happy, sometimes sad)*
|
| 236 |
- **❤️ Love**: "मुझे यह पसंद है" *(Mujhe yeh pasand hai)*
|
| 237 |
+
- **🤔 Confused**: "समझ नहीं आ रहा क्या करूं" *(Don't understand what to do)*
|
| 238 |
|
| 239 |
### 📋 Instructions:
|
| 240 |
1. Click the microphone to record or upload an audio file
|
| 241 |
+
2. Speak clearly in Hindi for 3-10 seconds
|
| 242 |
3. Click Submit and check results + logs below
|
| 243 |
|
| 244 |
+
### 🔍 Enhanced Features:
|
| 245 |
+
- **Mixed emotion detection** for complex feelings
|
| 246 |
+
- **Context-aware sentiment** analysis
|
| 247 |
+
- **Async processing** for better performance
|
| 248 |
+
- **Supports various Hindi dialects** and speaking styles
|
| 249 |
+
|
| 250 |
+
### 💡 Perfect for:
|
| 251 |
+
- **Personal diary analysis** - Understanding your emotional patterns
|
| 252 |
+
- **Relationship counseling** - Analyzing complex feelings
|
| 253 |
+
- **Mental health tracking** - Monitoring emotional states over time
|
| 254 |
""",
|
| 255 |
examples=None,
|
| 256 |
theme=gr.themes.Soft(),
|