Music Genre Classifier

Music Genre Classifier

Music Genre Classifier

A step-by-step guide to classifying music genres using Spectrograms and a CNN.

Libraries Used

This pipeline uses a few key Python libraries. Here is a quick overview of their roles:

  • tensorflow: The core deep learning framework.
  • numpy: Used for numerical operations.
  • librosa: A Python library for audio analysis, used here to extract audio features and create spectrograms.
  • matplotlib: A plotting library for visualizing the spectrograms.

1. Data Loading and Feature Extraction

  • What the code does: It uses the `librosa` library to load a sample audio file and then creates a `Mel Spectrogram`, which is a visual representation of the audio's frequency content over time. This spectrogram is treated as an image.
  • Behind the scenes: Humans don't process raw audio waves; we perceive sound based on frequency and loudness. A spectrogram mimics this by mapping the audio to an image where the x-axis is time, the y-axis is frequency, and color intensity represents amplitude.
  • Abstraction: The `librosa.feature.melspectrogram` function abstracts the complex process of performing a Short-Time Fourier Transform and converting the result to the mel scale, which better represents human hearing.
import librosa
import librosa.display
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras import layers, models

# --- Dummy Data Generation ---
# In a real scenario, you would have a dataset of audio files
def generate_random_spectrograms(num_samples, shape=(128, 431)):
    return np.random.rand(num_samples, shape[0], shape[1], 1)

def generate_random_labels(num_samples, num_genres):
    return np.random.randint(0, num_genres, size=num_samples)

X_train = generate_random_spectrograms(800)
y_train = generate_random_labels(800, 10)
X_test = generate_random_spectrograms(200)
y_test = generate_random_labels(200, 10)

print(f"Shape of training data (spectrograms): {X_train.shape}")
print(f"Shape of training labels: {y_train.shape}")

2. Building the CNN Model

  • What the code does: It constructs a CNN, similar to a standard image classifier, but tailored for the shape of the spectrograms.
  • Behind the scenes: The CNN's convolutional layers are excellent at detecting patterns in images. In this case, they will learn to identify frequency and temporal patterns that are characteristic of different music genres.
  • Abstraction: We can reuse the same `Conv2D` and `MaxPooling2D` layers that are used for images because a spectrogram is essentially an image representation of sound. This highlights the power of CNNs for various data types.
# Define the input shape
input_shape = (X_train.shape[1], X_train.shape[2], 1)
num_genres = 10

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=input_shape))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(num_genres, activation='softmax'))

model.summary()

3. Training and Evaluation

  • What the code does: It compiles the model with an optimizer and a categorical cross-entropy loss function, then trains it on the spectrograms.
  • Behind the scenes: Since music genre classification is a multi-class problem (each song belongs to exactly one genre), `sparse_categorical_crossentropy` is a suitable loss function. The model's weights are adjusted to minimize this loss.
  • Abstraction: The `model.fit` method handles the complex task of training the CNN on the pre-processed spectrograms, allowing you to focus on the results rather than the low-level implementation details.
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

history = model.fit(X_train, y_train, epochs=10,
                    validation_data=(X_test, y_test))

test_loss, test_acc = model.evaluate(X_test, y_test, verbose=2)
print(f"\nTest accuracy: {test_acc}")

Comments

Popular posts from this blog

Reinforcement Learning with a Deep Q-Network (DQN)

Text Generation with a Character-level RNN

Simple Transformer for Text Classification