dhruthick commited on
Commit
dd541ca
·
1 Parent(s): bf5544b

added chart and other details

Browse files
Files changed (2) hide show
  1. app.py +13 -6
  2. frontend/index.html +116 -6
app.py CHANGED
@@ -2,6 +2,7 @@ from flask import Flask, request, jsonify, send_from_directory
2
  from lyricsgenius import Genius
3
  import json
4
  import torch
 
5
  import numpy as np
6
  import os
7
  from transformers import BertTokenizer, BertForSequenceClassification, AutoTokenizer, AutoModelForSequenceClassification
@@ -11,6 +12,10 @@ os.environ['TRANSFORMERS_CACHE'] = './hf_cache'
11
 
12
  app = Flask(__name__)
13
 
 
 
 
 
14
  mood_map = {
15
  0: 'Angry',
16
  1: 'Happy',
@@ -77,13 +82,15 @@ def get_prediction(iids, ams):
77
  attention_mask=ams)
78
  logits = outputs.logits.detach().numpy()
79
  pred_flat = np.argmax(logits, axis=1).flatten()
80
- return pred_flat[0]
 
81
 
82
  def classify_lyrics(lyrics):
83
  input_ids, attention_masks = tokenize_and_format([lyrics.replace('\n', ' ')])
84
- prediction = get_prediction(input_ids, attention_masks)
85
  mood = ["Angry", "Happy", "Relaxed", "Sad"][prediction]
86
- return mood
 
87
 
88
  @app.route('/')
89
  def index():
@@ -96,9 +103,9 @@ def predict():
96
  artist_name = data['artist']
97
  success, lyrics = get_lyrics(song_title, artist_name)
98
  if success:
99
- mood = classify_lyrics(lyrics)
100
- return jsonify({'mood': mood, 'lyrics': lyrics})
101
- return jsonify({'mood': '-', 'lyrics': lyrics})
102
 
103
  def get_lyrics(song_title, artist_name):
104
  token = config.get('GENIUS_TOKEN')
 
2
  from lyricsgenius import Genius
3
  import json
4
  import torch
5
+ import logging
6
  import numpy as np
7
  import os
8
  from transformers import BertTokenizer, BertForSequenceClassification, AutoTokenizer, AutoModelForSequenceClassification
 
12
 
13
  app = Flask(__name__)
14
 
15
+ # Configure Flask logging
16
+ logging.basicConfig(level=logging.INFO,
17
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
18
+ handlers=[logging.StreamHandler()])
19
  mood_map = {
20
  0: 'Angry',
21
  1: 'Happy',
 
82
  attention_mask=ams)
83
  logits = outputs.logits.detach().numpy()
84
  pred_flat = np.argmax(logits, axis=1).flatten()
85
+ probabilities = torch.softmax(outputs.logits, dim=1).tolist()[0]
86
+ return pred_flat[0], probabilities
87
 
88
  def classify_lyrics(lyrics):
89
  input_ids, attention_masks = tokenize_and_format([lyrics.replace('\n', ' ')])
90
+ prediction, probabilities = get_prediction(input_ids, attention_masks)
91
  mood = ["Angry", "Happy", "Relaxed", "Sad"][prediction]
92
+ app.logger.info(f"probabilities: {probabilities}")
93
+ return mood, probabilities
94
 
95
  @app.route('/')
96
  def index():
 
103
  artist_name = data['artist']
104
  success, lyrics = get_lyrics(song_title, artist_name)
105
  if success:
106
+ mood, probabilities = classify_lyrics(lyrics)
107
+ return jsonify({'mood': mood, 'lyrics': lyrics, 'probabilities': probabilities})
108
+ return jsonify({'mood': '-', 'lyrics': lyrics, 'probabilities': [0, 0, 0, 0]})
109
 
110
  def get_lyrics(song_title, artist_name):
111
  token = config.get('GENIUS_TOKEN')
frontend/index.html CHANGED
@@ -16,11 +16,11 @@
16
  justify-content: center;
17
  align-items: center;
18
  height: 100vh;
19
- transition: background 1s ease-in-out; /* Increased duration for smoother transition */
20
  }
21
  .container {
22
  background: rgba(255, 255, 255, 0.9);
23
- padding: 40px;
24
  border-radius: 20px;
25
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
26
  max-width: 700px;
@@ -29,11 +29,14 @@
29
  overflow-y: auto;
30
  max-height: 90vh;
31
  transition: background-color 0.5s ease-in-out;
 
 
 
32
  }
