|
|
--- |
|
|
license: mit |
|
|
datasets: |
|
|
- Clemylia/Tempo |
|
|
language: |
|
|
- fr |
|
|
pipeline_tag: audio-classification |
|
|
tags: |
|
|
- music |
|
|
- Rythme |
|
|
- classification |
|
|
- decalage |
|
|
- problème de rythme |
|
|
--- |
|
|
|
|
|
# 🩷🌸 Musica 🌸🩷 |
|
|
|
|
|
 |
|
|
|
|
|
## 🦋 **c'est quoi** ? |
|
|
|
|
|
Musica est un projet de machine learning, |
|
|
de type classification d'audio, |
|
|
il a été conçu pour classifier les chansons au niveau de leur rythme (calé ou décalé), |
|
|
C'est-à-dire de percevoir les décalages rythmiques dans les chansons. |
|
|
|
|
|
## ❤️ Comment utiliser ? |
|
|
|
|
|
Pour utiliser Musica, |
|
|
Qui a été crée from scratch sur la dataset Clemylia/Tempo, |
|
|
Vous devez reconstruire le code d'inférence, |
|
|
Voici un exemple de code d'utilisation : |
|
|
|
|
|
``` |
|
|
import torch |
|
|
import torch.nn as nn |
|
|
import torch.nn.functional as F |
|
|
import torchaudio |
|
|
import numpy as np |
|
|
from huggingface_hub import hf_hub_download |
|
|
from datasets import load_dataset, Audio # On garde l'import au cas où |
|
|
|
|
|
# ============================================================================= |
|
|
# PARTIE 1 : DÉFINITION DE L'ARCHITECTURE (inchangée) |
|
|
# ============================================================================= |
|
|
|
|
|
NUM_CLASSES = 2 |
|
|
N_MELS = 128 |
|
|
|
|
|
class AudioClassifier(nn.Module): |
|
|
"""Réseau de Neurones Convolutionnels (CNN) que nous avons entraîné.""" |
|
|
def __init__(self): |
|
|
super(AudioClassifier, self).__init__() |
|
|
self.conv1 = nn.Conv2d(in_channels=1, out_channels=32, kernel_size=(5, 5), padding=2) |
|
|
self.bn1 = nn.BatchNorm2d(32) |
|
|
self.pool1 = nn.MaxPool2d(kernel_size=(2, 2)) |
|
|
self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=(3, 3), padding=1) |
|
|
self.bn2 = nn.BatchNorm2d(64) |
|
|
self.pool2 = nn.MaxPool2d(kernel_size=(2, 2)) |
|
|
self.conv3 = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=(3, 3), padding=1) |
|
|
self.bn3 = nn.BatchNorm2d(128) |
|
|
self.pool3 = nn.MaxPool2d(kernel_size=(2, 2)) |
|
|
self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) |
|
|
self.fc1 = nn.Linear(128 * 1 * 1, NUM_CLASSES) |
|
|
|
|
|
def forward(self, x): |
|
|
x = self.pool1(F.relu(self.bn1(self.conv1(x)))) |
|
|
x = self.pool2(F.relu(self.bn2(self.conv2(x)))) |
|
|
x = self.pool3(F.relu(self.bn3(self.conv3(x)))) |
|
|
x = self.avgpool(x) |
|
|
x = torch.flatten(x, 1) |
|
|
return self.fc1(x) |
|
|
|
|
|
|
|
|
# ============================================================================= |
|
|
# PARTIE 2 : FONCTIONS DE PRÉPARATION POUR L'INFÉRENCE (inchangée) |
|
|
# ============================================================================= |
|
|
|
|
|
SAMPLING_RATE = 16000 |
|
|
N_FFT = 400 |
|
|
HOP_LENGTH = 160 |
|
|
MAX_TIME_STEPS = 300 |
|
|
|
|
|
def prepare_spectrogram(audio_path): |
|
|
""" |
|
|
Charge un fichier audio, calcule le Log-Mel Spectrogramme, et le prépare |
|
|
pour le modèle. |
|
|
""" |
|
|
# 1. Charger et Rééchantillonner |
|
|
waveform, sr = torchaudio.load(audio_path) |
|
|
if sr != SAMPLING_RATE: |
|
|
resampler = torchaudio.transforms.Resample(orig_freq=sr, new_freq=SAMPLING_RATE) |
|
|
waveform = resampler(waveform) |
|
|
|
|
|
if waveform.shape[0] > 1: |
|
|
waveform = torch.mean(waveform, dim=0, keepdim=True) |
|
|
|
|
|
# 2. Calculer le Log-Mel Spectrogramme |
|
|
mel_spectrogram_transform = torchaudio.transforms.MelSpectrogram( |
|
|
sample_rate=SAMPLING_RATE, |
|
|
n_fft=N_FFT, |
|
|
hop_length=HOP_LENGTH, |
|
|
n_mels=N_MELS, |
|
|
) |
|
|
mel_spectrogram = mel_spectrogram_transform(waveform.squeeze(0)) |
|
|
log_mel_spectrogram = torchaudio.transforms.AmplitudeToDB()(mel_spectrogram) |
|
|
|
|
|
# 3. Tronquer |
|
|
if log_mel_spectrogram.shape[1] > MAX_TIME_STEPS: |
|
|
log_mel_spectrogram = log_mel_spectrogram[:, :MAX_TIME_STEPS] |
|
|
|
|
|
# 4. Ajouter les dimensions Batch et Channel : [1, 1, N_MELS, Time_Steps] |
|
|
input_tensor = log_mel_spectrogram.unsqueeze(0).unsqueeze(0) |
|
|
|
|
|
return input_tensor |
|
|
|
|
|
|
|
|
def predict_audio(model, audio_tensor): |
|
|
""" |
|
|
Effectue la prédiction et retourne l'étiquette. |
|
|
""" |
|
|
model.eval() |
|
|
device = next(model.parameters()).device |
|
|
|
|
|
with torch.no_grad(): |
|
|
audio_tensor = audio_tensor.to(device) |
|
|
outputs = model(audio_tensor) |
|
|
|
|
|
probabilities = F.softmax(outputs, dim=1) |
|
|
predicted_index = torch.argmax(probabilities, dim=1).item() |
|
|
|
|
|
# Décodeur des classes (assumant 0 = Calé, 1 = Décalé) |
|
|
class_labels = {0: "Calé (On Beat)", 1: "Décalé (Off Beat)"} |
|
|
|
|
|
return class_labels[predicted_index], probabilities[0].cpu().numpy() |
|
|
|
|
|
|
|
|
# ============================================================================= |
|
|
# PARTIE 3 : CHARGEMENT DU MODÈLE ET EXÉCUTION DU TEST (CORRIGÉE) |
|
|
# ============================================================================= |
|
|
|
|
|
# --- Configuration Hugging Face --- |
|
|
REPO_ID = "Clemylia/Musica1" |
|
|
MODEL_FILENAME = "pytorch_model.bin" |
|
|
|
|
|
# 1. Télécharger les poids du modèle |
|
|
print(f"1. Téléchargement des poids du modèle depuis {REPO_ID}...") |
|
|
try: |
|
|
model_path = hf_hub_download(repo_id=REPO_ID, filename=MODEL_FILENAME) |
|
|
except Exception as e: |
|
|
print(f"Erreur de téléchargement : {e}. Vérifiez le nom du dépôt et les permissions.") |
|
|
exit() |
|
|
|
|
|
# 2. Charger le modèle |
|
|
device = torch.device("cuda" if torch.cuda.is_available() else "cpu") |
|
|
model = AudioClassifier() |
|
|
|
|
|
try: |
|
|
model.load_state_dict(torch.load(model_path, map_location=device)) |
|
|
model.to(device) |
|
|
print(f"2. Modèle chargé avec succès sur {device}.") |
|
|
except Exception as e: |
|
|
print(f"Erreur lors du chargement des poids : {e}") |
|
|
exit() |
|
|
|
|
|
# 3. Préparer une donnée de test |
|
|
|
|
|
# *** CORRECTION MAJEURE *** |
|
|
# Veuillez remplacer le chemin ci-dessous par un chemin valide sur votre système ! |
|
|
# Exemple : "C:/Users/Clemylia/Desktop/mes_sons/calé_test.wav" ou "./data/audio_test.mp3" |
|
|
# ---------------------------------------------------------------------------------- |
|
|
AUDIO_TEST_FILE = input("Veuillez entrer le chemin complet d'un fichier audio (ex: /path/to/test.wav): ") |
|
|
# ---------------------------------------------------------------------------------- |
|
|
|
|
|
print(f"\n3. Préparation d'un échantillon de test à partir de: {AUDIO_TEST_FILE}...") |
|
|
|
|
|
try: |
|
|
input_tensor = prepare_spectrogram(AUDIO_TEST_FILE) |
|
|
audio_test_path = AUDIO_TEST_FILE # Pour l'affichage final |
|
|
|
|
|
except Exception as e: |
|
|
print(f"Erreur lors de la préparation de l'échantillon de test (le fichier existe-t-il ? le format est-il pris en charge par torchaudio ?) : {e}") |
|
|
input_tensor = None |
|
|
|
|
|
|
|
|
# 4. Exécuter la prédiction |
|
|
if input_tensor is not None: |
|
|
print(f"\n4. Exécution de la prédiction sur l'échantillon...") |
|
|
|
|
|
prediction, probabilities = predict_audio(model, input_tensor) |
|
|
|
|
|
# Affichage des résultats |
|
|
print("\n-------------------------------------------") |
|
|
print(f"FICHIER TESTÉ: {audio_test_path}") |
|
|
print(f"PRÉDICTION: {prediction}") |
|
|
print(f"PROBABILITÉS: Calé={probabilities[0]:.4f}, Décalé={probabilities[1]:.4f}") |
|
|
print("-------------------------------------------") |
|
|
else: |
|
|
print("Test annulé faute de pouvoir traiter le fichier audio.") |
|
|
``` |
|
|
## ❤️🔥 Informations sur Musica |
|
|
|
|
|
**nom** : Musica |
|
|
**version** : 1 (entraînement sur un tout petit dataset) |
|
|
**développeur** : Clemylia |
|
|
**Tache** : détecter si une chanson est dans le rythme où pas |
|
|
|
|
|
❤️**amusez vous bien à détecter si vos chansons d'anniversaire, vos bruits de bouches, vos cover de chansons ou autre sont calé et si vous avez le rythme !**❤️ |