Ridzuan commited on
Commit
0c2d8c4
1 Parent(s): 1123866

update app

Browse files
.ipynb_checkpoints/Audio_Classifier-checkpoint.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from helper import model, upload, record
3
+
4
+ title = "Emotion Audio Classifier"
5
+ st.title(title)
6
+
7
+ st.subheader('This Web App allows user to classify Emotion from Audio File')
8
+
9
+ def add_bg_from_url():
10
+ st.markdown(
11
+ f"""
12
+ <style>
13
+ .stApp {{
14
+ background-image: url("https://img.freepik.com/free-vector/white-grid-line-pattern-gray-background_53876-99015.jpg? w=996&t=st=1667979021~exp=1667979621~hmac=25b2066b6c3abd08a038e86ad9579fe48db944b57f853bd8ee2a00a98f752d7b");
15
+ background-attachment: fixed;
16
+ background-size: cover
17
+ }}
18
+ </style>
19
+ """,
20
+ unsafe_allow_html=True
21
+ )
22
+
23
+ add_bg_from_url()
24
+
25
+ model()
.ipynb_checkpoints/helper-checkpoint.py ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from keras.models import load_model
3
+ import os
4
+ import streamlit as st
5
+ import numpy as np
6
+ import pandas as pd
7
+ from sklearn.preprocessing import normalize
8
+ import matplotlib.pyplot as plt
9
+ import librosa
10
+ import librosa.display
11
+ import IPython.display as ipd
12
+ import streamlit.components.v1 as components
13
+ from io import BytesIO
14
+ from scipy.io.wavfile import read, write
15
+ from googlesearch import search
16
+ import requests
17
+ from bs4 import BeautifulSoup
18
+
19
+ classifier = load_model('./model/bestmodel.h5')
20
+
21
+
22
+ def prepare_test(file):
23
+ max_size=350
24
+ features=[]
25
+ data_ori, sample_rate = librosa.load(file)
26
+ data, _ = librosa.effects.trim(data_ori)
27
+
28
+ spec_bw = padding(librosa.feature.spectral_bandwidth(y = data, sr= sample_rate), 20, max_size).astype('float32')
29
+ cent = padding(librosa.feature.spectral_centroid(y = data, sr=sample_rate), 20, max_size).astype('float32')
30
+ mfcc = librosa.feature.mfcc(y=data, sr=sample_rate,n_mfcc=20)
31
+ mfccs = padding(normalize(mfcc, axis=1), 20, max_size).astype('float32')
32
+ rms = padding(librosa.feature.rms(y = data),20, max_size).astype('float32')
33
+ y = librosa.effects.harmonic(data)
34
+ tonnetz = padding(librosa.feature.tonnetz(y=y, sr=sample_rate,fmin=75),20, max_size).astype('float32')
35
+ image = padding(librosa.feature.chroma_cens(y = data, sr=sample_rate,fmin=75), 20, max_size).astype('float32')
36
+
37
+ image=np.dstack((image,spec_bw))
38
+ image=np.dstack((image,cent))
39
+ image=np.dstack((image,mfccs))
40
+ image=np.dstack((image,rms))
41
+ image=np.dstack((image,tonnetz))
42
+ features.append(image[np.newaxis,...])
43
+ output = np.concatenate(features,axis=0)
44
+ return output
45
+
46
+ def padding(array, xx, yy):
47
+ h = array.shape[0]
48
+ w = array.shape[1]
49
+ a = max((xx - h) // 2,0)
50
+ aa = max(0,xx - a - h)
51
+ b = max(0,(yy - w) // 2)
52
+ bb = max(yy - b - w,0)
53
+ return np.pad(array, pad_width=((a, aa), (b, bb)), mode='constant')
54
+
55
+
56
+ def model():
57
+ select = st.selectbox('Please select one to find out more about the model',
58
+ ('Choose','Model Training History', 'Confusion Matrix', 'Train-Test Scores'))
59
+ if select == 'Model Training History':
60
+ st.header('Train-Val Accuracy History')
61
+ st.write('Train and Validation accuracy scores are comparable this indicates that the Model is moderately trained.')
62
+ st.image('./img/bestmodelacc.png')
63
+
64
+ st.header('Train-Val Loss History')
65
+ st.write('The training was stopped with EarlyStopping() when the Validation loss score starts to saturate.')
66
+ st.image('./img/bestmodelloss.png')
67
+
68
+ if select == 'Confusion Matrix':
69
+ st.header('Confusion Matrix')
70
+ st.write('Below is the Confusion Matrix for this Model normalized by rows indicating Recall scores which are over 80%.')
71
+ st.image('./img/bestmodelcm.png')
72
+
73
+ if select == 'Train-Test Scores':
74
+ st.header('Train-Test Accuracy scores')
75
+ st.write('Train accuracy score is 94% and Test accuracy score is 90%. There is a 4% difference indicating that the model fitted moderately')
76
+ acc = [0.943, 0.908]
77
+ loss = [0.177, 0.304]
78
+ traintest_df = pd.DataFrame(list(zip(acc,loss)),columns=['Accuracy', 'loss'],index =['Train','Test'])
79
+ st.dataframe(traintest_df.style.format("{:.3}"))
80
+
81
+ st.header('Model Precision, Recall, F1-score & MCC')
82
+ st.write('Macro avg F1 score is 91%.')
83
+ st.write('Matthew’s correlation coefficient: 0.885')
84
+ prec = [0.92, 0.86, 0.91, 0.97, 0.88,0.91]
85
+ re = [0.92, 0.83, 0.96, 0.92, 0.90, 0.91]
86
+ f1 = [0.92, 0.85, 0.94, 0.94, 0.89, 0.91]
87
+ traintest_df2 = pd.DataFrame(list(zip(prec,re,f1)),columns=['Precision', 'Recall', 'F1-score'],index =['angry', 'happy', 'neutral', 'sad', 'surprise','macro avg'])
88
+ st.dataframe(traintest_df2.style.format("{:.3}"))
89
+
90
+ def plot_features(data,sample_rate):
91
+ fig1, ax1 = plt.subplots(figsize=(6, 2))
92
+ img = librosa.display.waveshow(y = data, sr=sample_rate, x_axis="time")
93
+ ax1.set(title = 'Sample Waveform')
94
+ st.pyplot(plt.gcf())
95
+
96
+ fig2, ax2 = plt.subplots(figsize=(6, 2))
97
+ cens = librosa.feature.chroma_cens(y = data, sr=sample_rate,fmin=75)
98
+ img_cens = librosa.display.specshow(cens, y_axis = 'chroma', x_axis='time', ax=ax2)
99
+ ax2.set(title = 'Chroma_CENS')
100
+ st.pyplot(plt.gcf())
101
+
102
+ fig3, ax3 = plt.subplots(figsize=(6, 2))
103
+ spec_bw = librosa.feature.spectral_bandwidth(y = data, sr= sample_rate)
104
+ cent = librosa.feature.spectral_centroid(y = data, sr=sample_rate)
105
+ times = librosa.times_like(spec_bw)
106
+ S, phase = librosa.magphase(librosa.stft(y=data))
107
+ librosa.display.specshow(librosa.amplitude_to_db(S, ref=np.max), y_axis='log', x_axis='time', ax=ax3)
108
+ ax3.fill_between(times, np.maximum(0, cent[0] - spec_bw[0]),
109
+ np.minimum(cent[0] + spec_bw[0], sample_rate/2),
110
+ alpha=0.5, label='Centroid +- bandwidth')
111
+ ax3.plot(times, cent[0], label='Spectral centroid', color='w')
112
+ ax3.legend(loc='lower right')
113
+ ax3.set(title='log Power spectrogram')
114
+ st.pyplot(plt.gcf())
115
+
116
+ fig4, ax4 = plt.subplots(figsize=(6, 2))
117
+ mfcc = librosa.feature.mfcc(y=data, sr=sample_rate,n_mfcc=40)
118
+ mfccs = normalize(mfcc, axis=1)
119
+ img_mfcc = librosa.display.specshow(mfccs, y_axis = 'mel', x_axis='time', ax=ax4)
120
+ ax4.set(title = 'Sample Mel-Frequency Cepstral Coefficients')
121
+ st.pyplot(plt.gcf())
122
+
123
+ fig5, ax5 = plt.subplots(figsize=(6, 2))
124
+ rms = librosa.feature.rms(y=data)
125
+ times = librosa.times_like(rms)
126
+ ax5.semilogy(times, rms[0], label='RMS Energy')
127
+ ax5.set_title(f'RMS Energy')
128
+ ax5.set(xticks=[])
129
+ ax5.legend()
130
+ ax5.label_outer()
131
+ st.pyplot(plt.gcf())
132
+
133
+ fig6, ax6= plt.subplots(figsize=(6, 2))
134
+ y = librosa.effects.harmonic(data)
135
+ tonnetz = librosa.feature.tonnetz(y=y, sr=sample_rate,fmin=75)
136
+ img_tonnetz = librosa.display.specshow(tonnetz,
137
+ y_axis='tonnetz', x_axis='time', ax=ax6)
138
+ ax6.set(title=f'Tonal Centroids(Tonnetz)')
139
+ ax6.label_outer()
140
+ fig6.colorbar(img_tonnetz, ax=ax6)
141
+ st.pyplot(plt.gcf())
142
+
143
+
144
+
145
+ def find_definition(emo):
146
+ word_to_search = emo
147
+ scrape_url = 'https://www.oxfordlearnersdictionaries.com/definition/english/' + word_to_search
148
+
149
+ headers = {"User-Agent": "mekmek"}
150
+ web_response = requests.get(scrape_url, headers=headers)
151
+
152
+ if web_response.status_code == 200:
153
+ soup = BeautifulSoup(web_response.text, 'html.parser')
154
+
155
+ try:
156
+ for sense in soup.find_all('li', class_='sense'):
157
+ definition = sense.find('span', class_='def').text
158
+ for example in soup.find_all('ul', class_='examples'):
159
+ example_1 = example.text.split('.')[0:1]
160
+ except AttributeError:
161
+ print('Word not found!!')
162
+ else:
163
+ print('Failed to get response...')
164
+ return definition, example_1
165
+
166
+ def get_search_results(emo):
167
+ results_lis =[]
168
+ results = search(f"Understanding {emo}", num_results=3)
169
+ for result in results:
170
+ results_lis.append(result)
171
+ result_1 = results_lis[0]
172
+ result_2 = results_lis[1]
173
+ result_3 = results_lis[2]
174
+ return result_1, result_2, result_3
175
+
176
+ def get_content(emo):
177
+ definition, example_1 = find_definition(emo)
178
+ result_1, result_2, result_3 = get_search_results(emo)
179
+
180
+
181
+ with st.expander(f"Word Definition of {emo.capitalize()}"):
182
+ st.write(definition.capitalize()+'.')
183
+ with st.expander(f'Example of {emo.capitalize()}'):
184
+ with st.container():
185
+ st.write(f'1) {example_1[0].capitalize()}'+'.')
186
+
187
+ with st.expander(f'The following links will help you understand more on {emo.capitalize()}'):
188
+ with st.container():
189
+ st.write(f"Check out this link ➡ {result_1}")
190
+ st.write(f"Check out this link ➡ {result_2}")
191
+ st.write(f"Check out this link ➡ {result_3}")
192
+
193
+ if emo == 'anger':
194
+ with st.expander(f'Video on {emo.capitalize()}'):
195
+ with st.container():
196
+ st.video('https://www.youtube.com/watch?v=weMeIh10cLs')
197
+ if emo in 'happiness':
198
+ with st.expander(f'Video on {emo.capitalize()}'):
199
+ with st.container():
200
+ st.video('https://www.youtube.com/watch?v=FDF2DidUAyY')
201
+ if emo in 'sadness':
202
+ with st.expander(f'Video on {emo.capitalize()}'):
203
+ with st.container():
204
+ st.video('https://www.youtube.com/watch?v=34rqQEkuhK4')
205
+ if emo in 'surprised':
206
+ with st.expander(f'Video on {emo.capitalize()}'):
207
+ with st.container():
208
+ st.video('https://www.youtube.com/watch?v=UYoBi0EssLE')
209
+
210
+
211
+ def upload():
212
+ upload_file = st.sidebar.file_uploader('Upload an audio .wav file. Currently max 8 seconds', type=".wav", accept_multiple_files = False)
213
+
214
+ if upload_file:
215
+ st.write('Sample Audio')
216
+ st.audio(upload_file, format='audio/wav')
217
+
218
+ if st.sidebar.button('Show Features'):
219
+ with st.spinner(f'Showing....'):
220
+ data_ori, sample_rate = librosa.load(upload_file)
221
+ data, _ = librosa.effects.trim(data_ori)
222
+
223
+ plot_features(data,sample_rate)
224
+ st.sidebar.success("Completed")
225
+
226
+ if st.sidebar.button('Classify'):
227
+ with st.spinner(f'Classifying....'):
228
+ test = prepare_test(upload_file)
229
+ pred = classifier.predict(test)
230
+ pred_df = pd.DataFrame(pred.T,index=['anger', 'happiness','neutral','sadness','surprised'],columns =['Scores'])
231
+ emo = pred_df[pred_df['Scores'] == pred_df.max().values[0]].index[0]
232
+ st.info(f'The predicted Emotion: {emo.upper()}')
233
+ st.sidebar.success("Classification completed")
234
+
235
+ if emo:
236
+ get_content(emo)
237
+
238
+ def record():
239
+ with st.spinner(f'Recording....'):
240
+ st.sidebar.write('To start press Start Recording and stop to finish recording')
241
+ parent_dir = os.path.dirname(os.path.abspath(__file__))
242
+ build_dir = os.path.join(parent_dir, "st_audiorec/frontend/build")
243
+ st_audiorec = components.declare_component("st_audiorec", path=build_dir)
244
+ val = st_audiorec()
245
+
246
+
247
+ if isinstance(val, dict):
248
+ st.sidebar.success("Audio Recorded")
249
+ ind, val = zip(*val['arr'].items())
250
+ ind = np.array(ind, dtype=int)
251
+ val = np.array(val)
252
+ sorted_ints = val[ind]
253
+ stream = BytesIO(b"".join([int(v).to_bytes(1, "big") for v in sorted_ints]))
254
+ wav_bytes = stream.read()
255
+ rate, data = read(BytesIO(wav_bytes))
256
+ reversed_data = data[::-1]
257
+ bytes_wav = bytes()
258
+ byte_io = BytesIO(bytes_wav)
259
+ write(byte_io, rate, reversed_data)
260
+
261
+ if st.sidebar.button('Show Features'):
262
+ with st.spinner(f'Showing....'):
263
+ data_ori, sample_rate = librosa.load(byte_io)
264
+ data, _ = librosa.effects.trim(data_ori)
265
+
266
+ plot_features(data,sample_rate)
267
+ st.sidebar.success("Completed")
268
+
269
+ if st.sidebar.button('Classify'):
270
+ with st.spinner(f'Classifying....'):
271
+ test = prepare_test(byte_io)
272
+ pred = classifier.predict(test)
273
+ pred_df = pd.DataFrame(pred.T,index=['anger', 'happiness','neutral','sadness','surprised'],columns =['Scores'])
274
+ emo = pred_df[pred_df['Scores'] == pred_df.max().values[0]].index[0]
275
+ st.info(f'The predicted Emotion: {emo.upper()}')
276
+ st.sidebar.success("Classification completed")
277
+
278
+ if emo:
279
+ get_content(emo)
280
+
.ipynb_checkpoints/requirements-checkpoint.txt ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ beautifulsoup4==4.9.3
2
+ googlesearch_python==1.1.0
3
+ ipython==8.6.0
4
+ keras==2.10.0
5
+ tensorflow==2.10.0
6
+ librosa==0.9.2
7
+ matplotlib==3.6.0
8
+ numpy==1.22.1
9
+ pandas==1.4.4
10
+ requests==2.25.1
11
+ scikit_learn==1.1.3
12
+ soundfile==0.11.0
13
+ scipy==1.7.3
14
+ streamlit==1.14.0
15
+ helper==2.5.0
Audio_Classifier.py CHANGED
@@ -1,5 +1,4 @@
1
  import streamlit as st
2
- from streamlit_chat import message
3
  from helper import model, upload, record
4
 
5
  title = "Emotion Audio Classifier"
 
1
  import streamlit as st
 
2
  from helper import model, upload, record
3
 
4
  title = "Emotion Audio Classifier"
__pycache__/helper.cpython-38.pyc ADDED
Binary file (10.1 kB). View file
 
helper.py CHANGED
@@ -1,5 +1,4 @@
1
  import streamlit as st
2
- from streamlit_chat import message
3
  from keras.models import load_model
4
  import os
5
  import streamlit as st
@@ -166,7 +165,7 @@ def find_definition(emo):
166
 
167
  def get_search_results(emo):
168
  results_lis =[]
169
- results = search(f"Understanding {emo}", num_results=1)
170
  for result in results:
171
  results_lis.append(result)
172
  result_1 = results_lis[0]
@@ -195,15 +194,15 @@ def get_content(emo):
195
  with st.expander(f'Video on {emo.capitalize()}'):
196
  with st.container():
197
  st.video('https://www.youtube.com/watch?v=weMeIh10cLs')
198
- if emo in 'happy':
199
  with st.expander(f'Video on {emo.capitalize()}'):
200
  with st.container():
201
  st.video('https://www.youtube.com/watch?v=FDF2DidUAyY')
202
- if emo in 'sad':
203
  with st.expander(f'Video on {emo.capitalize()}'):
204
  with st.container():
205
  st.video('https://www.youtube.com/watch?v=34rqQEkuhK4')
206
- if emo in 'suprise':
207
  with st.expander(f'Video on {emo.capitalize()}'):
208
  with st.container():
209
  st.video('https://www.youtube.com/watch?v=UYoBi0EssLE')
@@ -228,7 +227,7 @@ def upload():
228
  with st.spinner(f'Classifying....'):
229
  test = prepare_test(upload_file)
230
  pred = classifier.predict(test)
231
- pred_df = pd.DataFrame(pred.T,index=['anger', 'happy','neutral','sad','suprise'],columns =['Scores'])
232
  emo = pred_df[pred_df['Scores'] == pred_df.max().values[0]].index[0]
233
  st.info(f'The predicted Emotion: {emo.upper()}')
234
  st.sidebar.success("Classification completed")
@@ -271,7 +270,7 @@ def record():
271
  with st.spinner(f'Classifying....'):
272
  test = prepare_test(byte_io)
273
  pred = classifier.predict(test)
274
- pred_df = pd.DataFrame(pred.T,index=['anger', 'happy','neutral','sad','suprise'],columns =['Scores'])
275
  emo = pred_df[pred_df['Scores'] == pred_df.max().values[0]].index[0]
276
  st.info(f'The predicted Emotion: {emo.upper()}')
277
  st.sidebar.success("Classification completed")
 
1
  import streamlit as st
 
2
  from keras.models import load_model
3
  import os
4
  import streamlit as st
 
165
 
166
  def get_search_results(emo):
167
  results_lis =[]
168
+ results = search(f"Understanding {emo}", num_results=3)
169
  for result in results:
170
  results_lis.append(result)
171
  result_1 = results_lis[0]
 
194
  with st.expander(f'Video on {emo.capitalize()}'):
195
  with st.container():
196
  st.video('https://www.youtube.com/watch?v=weMeIh10cLs')
197
+ if emo in 'happiness':
198
  with st.expander(f'Video on {emo.capitalize()}'):
199
  with st.container():
200
  st.video('https://www.youtube.com/watch?v=FDF2DidUAyY')
201
+ if emo in 'sadness':
202
  with st.expander(f'Video on {emo.capitalize()}'):
203
  with st.container():
204
  st.video('https://www.youtube.com/watch?v=34rqQEkuhK4')
205
+ if emo in 'surprised':
206
  with st.expander(f'Video on {emo.capitalize()}'):
207
  with st.container():
208
  st.video('https://www.youtube.com/watch?v=UYoBi0EssLE')
 
227
  with st.spinner(f'Classifying....'):
228
  test = prepare_test(upload_file)
229
  pred = classifier.predict(test)
230
+ pred_df = pd.DataFrame(pred.T,index=['anger', 'happiness','neutral','sadness','surprised'],columns =['Scores'])
231
  emo = pred_df[pred_df['Scores'] == pred_df.max().values[0]].index[0]
232
  st.info(f'The predicted Emotion: {emo.upper()}')
233
  st.sidebar.success("Classification completed")
 
270
  with st.spinner(f'Classifying....'):
271
  test = prepare_test(byte_io)
272
  pred = classifier.predict(test)
273
+ pred_df = pd.DataFrame(pred.T,index=['anger', 'happiness','neutral','sadness','surprised'],columns =['Scores'])
274
  emo = pred_df[pred_df['Scores'] == pred_df.max().values[0]].index[0]
275
  st.info(f'The predicted Emotion: {emo.upper()}')
276
  st.sidebar.success("Classification completed")
pages/.ipynb_checkpoints/Classify by file upload-checkpoint.py CHANGED
@@ -1,5 +1,4 @@
1
  import streamlit as st
2
- from streamlit_chat import message
3
  from helper import model, upload, record
4
 
5
  title = "Emotion Audio Classifier with uploaded file"
 
1
  import streamlit as st
 
2
  from helper import model, upload, record
3
 
4
  title = "Emotion Audio Classifier with uploaded file"
pages/.ipynb_checkpoints/Classify by recordings-checkpoint.py CHANGED
@@ -1,5 +1,4 @@
1
  import streamlit as st
2
- from streamlit_chat import message
3
  from helper import model, upload, record
4
 
5
  title = "Emotion Audio Classifier with recordings"
 
1
  import streamlit as st
 
2
  from helper import model, upload, record
3
 
4
  title = "Emotion Audio Classifier with recordings"
pages/Classify by file upload.py CHANGED
@@ -1,5 +1,4 @@
1
  import streamlit as st
2
- from streamlit_chat import message
3
  from helper import model, upload, record
4
 
5
  title = "Emotion Audio Classifier with uploaded file"
 
1
  import streamlit as st
 
2
  from helper import model, upload, record
3
 
4
  title = "Emotion Audio Classifier with uploaded file"
pages/Classify by recordings.py CHANGED
@@ -1,5 +1,4 @@
1
  import streamlit as st
2
- from streamlit_chat import message
3
  from helper import model, upload, record
4
 
5
  title = "Emotion Audio Classifier with recordings"
 
1
  import streamlit as st
 
2
  from helper import model, upload, record
3
 
4
  title = "Emotion Audio Classifier with recordings"
requirements.txt CHANGED
@@ -12,5 +12,4 @@ scikit_learn==1.1.3
12
  soundfile==0.11.0
13
  scipy==1.7.3
14
  streamlit==1.14.0
15
- streamlit_chat==0.0.2.1
16
  helper==2.5.0
 
12
  soundfile==0.11.0
13
  scipy==1.7.3
14
  streamlit==1.14.0
 
15
  helper==2.5.0