33
  h1 {
34
  color: #2c3e50;
35
  font-size: 2.5em;
36
- margin-bottom: 30px;
37
  font-family: 'Playfair Display', serif;
38
  }
39
  form {
@@ -72,10 +75,14 @@
72
  transform: translateY(-2px);
73
  }
74
  #mood-result {
75
- margin-top: 30px;
76
  font-size: 1.5em;
77
  color: #2980b9;
78
  }
 
 
 
 
79
  pre {
80
  background: rgba(244, 244, 249, 0.9);
81
  padding: 20px;
@@ -88,11 +95,40 @@
88
  transition: background-color 0.5s ease-in-out;
89
  }
90
  #results-container {
91
- margin-top: 30px;
92
  padding: 20px;
93
  border-radius: 10px;
94
  transition: background-color 0.5s ease-in-out;
95
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  </style>
97
  </head>
98
  <body>
@@ -105,15 +141,71 @@
105
  </form>
106
  <div id="results-container">
107
  <h2 id="mood-result"></h2>
 
108
  <pre id="lyrics"></pre>
109
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  </div>
 
111
  <script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  document.getElementById('mood-form').addEventListener('submit', async function(event) {
113
  event.preventDefault();
114
  const title = document.getElementById('title').value;
115
  const artist = document.getElementById('artist').value;
116
-
117
  const response = await fetch('/predict', {
118
  method: 'POST',
119
  headers: {
@@ -124,6 +216,7 @@
124
  const data = await response.json();
125
  document.getElementById('mood-result').innerText = `Predicted Mood: ${data.mood}`;
126
  document.getElementById('lyrics').innerText = data.lyrics;
 
127
  // Scroll to the top of the container to ensure the form remains visible
128
  document.querySelector('.container').scrollTop = 0;
129
 
@@ -151,6 +244,23 @@
151
  resultsContainer.style.backgroundColor = 'rgba(244, 244, 249, 0.9)'; // default background color
152
  body.style.background = 'linear-gradient(135deg, #f3ec78, #af4261)'; // default gradient
153
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  });
155
  </script>
156
  </body>
 
16
  justify-content: center;
17
  align-items: center;
18
  height: 100vh;
19
+ transition: background 1s ease-in-out; /* Smooth gradient transition */
20
  }
21
  .container {
22
  background: rgba(255, 255, 255, 0.9);
23
+ padding: 30px;
24
  border-radius: 20px;
25
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
26
  max-width: 700px;
 
29
  overflow-y: auto;
30
  max-height: 90vh;
31
  transition: background-color 0.5s ease-in-out;
32
+ display: flex;
33
+ flex-direction: column;
34
+ gap: 20px;
35
  }
36
  h1 {
37
  color: #2c3e50;
38
  font-size: 2.5em;
39
+ margin-bottom: 20px;
40
  font-family: 'Playfair Display', serif;
41
  }
42
  form {
 
75
  transform: translateY(-2px);
76
  }
77
  #mood-result {
78
+ margin-top: 20px;
79
  font-size: 1.5em;
80
  color: #2980b9;
81
  }
82
+ #mood-chart {
83
+ max-width: 100%;
84
+ height: 300px;
85
+ }
86
  pre {
87
  background: rgba(244, 244, 249, 0.9);
88
  padding: 20px;
 
95
  transition: background-color 0.5s ease-in-out;
96
  }
97
  #results-container {
98
+ margin-top: 20px;
99
  padding: 20px;
100
  border-radius: 10px;
101
  transition: background-color 0.5s ease-in-out;
102
  }
103
+ .footer {
104
+ margin-top: 20px;
105
+ font-size: 0.9em;
106
+ color: #555;
107
+ text-align: center;
108
+ }
109
+ #more-info {
110
+ display: none;
111
+ max-height: 0;
112
+ overflow: hidden;
113
+ transition: max-height 0.5s ease-out, opacity 0.5s ease-out;
114
+ opacity: 0;
115
+ text-align: left;
116
+ font-size: 0.9em;
117
+ color: #333;
118
+ padding: 0;
119
+ border-radius: 10px;
120
+ background: rgba(244, 244, 249, 0.9);
121
+ }
122
+ #more-info.show {
123
+ display: block;
124
+ max-height: 500px; /* Adjust as needed */
125
+ opacity: 1;
126
+ }
127
+ #more-info-link {
128
+ color: #333; /* Match the rest of the text color */
129
+ cursor: pointer;
130
+ text-decoration: underline;
131
+ }
132
  </style>
133
  </head>
134
  <body>
 
141
  </form>
142
  <div id="results-container">
143
  <h2 id="mood-result"></h2>
