dhruthick commited on
Commit
42d18ff
·
1 Parent(s): faa1cc5

deployed mood prediction model with flask

Browse files
Files changed (3) hide show
  1. .gitignore +1 -0
  2. app.py +113 -0
  3. frontend/index.html +35 -0
.gitignore CHANGED
@@ -1,2 +1,3 @@
1
  .DS_Store
2
  backend/.DS_Store
 
 
1
  .DS_Store
2
  backend/.DS_Store
3
+ backend/models/bert-mood-prediction-1.pt
app.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, jsonify, send_from_directory
2
+ from lyricsgenius import Genius
3
+
4
+ import torch
5
+ import numpy as np
6
+ from transformers import BertTokenizer, BertForSequenceClassification
7
+
8
+ app = Flask(__name__)
9
+
10
+ mood_map = {
11
+ 0: 'Angry',
12
+ 1: 'Happy',
13
+ 3: 'Sad',
14
+ 2: 'Relaxed'
15
+ }
16
+
17
+ # Load your pre-trained model and tokenizer
18
+ model = BertForSequenceClassification.from_pretrained(
19
+ "bert-base-uncased", # Use the 12-layer BERT model, with an uncased vocab.
20
+ num_labels = 4, # The number of output labels.
21
+ output_attentions = False, # Whether the model returns attentions weights.
22
+ output_hidden_states = False, # Whether the model returns all hidden-states.
23
+ )
24
+ model.load_state_dict(torch.load('backend/models/bert-mood-prediction-1.pt', map_location=torch.device('cpu')))
25
+ model.eval()
26
+
27
+ def tokenize_and_format(sentences):
28
+ tokenizer = BertTokenizer.from_pretrained('bert-base-uncased', do_lower_case=True)
29
+
30
+ # Tokenize all of the sentences and map the tokens to thier word IDs.
31
+ input_ids = []
32
+ attention_masks = []
33
+
34
+ # For every sentence...
35
+ for sentence in sentences:
36
+ # `encode_plus` will:
37
+ # (1) Tokenize the sentence.
38
+ # (2) Prepend the `[CLS]` token to the start.
39
+ # (3) Append the `[SEP]` token to the end.
40
+ # (4) Map tokens to their IDs.
41
+ # (5) Pad or truncate the sentence to `max_length`
42
+ # (6) Create attention masks for [PAD] tokens.
43
+ encoded_dict = tokenizer.encode_plus(
44
+ sentence, # Sentence to encode.
45
+ add_special_tokens = True, # Add '[CLS]' and '[SEP]'
46
+ max_length = 256, # Pad & truncate all sentences.
47
+ padding = 'max_length',
48
+ truncation = True,
49
+ return_attention_mask = True, # Construct attn. masks.
50
+ return_tensors = 'pt', # Return pytorch tensors.
51
+ )
52
+
53
+ # Add the encoded sentence to the list.
54
+ input_ids.append(encoded_dict['input_ids'])
55
+
56
+ # And its attention mask (simply differentiates padding from non-padding).
57
+ attention_masks.append(encoded_dict['attention_mask'])
58
+ return torch.cat(input_ids, dim=0), torch.cat(attention_masks, dim=0)
59
+
60
+ def get_prediction(iids, ams):
61
+ with torch.no_grad():
62
+ # Forward pass, calculate logit predictions.
63
+ outputs = model(iids,token_type_ids=None,
64
+ attention_mask=ams)
65
+ logits = outputs.logits.detach().numpy()
66
+ pred_flat = np.argmax(logits, axis=1).flatten()
67
+ return pred_flat[0]
68
+
69
+ def classify_lyrics(lyrics):
70
+ input_ids, attention_masks = tokenize_and_format([lyrics.replace('\n', ' ')])
71
+ prediction = get_prediction(input_ids, attention_masks)
72
+ mood = ["angry", "happy", "relaxed", "sad"][prediction]
73
+ return mood
74
+
75
+ @app.route('/')
76
+ def index():
77
+ return send_from_directory('frontend', 'index.html')
78
+
79
+ @app.route('/predict', methods=['POST'])
80
+ def predict():
81
+ data = request.get_json()
82
+ song_title = data['title']
83
+ artist_name = data['artist']
84
+ success, lyrics = get_lyrics(song_title, artist_name)
85
+ if success:
86
+ mood = classify_lyrics(lyrics)
87
+ return jsonify({'mood': mood, 'lyrics': lyrics})
88
+ return jsonify({'mood': '-', 'lyrics': lyrics})
89
+
90
+ def get_lyrics(song_title, artist_name):
91
+ # Implement the lyrics fetching logic here
92
+ # This is a placeholder function
93
+ token='PFl5Jdd01ayEMNqxIkuoAWnA7N9Xw9KqD9BSphLmjQ4IBrJqyaTA9CxKP2k8yJpz'
94
+ genius = Genius(token)
95
+ genius.timeout = 300
96
+ try:
97
+ song = genius.search_song(song_title, artist_name)
98
+ if song == None:
99
+ return False, f"Song not found - {song_title} by {artist_name}"
100
+ lyrics=song.lyrics
101
+ if lyrics.count('-')>200:
102
+ return False, f"Song not found - {song_title} by {artist_name}"
103
+ verses=[]
104
+ for x in lyrics.split('Lyrics')[1][:-7].split('\n'):
105
+ if '[' in list(x) or len(x)==0:
106
+ continue
107
+ verses.append(x.replace("\'","'"))
108
+ return True, '\n'.join(verses)
109
+ except TimeoutError:
110
+ return False, "TIMEOUT"
111
+
112
+ if __name__ == '__main__':
113
+ app.run(debug=True)
frontend/index.html ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Lyrics Mood Predictor</title>
5
+ </head>
6
+ <body>
7
+ <h1>Enter Song Title and Artist</h1>
8
+ <form id="mood-form">
9
+ <input type="text" id="title" placeholder="Song Title" required>
10
+ <input type="text" id="artist" placeholder="Artist" required>
11
+ <button type="submit">Predict Mood</button>
12
+ </form>
13
+ <h2 id="mood-result"></h2>
14
+ <pre id="lyrics"></pre>
15
+
16
+ <script>
17
+ document.getElementById('mood-form').addEventListener('submit', async function(event) {
18
+ event.preventDefault();
19
+ const title = document.getElementById('title').value;
20
+ const artist = document.getElementById('artist').value;
21
+
22
+ const response = await fetch('/predict', {
23
+ method: 'POST',
24
+ headers: {
25
+ 'Content-Type': 'application/json',
26
+ },
27
+ body: JSON.stringify({ title, artist }),
28
+ });
29
+ const data = await response.json();
30
+ document.getElementById('mood-result').innerText = `Predicted Mood: ${data.mood}`;
31
+ document.getElementById('lyrics').innerText = data.lyrics;
32
+ });
33
+ </script>
34
+ </body>
35
+ </html>