Transformers documentation
Classification audio
Classification audio
La classification audio – tout comme pour le texte – attribue une étiquette de classe en sortie à partir des données d'entrée. La seule différence est qu'au lieu d'entrées textuelles, vous disposez de formes d'onde audio brutes. Parmi les applications pratiques de la classification audio, on trouve l'identification de l'intention du locuteur, la classification de la langue, et même l'identification des espèces animales par leurs sons.
Ce guide vous montre comment :
- Effectuer l'ajustement fin de Wav2Vec2 sur le jeu de données MInDS-14 pour classifier l'intention de l'orateur.
- Utilisez votre modèle affiné pour l'inférence.
Pour consulter toutes les architectures et points de contrôle compatibles avec cette tâche, nous vous recommandons de consulter la page de la tâche
Avant de commencer, assurez-vous d'avoir installé toutes les bibliothèques nécessaires :
pip install transformers datasets evaluate soundfile librosa torchcodec
Nous vous encourage à vous connecter à votre compte Hugging Face afin de pouvoir téléverser et partager votre modèle avec la communauté. Lorsque cela vous est demandé, saisissez votre jeton pour vous connecter :
>>> from huggingface_hub import notebook_login
>>> notebook_login()Charger le jeu de données MInDS-14
Commencez par charger le jeu de données MInDS-14 à partir de la bibliothèque 🤗 Datasets :
>>> from datasets import load_dataset, Audio
>>> minds = load_dataset("PolyAI/minds14", name="en-US", split="train")Divisez la partie train du jeu de données en un ensemble d’entraînement plus petit et un ensemble de test à l’aide de la méthode train_test_split. Cela vous permettra de faire des essais et de vous assurer que tout fonctionne correctement avant de consacrer plus de temps au jeu de données complet.
>>> minds = minds.train_test_split(test_size=0.2)Puis, examinez le jeu de données :
>>> minds
DatasetDict({
train: Dataset({
features: ['path', 'audio', 'transcription', 'english_transcription', 'intent_class', 'lang_id'],
num_rows: 450
})
test: Dataset({
features: ['path', 'audio', 'transcription', 'english_transcription', 'intent_class', 'lang_id'],
num_rows: 113
})
})Bien que le jeu de données contienne de nombreuses informations utiles, comme lang_id et english_transcription, vous vous concentrerez sur audio et intent_class dans ce guide. Supprimez les autres colonnes à l’aide de la méthode remove_columns :
>>> minds = minds.remove_columns(["path", "transcription", "english_transcription", "lang_id"])Voici un exemple :
>>> minds["train"][0]
{'audio': {'array': array([ 0. , 0. , 0. , ..., -0.00048828,
-0.00024414, -0.00024414], dtype=float32),
'path': '/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-US~APP_ERROR/602b9a5fbb1e6d0fbce91f52.wav',
'sampling_rate': 8000},
'intent_class': 2}Il y a deux champs :
audio: unarrayunidimensionnel du signal vocal qui doit être appelé pour charger et rééchantillonner le fichier audio.intent_class: représente l’identifiant de classe de l’intention de l’orateur.
Pour faciliter la récupération du nom de l'étiquette à partir de l'identifiant de l'étiquette par le modèle, créez un dictionnaire qui associe le nom de l'étiquette à un entier et vice versa :
>>> labels = minds["train"].features["intent_class"].names
>>> label2id, id2label = dict(), dict()
>>> for i, label in enumerate(labels):
... label2id[label] = str(i)
... id2label[str(i)] = labelVous pouvez maintenant convertir l'identifiant de la classe en nom de classe :
>>> id2label[str(2)]
'app_error'Prétraitement
L'étape suivante consiste à charger un extracteur de caractéristiques Wav2Vec2 pour traiter le signal audio :
>>> from transformers import AutoFeatureExtractor
>>> feature_extractor = AutoFeatureExtractor.from_pretrained("facebook/wav2vec2-base")Le jeu de données MInDS-14 a un taux d’échantillonnage de 8 kHz (vous pouvez trouver cette information dans sa fiche de jeu de données), ce qui signifie qu’il faudra rééchantillonner le jeu de données à 16 kHz pour utiliser le modèle Wav2Vec2 préentraîné :
>>> minds = minds.cast_column("audio", Audio(sampling_rate=16_000))
>>> minds["train"][0]
{'audio': {'array': array([ 2.2098757e-05, 4.6582241e-05, -2.2803260e-05, ...,
-2.8419291e-04, -2.3305941e-04, -1.1425107e-04], dtype=float32),
'path': '/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-US~APP_ERROR/602b9a5fbb1e6d0fbce91f52.wav',
'sampling_rate': 16000},
'intent_class': 2}Créez maintenant une fonction de prétraitement qui :
- Appelle la colonne
audioà charger et, le cas échéant, rééchantillonne le fichier audio. - Vérifie si la fréquence d'échantillonnage du fichier audio correspond à la fréquence d'échantillonnage des données audio utilisées pour la pré-entraînement du modèle. Vous pouvez trouver ces informations dans la fiche modèle de Wav2Vec2.
- Définissez une longueur d'entrée maximale pour regrouper des entrées plus longues sans les tronquer.
>>> def preprocess_function(examples):
... audio_arrays = [x["array"] for x in examples["audio"]]
... inputs = feature_extractor(
... audio_arrays, sampling_rate=feature_extractor.sampling_rate, max_length=16000, truncation=True
... )
... return inputsPour appliquer la fonction de prétraitement à l’ensemble du jeu de données, utilisez la fonction map de 🤗 Datasets. Vous pouvez accélérer map en définissant batched=True afin de traiter plusieurs éléments du jeu de données à la fois. Supprimez les colonnes inutiles et renommez intent_class en label, comme l’exige le modèle :
>>> encoded_minds = minds.map(preprocess_function, remove_columns="audio", batched=True)
>>> encoded_minds = encoded_minds.rename_column("intent_class", "label")Évaluer
Inclure une métrique pendant l’entraînement est souvent utile pour évaluer les performances de votre modèle. Vous pouvez charger rapidement une méthode d’évaluation avec la bibliothèque 🤗 Evaluate. Pour cette tâche, chargez la métrique accuracy (consultez le quick tour de 🤗 Evaluate pour en savoir plus sur la façon de charger et de calculer une métrique) :
>>> import evaluate
>>> accuracy = evaluate.load("accuracy")Créez ensuite une fonction qui transmet vos prédictions et vos étiquettes à compute pour calculer la précision :
>>> import numpy as np
>>> def compute_metrics(eval_pred):
... predictions = np.argmax(eval_pred.predictions, axis=1)
... return accuracy.compute(predictions=predictions, references=eval_pred.label_ids)Votre fonction compute_metrics est prête, et vous y reviendrez lors de la configuration de l’entraînement.
Entraînement
Si vous n’êtes pas familier avec l’ajustement fin d’un modèle à l’aide du Trainer, consultez le tutoriel de base ici !
Vous êtes prêt à commencer l’entraînement de votre modèle ! Chargez Wav2Vec2 avec AutoModelForAudioClassification, en précisant le nombre de labels attendus ainsi que les correspondances de labels :
>>> from transformers import AutoModelForAudioClassification, TrainingArguments, Trainer
>>> num_labels = len(id2label)
>>> model = AutoModelForAudioClassification.from_pretrained(
... "facebook/wav2vec2-base", num_labels=num_labels, label2id=label2id, id2label=id2label
... )À ce stade, il ne reste que trois étapes :
- Définissez vos hyperparamètres d’entraînement dans TrainingArguments. Le seul paramètre obligatoire est
output_dir, qui spécifie l’endroit où enregistrer votre modèle. Vous pousserez ce modèle sur le Hub en définissantpush_to_hub=True(vous devez être connecté à Hugging Face pour téléverser votre modèle). À la fin de chaque époque, le Trainer évaluera la précision et enregistrera le point de contrôle d’entraînement. - Transmettez les arguments d’entraînement à Trainer en même temps que le modèle, le jeu de données, le tokenizer, le data collator et la fonction
compute_metrics. - Appel de train() pour l’ajustement fin de votre modèle.
>>> training_args = TrainingArguments(
... output_dir="my_awesome_mind_model",
... eval_strategy="epoch",
... save_strategy="epoch",
... learning_rate=3e-5,
... per_device_train_batch_size=32,
... gradient_accumulation_steps=4,
... per_device_eval_batch_size=32,
... num_train_epochs=10,
... warmup_steps=0.1,
... logging_steps=10,
... load_best_model_at_end=True,
... metric_for_best_model="accuracy",
... push_to_hub=True,
... report_to="trackio",
... )
>>> trainer = Trainer(
... model=model,
... args=training_args,
... train_dataset=encoded_minds["train"],
... eval_dataset=encoded_minds["test"],
... processing_class=feature_extractor,
... compute_metrics=compute_metrics,
... )
>>> trainer.train()Une fois l’entraînement terminé, partagez votre modèle sur le Hub à l’aide de la méthode push_to_hub() afin que chacun puisse l’utiliser :
>>> trainer.push_to_hub()Pour un exemple plus approfondi sur la façon d’affiner un modèle pour la classification audio, consultez le notebook PyTorch correspondant.
Inférence
Parfait, maintenant que vous avez affiné un modèle, vous pouvez l'utiliser pour l'inférence !
Chargez un fichier audio pour l’inférence. N’oubliez pas de rééchantillonner le taux d’échantillonnage du fichier audio pour qu’il corresponde au taux d’échantillonnage du modèle, si nécessaire.
>>> from datasets import load_dataset, Audio
>>> dataset = load_dataset("PolyAI/minds14", name="en-US", split="train")
>>> dataset = dataset.cast_column("audio", Audio(sampling_rate=16000))
>>> sampling_rate = dataset.features["audio"].sampling_rate
>>> audio_file = dataset[0]["audio"]["path"]La manière la plus simple de tester votre modèle affiné pour l'inférence est de l'utiliser dans un pipeline(). Instanciez un pipeline pour la classification audio avec votre modèle, puis passez-lui votre fichier audio :
>>> from transformers import pipeline
>>> classifier = pipeline("audio-classification", model="stevhliu/my_awesome_minds_model")
>>> classifier(audio_file)
[
{'score': 0.09766869246959686, 'label': 'cash_deposit'},
{'score': 0.07998877018690109, 'label': 'app_error'},
{'score': 0.0781070664525032, 'label': 'joint_account'},
{'score': 0.07667109370231628, 'label': 'pay_bill'},
{'score': 0.0755252093076706, 'label': 'balance'}
]Vous pouvez également reproduire manuellement les résultats de pipeline si vous le souhaitez :
Chargez un extracteur de caractéristiques pour prétraiter le fichier audio et renvoyer l'input sous forme de tenseurs PyTorch :
>>> from transformers import AutoFeatureExtractor
>>> feature_extractor = AutoFeatureExtractor.from_pretrained("stevhliu/my_awesome_minds_model")
>>> inputs = feature_extractor(dataset[0]["audio"]["array"], sampling_rate=sampling_rate, return_tensors="pt")Passez vos entrées au modèle et renvoyez les logits :
>>> from transformers import AutoModelForAudioClassification
>>> model = AutoModelForAudioClassification.from_pretrained("stevhliu/my_awesome_minds_model")
>>> with torch.no_grad():
... logits = model(**inputs).logitsObtenez la classe ayant la probabilité la plus élevée, puis utilisez le mapping id2label du modèle pour la convertir en étiquette :
>>> import torch
>>> predicted_class_ids = torch.argmax(logits).item()
>>> predicted_label = model.config.id2label[predicted_class_ids]
>>> predicted_label
'cash_deposit'