Urban Sound Classification using Neural Networks | by Shubham Gupta | Towards Data Science

Every day we hear different sounds and it is part of our life. Humans can differentiate between sounds easily but how cool it will be if computer can also classify the sounds into categories.
In this blog post, we’ll learn techniques for classifying urban sounds into categories using machine learning with neural networks. The dataset is taken from a competition in analytics vidya called Urban Sound. This dataset contains 8732 labelled sound excerpts of urban sounds from 10 classes: air_conditioner, car_horn, children_playing, dog_bark, drilling, enginge_idling, gun_shot, jackhammer, siren, and street_music.
I will use the python librosa library to extract numerical features from audio clips and use those features to train a neural network model.
First, let us get all the required libraries,
import IPython.display as ipdimport osimport numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport librosafrom tqdm import tqdmfrom sklearn.preprocessing import StandardScalerfrom keras.models import Sequentialfrom keras.layers import Dense, Dropout, Activationfrom keras.optimizers import Adam
The dataset is available in a google drive, it can be downloaded from here.
The dataset contain train, test folder in which sound excerpts are saved and there are train.csv and test.csv which have labels of each sound excerpts. I will be using only train folder for training, validation and testing, it contains 5435 labelled sounds.
Now let’s read the train.csv which contains labelled information about sound excerpts.
data=pd.read_csv('/content/drive/MyDrive/colab_notebook/train.csv')data.head()#To see the dataset
Let’s hear any random sound from the dataset,
ipd.Audio(‘/content/drive/My Drive/colab_notebook/Train/123.wav’)
Now, the main step is to extract features from the dataset. For this, I will be using librosa library. It is a good library to use with audio files.
Using librosa library, I will be extracting four features from the audio files. These features are Mel-frequency cepstral coefficients (MFCCs), tonnetz, mel-scaled spectrogram and chromagram from a waveform.
mfc=[]chr=[]me=[]ton=[]lab=[]for i in tqdm(range(len(data))):    f_name='/content/drive/My Drive/colab_notebook/Train/'+str(data.ID[i])+'.wav'    X, s_rate = librosa.load(f_name, res_type='kaiser_fast')    mf = np.mean(librosa.feature.mfcc(y=X, sr=s_rate).T,axis=0)    mfc.append(mf)    l=data.Class[i]    lab.append(l)    try:        t =    np.mean(librosa.feature.tonnetz(                       y=librosa.effects.harmonic(X),                       sr=s_rate).T,axis=0)        ton.append(t)    except:        print(f_name)      m = np.mean(librosa.feature.melspectrogram(X, sr=s_rate).T,axis=0)    me.append(m)    s = np.abs(librosa.stft(X))    c = np.mean(librosa.feature.chroma_stft(S=s, sr=s_rate).T,axis=0)    chr.append(c)
I have got 186 features for each audio files with their respective labels.
After extracting features from the audio files save the features because it will take a lot of time to extract features.
mfcc = pd.DataFrame(mfc)mfcc.to_csv('/content/drive/My Drive/colab_notebook/mfc.csv', index=False)chrr = pd.DataFrame(chr)chrr.to_csv('/content/drive/My Drive/colab_notebook/chr.csv', index=False)mee = pd.DataFrame(me)mee.to_csv('/content/drive/My Drive/colab_notebook/me.csv', index=False)tonn = pd.DataFrame(ton)tonn.to_csv('/content/drive/My Drive/colab_notebook/ton.csv', index=False)la = pd.DataFrame(lab)la.to_csv('/content/drive/My Drive/colab_notebook/labels.csv', index=False)
Concatenate features into one array so that it can be passed to the model.
features = []for i in range(len(ton)):    features.append(np.concatenate((me[i], mfc[i],                 ton[i], chr[i]), axis=0))
Encode the labels so that model can understand.
la = pd.get_dummies(lab)label_columns=la.columns #To get the classestarget = la.to_numpy() #Convert labels to numpy array
Now normalize the features so that gradient descents can converge more quickly.
tran = StandardScaler()features_train = tran.fit_transform(features)
Now I will create train, validation and test dataset.
feat_train=features_train[:4434]target_train=target[:4434]y_train=features_train[4434:5330]y_val=target[4434:5330]test_data=features_train[5330:]test_label=lab['0'][5330:]print("Training",feat_train.shape)print(target_train.shape)print("Validation",y_train.shape)print(y_val.shape)print("Test",test_data.shape)print(test_label.shape)
Next step is to build the model.
model = Sequential()model.add(Dense(186, input_shape=(186,), activation = 'relu'))model.add(Dense(256, activation = 'relu'))model.add(Dropout(0.6))model.add(Dense(128, activation = 'relu'))model.add(Dropout(0.5))model.add(Dense(10, activation = 'softmax'))model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')
This is the final model which will be used for training.
history = model.fit(feat_train, target_train, batch_size=64, epochs=30,                     validation_data=(y_train, y_val))
The model will train for epoch =30 and has a batch size of 64.
After training the model it gives the validation accuracy of 92%.
Now let’s see how our model will perform on test dataset.
predict = model.predict_classes(test_data) #To predict labels
This will get the values now to get the prediction as classes.
prediction=[]for i in predict:  j=label_columns[i]  prediction.append(j)
Prediction has 104 test label, and now calculate how many are correctly predicted.
k=0for i, j in zip(test_label,prediction):    if i==j:       k=k+1
Out of 104 labels, this model has correctly predicted 94 labels, which is very good.
In this blog, we have discussed how to extract features from audio files using librosa library and then build a model to classify audio files in different classes.
All the code in this article resides on this Github link: