Transformers documentation
Classificação de áudio
Classificação de áudio
A classificação de áudio — assim como a de texto — atribui um rótulo de classe como saída a partir dos dados de entrada. A única diferença é que, em vez de entradas de texto, você tem formas de onda de áudio brutas. Algumas aplicações práticas da classificação de áudio incluem a identificação da intenção do falante, a classificação de idiomas e até mesmo a identificação de espécies de animais pelos seus sons.
Este guia mostrará como:
- Ajuste fino de Wav2Vec2 no conjunto de dados MInDS-14 para classificar a intenção do falante.
- Use seu modelo ajustado para inferência.
Para ver todas as arquiteturas e checkpoints compatíveis com esta tarefa, recomendamos consultar a página da tarefa
Antes de começar, verifique se você tem todas as bibliotecas necessárias instaladas:
pip install transformers datasets evaluate soundfile librosa torchcodec
Recomendamos que você faça login na sua conta do Hugging Face para que possa enviar e compartilhar seu modelo com a comunidade. Quando solicitado, insira seu token para fazer login:
>>> from huggingface_hub import notebook_login
>>> notebook_login()Carregar o conjunto de dados MInDS-14
Comece carregando o conjunto de dados MInDS-14 a partir da biblioteca 🤗 Datasets:
>>> from datasets import load_dataset, Audio
>>> minds = load_dataset("PolyAI/minds14", name="en-US", split="train")Divida o split train do conjunto de dados em um conjunto de treino menor e um conjunto de teste usando o método train_test_split. Isso lhe dará a oportunidade de experimentar e garantir que tudo funcione antes de gastar mais tempo no conjunto de dados completo.
>>> minds = minds.train_test_split(test_size=0.2)Em seguida, examine o conjunto de dados:
>>> 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
})
})Embora o conjunto de dados contenha muitas informações úteis, como lang_id e english_transcription, você se concentrará em audio e intent_class neste guia. Remova as outras colunas com o método remove_columns:
>>> minds = minds.remove_columns(["path", "transcription", "english_transcription", "lang_id"])Aqui está um exemplo:
>>> 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}Há dois campos:
audio: umarrayunidimensional do sinal de fala que deve ser chamado para carregar e reamostrar o arquivo de áudio.intent_class: representa o id da classe da intenção do falante.
Para facilitar que o modelo obtenha o nome do rótulo a partir do id do rótulo, crie um dicionário que mapeia o nome do rótulo para um inteiro e 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)] = labelAgora você pode converter o id do rótulo em um nome de rótulo:
>>> id2label[str(2)]
'app_error'Pré-processar
A próxima etapa é carregar um extrator de recursos Wav2Vec2 para processar o sinal de áudio:
>>> from transformers import AutoFeatureExtractor
>>> feature_extractor = AutoFeatureExtractor.from_pretrained("facebook/wav2vec2-base")O conjunto de dados MInDS-14 tem uma taxa de amostragem de 8 kHz (você pode encontrar essa informação em seu dataset card), o que significa que será necessário reamostrar o conjunto de dados para 16 kHz para usar o modelo Wav2Vec2 pré-treinado:
>>> 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}Agora, crie uma função de pré-processamento que:
- Chama a coluna
audiopara carregar e, se necessário, reamostra o arquivo de áudio. - Verifica se a taxa de amostragem do arquivo de áudio corresponde à taxa de amostragem dos dados de áudio com os quais o modelo foi pré-treinado. Você pode encontrar essas informações no model card do Wav2Vec2.
- Defina um comprimento máximo de entrada para agrupar entradas mais longas sem truncá-las.
>>> 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 inputsPara aplicar a função de pré-processamento em todo o conjunto de dados, use a função map do 🤗 Datasets. Você pode acelerar o map definindo batched=True para processar vários elementos do conjunto de dados de uma vez. Remova as colunas desnecessárias e renomeie intent_class para label, conforme exigido pelo modelo:
>>> encoded_minds = minds.map(preprocess_function, remove_columns="audio", batched=True)
>>> encoded_minds = encoded_minds.rename_column("intent_class", "label")Avaliar
Incluir uma métrica durante o treinamento é frequentemente útil para avaliar o desempenho do seu modelo. Você pode carregar rapidamente um método de avaliação com a biblioteca 🤗 Evaluate. Para esta tarefa, carregue a métrica accuracy (consulte o quick tour do 🤗 Evaluate para saber mais sobre como carregar e calcular uma métrica):
>>> import evaluate
>>> accuracy = evaluate.load("accuracy")Em seguida, crie uma função que passa suas previsões e rótulos para compute para calcular a precisão:
>>> 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)Sua função compute_metrics está pronta e você voltará a ela ao configurar o treinamento.
Treinar
Se você não está familiarizado com o ajuste fino de um modelo usando o Trainer, confira o tutorial básico aqui!
Agora você está pronto para começar o treinamento do seu modelo! Carregue o Wav2Vec2 com AutoModelForAudioClassification, juntamente com o número de rótulos esperados e os mapeamentos de rótulos:
>>> 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
... )Neste ponto, restam apenas três etapas:
- Defina os hiperparâmetros de treinamento em TrainingArguments. O único parâmetro obrigatório é
output_dir, que especifica onde salvar seu modelo. Você enviará este modelo para o Hub definindopush_to_hub=True(é necessário estar conectado ao Hugging Face para enviar seu modelo). No final de cada epoch, o Trainer avaliará a precisão e salvará o checkpoint de treinamento. - Passe os argumentos de treinamento para o Trainer junto com o modelo, o conjunto de dados, o tokenizer, o data collator e a função
compute_metrics. - Chame train() para fazer o ajuste fino do seu modelo.
>>> 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()Quando o treinamento for concluído, compartilhe seu modelo no Hub com o método push_to_hub() para que todos possam usá-lo:
>>> trainer.push_to_hub()Para um exemplo mais detalhado de como fazer o ajuste fino de um modelo para classificação de áudio, confira o notebook do PyTorch correspondente.
Inferência
Ótimo, agora que você ajustou um modelo, pode usá-lo para inferência!
Carregue um arquivo de áudio para inferência. Lembre-se de reamostrar a taxa de amostragem do arquivo de áudio para corresponder à taxa de amostragem do modelo, se necessário.
>>> 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"]A maneira mais simples de testar seu modelo ajustado para inferência é usá-lo em um pipeline(). Instancie um pipeline para classificação de áudio com seu modelo e passe seu arquivo de áudio para ele:
>>> 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'}
]Você também pode replicar manualmente os resultados do pipeline, se desejar:
Carregue um extrator de recursos para pré-processar o arquivo de áudio e retornar o input como tensores do 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")Passe suas entradas para o modelo e retorne os logits:
>>> from transformers import AutoModelForAudioClassification
>>> model = AutoModelForAudioClassification.from_pretrained("stevhliu/my_awesome_minds_model")
>>> with torch.no_grad():
... logits = model(**inputs).logitsObtenha a classe com a maior probabilidade e use o mapeamento id2label do modelo para convertê-la em um rótulo:
>>> import torch
>>> predicted_class_ids = torch.argmax(logits).item()
>>> predicted_label = model.config.id2label[predicted_class_ids]
>>> predicted_label
'cash_deposit'