File size: 6,912 Bytes
74569a1
 
4815911
74569a1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6bcf173
 
74569a1
 
 
 
 
 
 
6bcf173
74569a1
 
6bcf173
74569a1
 
 
6bcf173
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74569a1
 
 
a39ef94
74569a1
a39ef94
74569a1
a39ef94
74569a1
a39ef94
74569a1
a39ef94
74569a1
a39ef94
74569a1
6bcf173
74569a1
 
 
 
6bcf173
74569a1
 
 
 
6bcf173
74569a1
 
 
6bcf173
74569a1
 
 
 
 
 
 
 
dc45e5e
74569a1
 
6bcf173
4815911
 
dc45e5e
 
4815911
 
 
 
dc45e5e
 
 
 
4815911
 
 
 
74569a1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6bcf173
a39ef94
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import streamlit as st
import joblib
import pandas as pd
import numpy as np
import xgboost
# from sklearn.ensemble import GradientBoostingClassifier
# from tensorflow.keras.models import load_model
import tensorflow
from keras.losses import binary_crossentropy
from keras.optimizers import Adam
from tensorflow import keras
from keras.models import load_model
# Local Imports
import feature_extraction
import audio_splitting

# Create a Streamlit web app
st.title("Music Genre Classifier")
st.write("A single-label music genre classifier based and trained on the GTZAN Dataset available for use on "
         "Kaggle. All the models have been trained on that dataset.")
# Upload music file
uploaded_file = st.file_uploader("Upload a music file", type=["mp3", "wav"])

if uploaded_file is not None:
    # User selects a model
    all_models = ["K-Nearest Neighbors - (Single Label)", "Logistic Regression - (Single Label)", "Support Vector Machines - (Single Label)",
                  "Neural Network - (Single Label)",
                  "XGB Classifier - (Single Label)"]
    model_name = st.selectbox("Select a model", all_models)
    st.write(f"Predicition of following genres")

    multi_class_names = ["Metal", "Jazz", "Blues", "R&B", "Classical", "Reggae", "Rap & Hip-Hop", "Punk", "Rock",
                         "Country", "Bebop", "Pop", "Soul", "Dance & Electronic", "Folk"]

    class_names = ["Blues", "Classical", "Country", "Disco", "HipHop",
                   "Jazz", "Metal", "Pop", "Reggae", "Rock"]

    col1, col2 = st.columns(2)
    s = ''
    with col1:
        for i in class_names[:5]:
            s += "- " + i + "\n"
        st.markdown(s)

    s = ''

    with col2:
        for i in class_names[5:]:
            s += "- " + i + "\n"
        st.markdown(s)
    # st.write(multi_class_names)

    # Load the selected model
    if model_name == "K-Nearest Neighbors - (Single Label)":
        model = joblib.load("./models/knn.pkl")
    elif model_name == "Logistic Regression - (Single Label)":
        model = joblib.load("./models/logistic.pkl")
    elif model_name == "Support Vector Machines - (Single Label)":
        model = joblib.load("./models/svm.pkl")
    elif model_name == "Neural Network - (Single Label)":
        model = joblib.load("./models/nn.pkl")
    elif model_name == "XGB Classifier - (Single Label)":
        model = joblib.load("./models/xgb.pkl")
    elif model_name == "XGB - (Multi Label)":
        model = joblib.load("./models/xgb_mlb.pkl")
    elif model_name == "Convolutional Recurrent Neural Network - (Multi Label)":
        model = tensorflow.keras.models.load_model("../models/model_crnn1.h5", compile=False)
        model.compile(loss=binary_crossentropy,
                      optimizer=Adam(),
                      metrics=['accuracy'])
    elif model_name == "Neural Network - (Multi Label)":
        model = tensorflow.keras.models.load_model("../models/model_nn.h5", compile=False)
        model.compile(loss=binary_crossentropy,
                      optimizer=Adam(),
                      metrics=['accuracy'])
    elif model_name == "Batch Normalization - (Multi Label)":
        model = tensorflow.keras.models.load_model("../models/model_bn.h5", compile=False)
        model.compile(loss=binary_crossentropy,
                      optimizer=Adam(),
                      metrics=['accuracy'])
    # class_names = ["blues", "classical", "country", "disco", "hiphop", "jazz", "metal", "pop", "reggae", "rock"]

    xgb_multi_class_names = ["Rock", "Rap & Hip-Hop", "Soul", "Classical", "Dance & Electronic", "Blues","Jazz",
                             "Country","Bebop","Folk","Reggae","R&B","Punk","Metal","Pop"]

    xmulti_class_names = ["Metal", "Blues", "Reggae", "Jazz", "Rock", "Folk", "Classical", "Dance & Electronic",
                         "Punk","Bebop", "Pop", "R&B", "Country", "Rap & Hip-Hop", "Soul"]
    class_indices = {i: class_name for i, class_name in enumerate(class_names)}

    features_list,val_list = audio_splitting.split_audio(uploaded_file)
    features = feature_extraction.scale(features_list)

    # st.write(features)
    # Features Dataframe
    df = pd.DataFrame({
        "fname": ["Chroma_STFT"],
        "Values": val_list
    })
    st.dataframe(
        df,
        column_config={
            "name": "Features",
            "Values": st.column_config.LineChartColumn(
                "Graph Values",y_min=0,y_max = 10000
            )
        }
    )


    # Reshape the features to match the expected shape for prediction
    reshaped_features = features.reshape(1, -1)
    if model_name == "XGB - (Multi Label)":
        # Predict labels for the input features
        predicted_indices = model.predict(reshaped_features)
        print(predicted_indices)
        predicted_labels = []
        for i in range(0,len(predicted_indices[0])):
            if predicted_indices[0][i]==1.0:
                predicted_labels.append(xgb_multi_class_names[i])
        if predicted_labels:
            st.write(f"Predicted Genres: {', '.join(predicted_labels)}")
        else:
            st.write("No genres predicted for this input.")
    if model_name == "XGB Classifier - (Single Label)":
        predicted_indices = model.predict(reshaped_features)
        predicted_labels = [class_indices[i] for i in predicted_indices]
        st.write(f"Predicted Genre: {predicted_labels[0]}")
    elif model_name == "Convolutional Recurrent Neural Network - (Multi Label)"\
            or model_name == "Neural Network - (Multi Label)"\
            or model_name == "Batch Normalization - (Multi Label)":
        predicted_probabilities = model.predict(reshaped_features)

        # Set a threshold for class prediction (e.g., 0.5)
        threshold = 0.3
        print(predicted_probabilities)
        probabilities = []
        if model_name == "Convolutional Recurrent Neural Network - (Multi Label)":
            predicted_labels = [class_name for i, class_name in enumerate(multi_class_names) if
                                predicted_probabilities[0][i] >= threshold]
            probabilities = [(class_name,predicted_probabilities[0][i]*100) for i, class_name in enumerate(multi_class_names)]

        else:
            predicted_labels = [class_name for i,class_name in enumerate(xmulti_class_names) if
                                predicted_probabilities[0][i] >= threshold]
            probabilities = [(class_name,predicted_probabilities[0][i]*100) for i, class_name in enumerate(xmulti_class_names)]

        if predicted_labels:
            st.write(f"All probabilities are:")
            st.write(probabilities)
            st.write(f"Predicted Genres: {', '.join(predicted_labels)}")
        else:
            st.write("No genre predicted above the threshold.")
    else:
        predicted_label = model.predict(features)[0]
        st.metric("Predicted Genre:",str(predicted_label))