Prétraitement du son

Comment convertir du son en features ? That is the question.

Création d’un WAV

[16]:
import os

audio_path = "images/output.wav"
if not os.path.exists(audio_path):
    import sounddevice as sd
    from scipy.io.wavfile import write
    import numpy as np

    # Paramètres d'enregistrement
    samplerate = 16000  # 16kHz (standard pour ML et ASR)
    duration = 5  # Durée de l'enregistrement en secondes

    print("🎤 Enregistrement en cours...")
    audio = sd.rec(
        int(samplerate * duration), samplerate=samplerate, channels=1, dtype=np.int16
    )
    sd.wait()  # Attendre la fin de l'enregistrement

    # Sauvegarder en fichier .wav

    write(audio_path, samplerate, audio)
    print("done")
else:
    print("done already")
done already

librosa

librosa : le son est de longueur variable et il faut construire un vecteur de taille finie afin de pouvoir l’utiliser avec un prédicteur. On découpe le signal, on estime des features, puis on aggrège d’une façon ou d’une autre.

[17]:
import librosa
import numpy as np

# Charger un fichier audio
print(f"chargement du fichier: {audio_path!r}")
y, sr = librosa.load(
    audio_path, sr=None
)  # sr=None garde le taux d'échantillonnage original

# Extraction des caractéristiques audio (MFCCs)
print(f"features: {audio_path!r}")
mfccs = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13)
mfccs.shape
chargement du fichier: 'images/output.wav'
features: 'images/output.wav'
[17]:
(13, 157)
[18]:
mfccs = np.mean(mfccs, axis=1)
mfccs.shape
[18]:
(13,)

Prétraitement avancé ou transfer learning

Cette méthode s’apparente à une transfer learning. Quand on dispose de peu de données, il est difficile d’apprendre un modèle performant sur des données complexes type image ou son. En revanche, on peut utiliser la sortie d’un modèle appris sur des grandes quantité de données et les utiliser comme feature. On parle d” embedding.

Le package transformers offre plein de modèle de traitement de son, reconnaissance de la parole et autres traitements, il faut choisir un modèle qui s’approche de la tâche à réaliser par la suite. L’exemple suivant considère un petit modèle distil-wav2vec2 et transcrit le son en mots. Ce n’est pas le plus performant car c’est un petit modèle. On peut utiliser comme features la sortie du préprocesseur, celle du modèle… Tout dépend de ce qui suit.

[49]:
import torch
import librosa
from transformers import WhisperProcessor, WhisperForConditionalGeneration

# Charger le modèle et le processeur
model_name = "openai/whisper-tiny"
print(f"téléchargement du preprocesseur {model_name!r}")
processor = WhisperProcessor.from_pretrained(model_name)
print(f"téléchargement du modèle {model_name!r}")
model = WhisperForConditionalGeneration.from_pretrained(model_name)
print(f"chargement du fichier audio {audio_path!r}")
y, sr = librosa.load(
    audio_path, sr=16000
)  # wav2vec2 attend un échantillonnage de 16kHz

# Transformer en tenseur
input_features = processor(y, sampling_rate=16000, return_tensors="pt").input_features
input_features.shape, input_features.dtype
téléchargement du preprocesseur 'openai/whisper-tiny'
téléchargement du modèle 'openai/whisper-tiny'
chargement du fichier audio 'images/output.wav'
[49]:
(torch.Size([1, 80, 3000]), torch.float32)
[50]:
predicted_ids = model.generate(input_features)
predicted_ids.shape, predicted_ids.dtype
[50]:
(torch.Size([1, 14]), torch.int64)
[47]:
# Décoder le texte
transcription = processor.batch_decode(predicted_ids, skip_special_tokens=True)[0]
print("Texte reconnu :", transcription)
Texte reconnu :  création l'infiche-roix avec p'ton.

Pour avoir des features réels, on peut aussi appeler le modèle une seule fois mais le modèle n’aura peut-être traité toute la séquence. Il faut comprendre le modèle avant d’utiliser ce code.

[55]:
new_features = model(
    input_features=input_features,
    decoder_input_ids=torch.tensor([[50258]], dtype=torch.int64),
)
new_features.logits.shape, new_features.logits.dtype
[55]:
(torch.Size([1, 1, 51865]), torch.float32)
[ ]:


Notebook on github