Skip to content

Commit 42f6b55

Browse files
committed
Added Test functinoality
1 parent 6802e8a commit 42f6b55

2 files changed

Lines changed: 185 additions & 0 deletions

File tree

ser.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from sklearn.neural_network import MLPClassifier
2+
3+
from sklearn.metrics import accuracy_score
4+
from utils import load_data
5+
6+
import os
7+
import pickle
8+
9+
# load RAVDESS dataset
10+
X_train, X_test, y_train, y_test = load_data(test_size=0.25)
11+
# print some details
12+
# number of samples in training data
13+
print("[+] Number of training samples:", X_train.shape[0])
14+
# number of samples in testing data
15+
print("[+] Number of testing samples:", X_test.shape[0])
16+
# number of features used
17+
# this is a vector of features extracted
18+
# using utils.extract_features() method
19+
print("[+] Number of features:", X_train.shape[1])
20+
# best model, determined by a grid search
21+
model_params = {
22+
'alpha': 0.01,
23+
'batch_size': 256,
24+
'epsilon': 1e-08,
25+
'hidden_layer_sizes': (300,),
26+
'learning_rate': 'adaptive',
27+
'max_iter': 500,
28+
}
29+
# initialize Multi Layer Perceptron classifier
30+
# with best parameters ( so far )
31+
model = MLPClassifier(**model_params)
32+
33+
# train the model
34+
print("[*] Training the model...")
35+
model.fit(X_train, y_train)
36+
37+
# predict 25% of data to measure how good we are
38+
y_pred = model.predict(X_test)
39+
40+
# calculate the accuracy
41+
accuracy = accuracy_score(y_true=y_test, y_pred=y_pred)
42+
43+
print("Accuracy: {:.2f}%".format(accuracy*100))
44+
45+
# now we save the model
46+
# make result directory if doesn't exist yet
47+
if not os.path.isdir("result"):
48+
os.mkdir("result")
49+
50+
pickle.dump(model, open("result/mlp_classifier.model", "wb"))

test.py

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import pyaudio
2+
import os
3+
import wave
4+
import pickle
5+
from sys import byteorder
6+
from array import array
7+
from struct import pack
8+
from sklearn.neural_network import MLPClassifier
9+
10+
from utils import extract_feature
11+
12+
THRESHOLD = 500
13+
CHUNK_SIZE = 1024
14+
FORMAT = pyaudio.paInt16
15+
RATE = 16000
16+
17+
SILENCE = 30
18+
19+
def is_silent(snd_data):
20+
"Returns 'True' if below the 'silent' threshold"
21+
return max(snd_data) < THRESHOLD
22+
23+
def normalize(snd_data):
24+
"Average the volume out"
25+
MAXIMUM = 16384
26+
times = float(MAXIMUM)/max(abs(i) for i in snd_data)
27+
28+
r = array('h')
29+
for i in snd_data:
30+
r.append(int(i*times))
31+
return r
32+
33+
def trim(snd_data):
34+
"Trim the blank spots at the start and end"
35+
def _trim(snd_data):
36+
snd_started = False
37+
r = array('h')
38+
39+
for i in snd_data:
40+
if not snd_started and abs(i)>THRESHOLD:
41+
snd_started = True
42+
r.append(i)
43+
44+
elif snd_started:
45+
r.append(i)
46+
return r
47+
48+
# Trim to the left
49+
snd_data = _trim(snd_data)
50+
51+
# Trim to the right
52+
snd_data.reverse()
53+
snd_data = _trim(snd_data)
54+
snd_data.reverse()
55+
return snd_data
56+
57+
def add_silence(snd_data, seconds):
58+
"Add silence to the start and end of 'snd_data' of length 'seconds' (float)"
59+
r = array('h', [0 for i in range(int(seconds*RATE))])
60+
r.extend(snd_data)
61+
r.extend([0 for i in range(int(seconds*RATE))])
62+
return r
63+
64+
def record():
65+
"""
66+
Record a word or words from the microphone and
67+
return the data as an array of signed shorts.
68+
Normalizes the audio, trims silence from the
69+
start and end, and pads with 0.5 seconds of
70+
blank sound to make sure VLC et al can play
71+
it without getting chopped off.
72+
"""
73+
p = pyaudio.PyAudio()
74+
stream = p.open(format=FORMAT, channels=1, rate=RATE,
75+
input=True, output=True,
76+
frames_per_buffer=CHUNK_SIZE)
77+
78+
num_silent = 0
79+
snd_started = False
80+
81+
r = array('h')
82+
83+
while 1:
84+
# little endian, signed short
85+
snd_data = array('h', stream.read(CHUNK_SIZE))
86+
if byteorder == 'big':
87+
snd_data.byteswap()
88+
r.extend(snd_data)
89+
90+
silent = is_silent(snd_data)
91+
92+
if silent and snd_started:
93+
num_silent += 1
94+
elif not silent and not snd_started:
95+
snd_started = True
96+
97+
if snd_started and num_silent > SILENCE:
98+
break
99+
100+
sample_width = p.get_sample_size(FORMAT)
101+
stream.stop_stream()
102+
stream.close()
103+
p.terminate()
104+
105+
r = normalize(r)
106+
r = trim(r)
107+
r = add_silence(r, 0.5)
108+
return sample_width, r
109+
110+
def record_to_file(path):
111+
"Records from the microphone and outputs the resulting data to 'path'"
112+
sample_width, data = record()
113+
data = pack('<' + ('h'*len(data)), *data)
114+
115+
wf = wave.open(path, 'wb')
116+
wf.setnchannels(1)
117+
wf.setsampwidth(sample_width)
118+
wf.setframerate(RATE)
119+
wf.writeframes(data)
120+
wf.close()
121+
122+
123+
if __name__ == "__main__":
124+
# load the saved model (after training)
125+
model = pickle.load(open("result/mlp_classifier.model", "rb"))
126+
print("Please talk")
127+
filename = "test.wav"
128+
# record the file (start talking)
129+
record_to_file(filename)
130+
# extract features and reshape it
131+
features = extract_feature(filename, mfcc=True, chroma=True, mel=True).reshape(1, -1)
132+
# predict
133+
result = model.predict(features)[0]
134+
# show the result !
135+
print("result:", result)

0 commit comments

Comments
 (0)