Audio & Reconnaissance Vocale ML
“Des formes d'onde brutes aux caractéristiques MFCC — comment les machines écoutent et comprennent la parole”
Des formes d'ondes aux MFCC — STFT spectrogrammes, filterbanks Mel, CNN audio, perte CTC, SpecAugment et Whisper d'OpenAI.
Prérequis
Concepts Couverts
∑Formules Clés
Transformée de Fourier à Court Terme
Calculer le contenu fréquentiel dans une fenêtre glissante — produit le spectrogramme
Échelle Mel
Mappe la fréquence linéaire sur l'échelle perceptive — les humains entendent la hauteur de manière logarithmique, surtout aux hautes fréquences
MFCC
Transformée en Cosinus Discrète des énergies log du banc de filtres Mel — caractéristiques audio compactes et décorrélées
Perte CTC
Classification Temporelle Connexionniste — permet un entraînement sans alignement entre les trames d'entrée et les tokens de sortie
▶Simulation Interactive
Pourquoi le ML Audio Est Plus Difficile que le ML Image
L'audio présente des défis uniques : (1) Structure temporelle — le sens dépend de l'ordre et du timing, pas seulement du contenu (la parole est une séquence). (2) Longueur variable — un énoncé peut durer 0,1s ou 60s ; les images peuvent être rembourrées proprement, le rembourrage audio change le silence perçu. (3) Non-stationnarité — les propriétés statistiques changent au fil du temps (hauteur, vitesse, accent). (4) Variation non pertinente — même contenu prononcé plus vite, plus fort, avec un accent différent, un micro différent, du bruit de fond — tout doit produire la même sortie. (5) Pas de structure spatiale directe — contrairement aux images, les échantillons audio bruts sont des séries temporelles 1D à 16 000–44 100 Hz. La transformation spectrogramme convertit l'audio en une représentation 2D semblable à une image que les CNN peuvent traiter.
Siri, Google Assistant, Alexa et Whisper convertissent tous la parole en spectrogrammes (ou bancs de filtres Mel appris) avant d'appliquer les réseaux de neurones — les formes d'onde brutes ne sont presque jamais alimentées directement.
Le Pipeline de Traitement Audio
**Forme d'onde brute :** x(t) — une série temporelle 1D de valeurs de pression sonore échantillonnées à 16kHz (16 000 échantillons/seconde pour la parole). **Spectrogramme :** Appliquez la Transformée de Fourier à Court Terme (STFT) avec une fenêtre glissante (~25ms, pas ~10ms) → matrice du contenu fréquentiel au fil du temps. Régions brillantes = fréquences présentes à ce moment. **Spectrogramme Mel :** Appliquez un banc de filtres triangulaires (échelle Mel) pour réduire l'axe des fréquences à 80–128 canaux Mel — correspond à la perception auditive humaine. **MFCC :** Appliquez log + Transformée en Cosinus Discrète (DCT) pour décorrélr les énergies → 13–40 coefficients compacts par trame. Les MFCC étaient la référence pendant des décennies ; le Deep Learning moderne utilise directement les spectrogrammes log-mel comme entrée CNN.
Un clip d'1 seconde à 16kHz = 16 000 échantillons bruts. Après STFT avec fenêtres 25ms/pas 10ms = ~100 trames × 80 canaux Mel = 8 000 valeurs. Compression de 50% en conservant tout le contenu perceptif.
Pipeline de Reconnaissance Vocale (style Whisper)
Prétraitement : rééchantillonner à 16kHz, normaliser l'amplitude, rembourrer/couper à une longueur fixe.
Spectrogramme Log-Mel : appliquer STFT (fenêtre=25ms, pas=10ms, n_fft=400), appliquer 80 bancs de filtres Mel, prendre le log.
Encodeur : Conv 2D striée → encodeur Transformer avec embeddings positionnels absolus — encode le contexte audio.
Décodeur : décodeur Transformer autorégressif conditionné sur la sortie de l'encodeur. Entraîné avec le forçage enseignant sur les transcriptions.
Perte CTC ou entropie croisée entre la séquence de tokens prédite et la transcription de référence.
Inférence : la recherche en faisceau (largeur 5) décode la séquence de tokens la plus probable. Repondération optionnelle par modèle de langage.
Post-traitement : appliquer la restauration de la ponctuation, la normalisation inverse du texte (convertir '3 dollars' → '3 $').
Caractéristiques Audio avec librosa + OpenAI Whisper
import librosa import numpy as np import matplotlib.pyplot as plt class="tok-comment"># ── class="tok-num">1. Charger lclass="tok-str">'audio ──────────────────────────────────────────────────────── y_audio, taux_ech = librosa.load("parole.wav", sr=class="tok-num">16000) class="tok-comment"># rééchantillonner à 16kHz print(f"Durée : {len(y_audio)/taux_ech:.2f}s, Fréquence d'échantillonnage : {taux_ech}Hzclass="tok-str">") class="tok-comment"># ── class="tok-num">2. Forme d'onde vers spectrogramme ─────────────────────────────────────── D = librosa.stft(y_audio, n_fft=class="tok-num">400, hop_length=class="tok-num">160, win_length=class="tok-num">400) spectrogramme = np.abs(D)**class="tok-num">2 class="tok-comment"># spectrogramme de puissance (magnitude²) S_db = librosa.power_to_db(spectrogramme, ref=np.max) class="tok-comment"># échelle décibel class="tok-comment"># ── class="tok-num">3. Spectrogramme Mel ────────────────────────────────────────────────────── S_mel = librosa.feature.melspectrogram( y=y_audio, sr=taux_ech, n_fft=class="tok-num">400, hop_length=class="tok-num">160, class="tok-comment"># pas de 10ms à 16kHz win_length=class="tok-num">400, class="tok-comment"># fenêtre de 25ms à 16kHz n_mels=class="tok-num">80, class="tok-comment"># class="tok-num">80 canaux Mel (standard Whisper) fmin=class="tok-num">50, fmax=class="tok-num">8000, class="tok-comment"># filtrer entre 50Hz et 8kHz ) log_mel = librosa.power_to_db(S_mel, ref=np.max) print(f"Forme log-mel : {log_mel.shape}class="tok-str">") class="tok-comment"># (class="tok-num">80, T) class="tok-comment"># ── class="tok-num">4. MFCC ────────────────────────────────────────────────────────────────── mfcc = librosa.feature.mfcc(y=y_audio, sr=taux_ech, n_mfcc=class="tok-num">13, n_mels=class="tok-num">80) delta_mfcc = librosa.feature.delta(mfcc) class="tok-comment"># vélocité : variation temporelle delta2_mfcc = librosa.feature.delta(mfcc, order=class="tok-num">2) class="tok-comment"># accélération caracteristiques = np.vstack([mfcc, delta_mfcc, delta2_mfcc]) class="tok-comment"># vecteur class="tok-num">39-dim print(f"Forme MFCC + deltas : {caracteristiques.shape}class="tok-str">") class="tok-comment"># (class="tok-num">39, T) class="tok-comment"># ── class="tok-num">5. Classification audio avec CNN ───────────────────────────────────────── import torch, torch.nn as nn class CNNAudio(nn.Module): def __init__(self, n_classes: int): super().__init__() self.conv = nn.Sequential( nn.Conv2d(class="tok-num">1, class="tok-num">32, kernel_size=class="tok-num">3, padding=class="tok-num">1), nn.ReLU(), nn.MaxPool2d(class="tok-num">2), nn.Conv2d(class="tok-num">32, class="tok-num">64, kernel_size=class="tok-num">3, padding=class="tok-num">1), nn.ReLU(), nn.MaxPool2d(class="tok-num">2), nn.Conv2d(class="tok-num">64, class="tok-num">128, kernel_size=class="tok-num">3, padding=class="tok-num">1), nn.ReLU(), nn.AdaptiveAvgPool2d((class="tok-num">4, class="tok-num">4)), class="tok-comment"># pooling global moyen vers taille fixe ) self.fc = nn.Sequential( nn.Linear(class="tok-num">128*class="tok-num">4*class="tok-num">4, class="tok-num">256), nn.ReLU(), nn.Dropout(class="tok-num">0.4), nn.Linear(class="tok-num">256, n_classes), ) def forward(self, x): class="tok-comment"># x : (B, class="tok-num">1, n_mels, T) — log-mel comme 'image' mono-canal return self.fc(self.conv(x).flatten(class="tok-num">1)) modele_cnn = CNNAudio(n_classes=class="tok-num">10) class="tok-comment"># ex. UrbanSound8K : class="tok-num">10 classes sonores x = torch.randn(class="tok-num">8, class="tok-num">1, class="tok-num">80, class="tok-num">128) class="tok-comment"># lot de class="tok-num">8 clips, class="tok-num">80 mels, class="tok-num">128 trames print(modele_cnn(x).shape) class="tok-comment"># (class="tok-num">8, class="tok-num">10) class="tok-comment"># ── class="tok-num">6. OpenAI Whisper (parole vers texte) ──────────────────────────────────── class="tok-comment"># pip install openai-whisper import whisper modele_whisper = whisper.load_model("baseclass="tok-str">") class="tok-comment"># 74M paramètres resultat = modele_whisper.transcribe("parole.wavclass="tok-str">") print(resultat["textclass="tok-str">"]) class="tok-comment"># transcription complète print(resultat["languageclass="tok-str">"]) class="tok-comment"># langue détectée class="tok-comment"># Horodatages par mot res_ts = modele_whisper.transcribe("parole.wavclass="tok-str">", word_timestamps=True) for seg in res_ts["segmentsclass="tok-str">"]: print(f"[{seg[class="tok-str">'start']:.2f}s → {seg[class="tok-str">'end']:.2f}s] {seg[class="tok-str">'text']}")
L'Augmentation des Données Est Critique pour l'Audio
Les modèles audio surapprendraient facilement car un seul locuteur peut sonner complètement différent selon les conditions d'enregistrement. Augmentations clés : (1) **SpecAugment** (Google, 2019) — masquer aléatoirement des bandes de fréquences et des pas de temps dans le spectrogramme log-mel. Simple mais extrêmement efficace — utilisé dans Whisper. (2) **Étirement temporel** — changer le tempo sans changer la hauteur (librosa.effects.time_stretch). (3) **Décalage de hauteur** — changer la hauteur sans changer le tempo. (4) **Mélange de bruit de fond** — ajouter du bruit de foule, de la musique, de la circulation à différents niveaux SNR. (5) **Convolution de réponse impulsionnelle de salle (RIR)** — simuler différents environnements acoustiques. Sans augmentation, un modèle entraîné sur de la parole en studio échoue complètement sur des appels téléphoniques.
SpecAugment seul a amélioré le taux d'erreur de mots (WER) du modèle LAS de 13,9% relatif sur LibriSpeech — sans doute la meilleure technique d'augmentation unique dans l'histoire de la reconnaissance automatique de la parole.
?Vérification des Connaissances
La progression est sauvegardée dans votre navigateur — aucun compte requis.
Besoin d'un ingénieur IA ou data scientist ?
Je conçois des modèles ML sur mesure, des agents IA, de la vision par ordinateur et de l'automatisation — de l'idée à la production.