144
+ <canvas id="mood-chart"></canvas>
145
  <pre id="lyrics"></pre>
146
  </div>
147
+ <div class="footer">
148
+ This app analyzes song lyrics to predict their mood. Enter a song title and artist, and get mood predictions along with the lyrics. Deployed using Hugging Face Spaces.
149
+ <br><br>
150
+ <a href="#" id="more-info-link">Click here to learn more about how this web app works</a>
151
+ <div id="more-info">
152
+ <p><strong>How it Works:</strong></p>
153
+ <p>This web app utilizes a fine-tuned BERT model to analyze the mood of song lyrics. Upon entering a song title and artist, the app retrieves the song's lyrics from Genius, processes them through the BERT model, and predicts the mood.</p>
154
+ <p><strong>Technology:</strong></p>
155
+ <ul>
156
+ <li><strong>Model:</strong> BERT (Bidirectional Encoder Representations from Transformers) fine-tuned on song lyrics to classify moods.</li>
157
+ <li><strong>Framework:</strong> PyTorch and Hugging Face Transformers library for model training and prediction.</li>
158
+ <li><strong>Deployment:</strong> The web app is hosted and deployed using Hugging Face Spaces, which provides a simple interface for serving machine learning models.</li>
159
+ </ul>
160
+ </div>
161
+ </div>
162
  </div>
163
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
164
  <script>
165
+ // Initialize the chart with zero probabilities
166
+ const ctx = document.getElementById('mood-chart').getContext('2d');
167
+ let moodChart = new Chart(ctx, {
168
+ type: 'bar',
169
+ data: {
170
+ labels: ['Angry', 'Happy', 'Relaxed', 'Sad'],
171
+ datasets: [{
172
+ label: 'Mood Probabilities',
173
+ data: [0, 0, 0, 0], // Initial data
174
+ backgroundColor: [
175
+ 'rgba(255, 99, 132, 0.2)',
176
+ 'rgba(255, 159, 64, 0.2)',
177
+ 'rgba(75, 192, 192, 0.2)',
178
+ 'rgba(153, 102, 255, 0.2)'
179
+ ],
180
+ borderColor: [
181
+ 'rgba(255, 99, 132, 1)',
182
+ 'rgba(255, 159, 64, 1)',
183
+ 'rgba(75, 192, 192, 1)',
184
+ 'rgba(153, 102, 255, 1)'
185
+ ],
186
+ borderWidth: 1
187
+ }]
188
+ },
189
+ options: {
190
+ scales: {
191
+ y: {
192
+ beginAtZero: true,
193
+ min: 0,
194
+ max: 1,
195
+ ticks: {
196
+ stepSize: 0.1,
197
+ callback: function(value) { return value.toFixed(1); } // Format y-axis labels
198
+ }
199
+ }
200
+ }
201
+ }
202
+ });
203
+
204
  document.getElementById('mood-form').addEventListener('submit', async function(event) {
205
  event.preventDefault();
206
  const title = document.getElementById('title').value;
207
  const artist = document.getElementById('artist').value;
208
+
209
  const response = await fetch('/predict', {
210
  method: 'POST',
211
  headers: {
 
216
  const data = await response.json();
217
  document.getElementById('mood-result').innerText = `Predicted Mood: ${data.mood}`;
218
  document.getElementById('lyrics').innerText = data.lyrics;
219
+
220
  // Scroll to the top of the container to ensure the form remains visible
221
  document.querySelector('.container').scrollTop = 0;
222
 
 
244
  resultsContainer.style.backgroundColor = 'rgba(244, 244, 249, 0.9)'; // default background color
245
  body.style.background = 'linear-gradient(135deg, #f3ec78, #af4261)'; // default gradient
246
  }
247
+
248
+ // Update chart with new data
249
+ moodChart.data.datasets[0].data = data.probabilities || [0, 0, 0, 0];
250
+ moodChart.update();
251
+ });
252
+
253
+ // Toggle detailed description with smooth effect
254
+ document.getElementById('more-info-link').addEventListener('click', function(event) {
255
+ event.preventDefault();
256
+ const moreInfo = document.getElementById('more-info');
257
+ if (moreInfo.style.display === 'none' || !moreInfo.style.display) {
258
+ moreInfo.style.display = 'block';
259
+ setTimeout(() => moreInfo.classList.add('show'), 10);
260
+ } else {
261
+ moreInfo.classList.remove('show');
262
+ setTimeout(() => moreInfo.style.display = 'none', 500);
263
+ }
264
  });
265
  </script>
266
  </body>