音频
音频分类
原始文本:
huggingface.co/docs/transformers/v4.37.2/en/tasks/audio_classification
www.youtube-nocookie.com/embed/KWwzcmG98Ds
音频分类 - 就像文本一样 - 从输入数据中分配一个类标签输出。唯一的区别是,您有原始音频波形而不是文本输入。音频分类的一些实际应用包括识别说话者意图、语言分类,甚至通过声音识别动物物种。
本指南将向您展示如何:
本教程中所示的任务由以下模型架构支持:
音频频谱变换器、Data2VecAudio、Hubert、SEW、SEW-D、UniSpeech、UniSpeechSat、Wav2Vec2、Wav2Vec2-BERT、Wav2Vec2-Conformer、WavLM、Whisper
在开始之前,请确保已安装所有必要的库:
pip install transformers datasets evaluate
我们鼓励您登录您的 Hugging Face 帐户,这样您就可以上传和分享您的模型给社区。在提示时,输入您的令牌以登录:
>>> from huggingface_hub import notebook_login >>> notebook_login()
加载 MInDS-14 数据集
首先从🤗数据集库中加载 MInDS-14 数据集:
>>> from datasets import load_dataset, Audio >>> minds = load_dataset("PolyAI/minds14", name="en-US", split="train")
使用train_test_split方法将数据集的train
拆分为较小的训练集和测试集。这将让您有机会进行实验,并确保一切正常,然后再花更多时间处理完整数据集。
>>> minds = minds.train_test_split(test_size=0.2)
然后查看数据集:
>>> 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 }) })
虽然数据集包含许多有用信息,比如lang_id
和english_transcription
,但在本指南中,您将专注于audio
和intent_class
。使用remove_columns方法删除其他列:
>>> minds = minds.remove_columns(["path", "transcription", "english_transcription", "lang_id"])
现在看一个示例:
>>> 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}
有两个领域:
audio
:必须调用的语音信号的一维array
,以加载和重新采样音频文件。intent_class
:表示说话者意图的类别 ID。
为了让模型更容易从标签 ID 中获取标签名称,创建一个将标签名称映射到整数以及反之的字典:
>>> labels = minds["train"].features["intent_class"].names >>> label2id, id2label = dict(), dict() >>> for i, label in enumerate(labels): ... label2id[label] = str(i) ... id2label[str(i)] = label
现在您可以将标签 ID 转换为标签名称:
>>> id2label[str(2)] 'app_error'
预处理
下一步是加载 Wav2Vec2 特征提取器来处理音频信号:
>>> from transformers import AutoFeatureExtractor >>> feature_extractor = AutoFeatureExtractor.from_pretrained("facebook/wav2vec2-base")
MInDS-14 数据集的采样率为 8000khz(您可以在其数据集卡片中找到此信息),这意味着您需要将数据集重新采样为 16000kHz 以使用预训练的 Wav2Vec2 模型:
>>> 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}
现在创建一个预处理函数,该函数:
- 调用
audio
列进行加载,并在必要时重新采样音频文件。 - 检查音频文件的采样率是否与模型预训练时的音频数据的采样率匹配。您可以在 Wav2Vec2 的模型卡片中找到此信息。
- 设置最大输入长度以批处理更长的输入而不截断它们。
>>> 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 inputs
要在整个数据集上应用预处理函数,请使用🤗 Datasets map函数。您可以通过设置batched=True
来加速map
,以一次处理数据集的多个元素。删除您不需要的列,并将intent_class
重命名为label
,因为这是模型期望的名称:
>>> encoded_minds = minds.map(preprocess_function, remove_columns="audio", batched=True) >>> encoded_minds = encoded_minds.rename_column("intent_class", "label")
评估
在训练过程中包含一个度量通常有助于评估模型的性能。您可以通过🤗 Evaluate库快速加载一个评估方法。对于这个任务,加载accuracy度量(查看🤗 Evaluate quick tour以了解如何加载和计算度量):
>>> import evaluate >>> accuracy = evaluate.load("accuracy")
然后创建一个函数,将您的预测和标签传递给compute
以计算准确性:
>>> 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)
您的compute_metrics
函数现在已经准备就绪,当您设置训练时将返回到它。
训练
Pytorch 隐藏 Pytorch 内容
如果您不熟悉使用 Trainer 微调模型,请查看这里的基本教程[…/training#train-with-pytorch-trainer]!
现在您已经准备好开始训练您的模型了!使用 AutoModelForAudioClassification 加载 Wav2Vec2,以及预期标签的数量和标签映射:
>>> 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 ... )
此时,只剩下三个步骤:
- 在 TrainingArguments 中定义您的训练超参数。唯一必需的参数是
output_dir
,指定保存模型的位置。通过设置push_to_hub=True
将此模型推送到 Hub(您需要登录 Hugging Face 才能上传模型)。在每个时代结束时,Trainer 将评估准确性并保存训练检查点。 - 将训练参数传递给 Trainer,以及模型、数据集、分词器、数据整理器和
compute_metrics
函数。 - 调用 train()来微调您的模型。
>>> training_args = TrainingArguments( ... output_dir="my_awesome_mind_model", ... evaluation_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_ratio=0.1, ... logging_steps=10, ... load_best_model_at_end=True, ... metric_for_best_model="accuracy", ... push_to_hub=True, ... ) >>> trainer = Trainer( ... model=model, ... args=training_args, ... train_dataset=encoded_minds["train"], ... eval_dataset=encoded_minds["test"], ... tokenizer=feature_extractor, ... compute_metrics=compute_metrics, ... ) >>> trainer.train()
训练完成后,使用 push_to_hub()方法将您的模型共享到 Hub,这样每个人都可以使用您的模型:
>>> trainer.push_to_hub()
要了解如何为音频分类微调模型的更深入示例,请查看相应的PyTorch 笔记本。
推理
现在,您已经微调了一个模型,可以用它进行推理了!
加载您想要进行推理的音频文件。记得重新采样音频文件的采样率,以匹配模型的采样率(如果需要)!
>>> 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"]
尝试使用一个 pipeline()来进行推理的最简单方法是在其中使用微调后的模型。使用您的模型实例化一个用于音频分类的pipeline
,并将音频文件传递给它:
>>> 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'} ]
如果您愿意,也可以手动复制pipeline
的结果:
Pytorch 隐藏 Pytorch 内容
加载一个特征提取器来预处理音频文件,并将input
返回为 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")
将您的输入传递给模型并返回 logits:
>>> from transformers import AutoModelForAudioClassification >>> model = AutoModelForAudioClassification.from_pretrained("stevhliu/my_awesome_minds_model") >>> with torch.no_grad(): ... logits = model(**inputs).logits
获取具有最高概率的类,并使用模型的id2label
映射将其转换为标签:
>>> import torch >>> predicted_class_ids = torch.argmax(logits).item() >>> predicted_label = model.config.id2label[predicted_class_ids] >>> predicted_label 'cash_deposit'
自动语音识别
www.youtube-nocookie.com/embed/TksaY_FDgnk
自动语音识别(ASR)将语音信号转换为文本,将一系列音频输入映射到文本输出。虚拟助手如 Siri 和 Alexa 使用 ASR 模型帮助用户日常,还有许多其他有用的用户界面应用,如实时字幕和会议记录。
本指南将向您展示如何:
本教程中演示的任务由以下模型架构支持:
Data2VecAudio, Hubert, M-CTC-T, SEW, SEW-D, UniSpeech, UniSpeechSat, Wav2Vec2, Wav2Vec2-BERT, Wav2Vec2-Conformer, WavLM
在开始之前,请确保已安装所有必要的库:
pip install transformers datasets evaluate jiwer
我们鼓励您登录您的 Hugging Face 账户,这样您就可以上传和与社区分享您的模型。在提示时,输入您的令牌以登录:
>>> from huggingface_hub import notebook_login >>> notebook_login()
加载 MInDS-14 数据集
首先加载来自🤗数据集库的MInDS-14数据集的较小子集。这将让您有机会进行实验,并确保一切正常,然后再花更多时间在完整数据集上进行训练。
>>> from datasets import load_dataset, Audio >>> minds = load_dataset("PolyAI/minds14", name="en-US", split="train[:100]")
使用~Dataset.train_test_split
方法将数据集的train
拆分为训练集和测试集:
>>> minds = minds.train_test_split(test_size=0.2)
然后查看数据集:
>>> minds DatasetDict({ train: Dataset({ features: ['path', 'audio', 'transcription', 'english_transcription', 'intent_class', 'lang_id'], num_rows: 16 }) test: Dataset({ features: ['path', 'audio', 'transcription', 'english_transcription', 'intent_class', 'lang_id'], num_rows: 4 }) })
虽然数据集包含许多有用信息,如lang_id
和english_transcription
,但在本指南中,您将专注于audio
和transcription
。使用remove_columns方法删除其他列:
>>> minds = minds.remove_columns(["english_transcription", "intent_class", "lang_id"])
再次查看示例:
>>> minds["train"][0] {'audio': {'array': array([-0.00024414, 0. , 0. , ..., 0.00024414, 0.00024414, 0.00024414], dtype=float32), 'path': '/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-US~APP_ERROR/602ba9e2963e11ccd901cd4f.wav', 'sampling_rate': 8000}, 'path': '/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-US~APP_ERROR/602ba9e2963e11ccd901cd4f.wav', 'transcription': "hi I'm trying to use the banking app on my phone and currently my checking and savings account balance is not refreshing"}
有两个字段:
audio
:必须调用的语音信号的一维array
,用于加载和重采样音频文件。transcription
:目标文本。
预处理
接下来的步骤是加载一个 Wav2Vec2 处理器来处理音频信号:
>>> from transformers import AutoProcessor >>> processor = AutoProcessor.from_pretrained("facebook/wav2vec2-base")
MInDS-14 数据集的采样率为 8000kHz(您可以在其数据集卡片中找到此信息),这意味着您需要将数据集重采样为 16000kHz 以使用预训练的 Wav2Vec2 模型:
>>> minds = minds.cast_column("audio", Audio(sampling_rate=16_000)) >>> minds["train"][0] {'audio': {'array': array([-2.38064706e-04, -1.58618059e-04, -5.43987835e-06, ..., 2.78103951e-04, 2.38446111e-04, 1.18740834e-04], dtype=float32), 'path': '/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-US~APP_ERROR/602ba9e2963e11ccd901cd4f.wav', 'sampling_rate': 16000}, 'path': '/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-US~APP_ERROR/602ba9e2963e11ccd901cd4f.wav', 'transcription': "hi I'm trying to use the banking app on my phone and currently my checking and savings account balance is not refreshing"}
如上所示的transcription
,文本包含大小写混合的字符。Wav2Vec2 分词器只训练大写字符,所以您需要确保文本与分词器的词汇匹配:
>>> def uppercase(example): ... return {"transcription": example["transcription"].upper()} >>> minds = minds.map(uppercase)
现在创建一个预处理函数,它:
- 调用
audio
列加载和重采样音频文件。 - 从音频文件中提取
input_values
并使用处理器对transcription
列进行标记。
>>> def prepare_dataset(batch): ... audio = batch["audio"] ... batch = processor(audio["array"], sampling_rate=audio["sampling_rate"], text=batch["transcription"]) ... batch["input_length"] = len(batch["input_values"][0]) ... return batch
要在整个数据集上应用预处理函数,使用🤗数据集map函数。您可以通过增加num_proc
参数来加快map
的速度。使用remove_columns方法删除不需要的列:
>>> encoded_minds = minds.map(prepare_dataset, remove_columns=minds.column_names["train"], num_proc=4)
🤗 Transformers 没有用于 ASR 的数据整理器,因此您需要调整 DataCollatorWithPadding 以创建一批示例。它还会动态填充您的文本和标签到其批次中最长元素的长度(而不是整个数据集),以使它们具有统一的长度。虽然可以通过在tokenizer
函数中设置padding=True
来填充文本,但动态填充更有效。
与其他数据整理器不同,这个特定的数据整理器需要对input_values
和labels
应用不同的填充方法:
>>> import torch >>> from dataclasses import dataclass, field >>> from typing import Any, Dict, List, Optional, Union >>> @dataclass ... class DataCollatorCTCWithPadding: ... processor: AutoProcessor ... padding: Union[bool, str] = "longest" ... def __call__(self, features: List[Dict[str, Union[List[int], torch.Tensor]]]) -> Dict[str, torch.Tensor]: ... # split inputs and labels since they have to be of different lengths and need ... # different padding methods ... input_features = [{"input_values": feature["input_values"][0]} for feature in features] ... label_features = [{"input_ids": feature["labels"]} for feature in features] ... batch = self.processor.pad(input_features, padding=self.padding, return_tensors="pt") ... labels_batch = self.processor.pad(labels=label_features, padding=self.padding, return_tensors="pt") ... # replace padding with -100 to ignore loss correctly ... labels = labels_batch["input_ids"].masked_fill(labels_batch.attention_mask.ne(1), -100) ... batch["labels"] = labels ... return batch
现在实例化您的DataCollatorForCTCWithPadding
:
>>> data_collator = DataCollatorCTCWithPadding(processor=processor, padding="longest")
评估
在训练过程中包含一个指标通常有助于评估模型的性能。您可以使用🤗 Evaluate库快速加载一个评估方法。对于这个任务,加载word error rate (WER)指标(查看🤗 Evaluate 快速入门以了解如何加载和计算指标):
>>> import evaluate >>> wer = evaluate.load("wer")
然后创建一个函数,将您的预测和标签传递给compute
以计算 WER:
>>> import numpy as np >>> def compute_metrics(pred): ... pred_logits = pred.predictions ... pred_ids = np.argmax(pred_logits, axis=-1) ... pred.label_ids[pred.label_ids == -100] = processor.tokenizer.pad_token_id ... pred_str = processor.batch_decode(pred_ids) ... label_str = processor.batch_decode(pred.label_ids, group_tokens=False) ... wer = wer.compute(predictions=pred_str, references=label_str) ... return {"wer": wer}
您的compute_metrics
函数已经准备就绪,当您设置训练时会返回到它。
训练
PytorchHide Pytorch 内容
如果您不熟悉使用 Trainer 微调模型,请查看这里的基本教程[training#train-with-pytorch-trainer]!
现在您已经准备好开始训练您的模型了!使用 AutoModelForCTC 加载 Wav2Vec2。指定要应用的减少量,使用ctc_loss_reduction
参数。通常最好使用平均值而不是默认的求和:
>>> from transformers import AutoModelForCTC, TrainingArguments, Trainer >>> model = AutoModelForCTC.from_pretrained( ... "facebook/wav2vec2-base", ... ctc_loss_reduction="mean", ... pad_token_id=processor.tokenizer.pad_token_id, ... )
此时,只剩下三个步骤:
- 在 TrainingArguments 中定义您的训练超参数。唯一必需的参数是
output_dir
,指定保存模型的位置。通过设置push_to_hub=True
将此模型推送到 Hub(您需要登录 Hugging Face 才能上传模型)。在每个时代结束时,Trainer 将评估 WER 并保存训练检查点。 - 将训练参数传递给 Trainer,同时还需要传递模型、数据集、分词器、数据整理器和
compute_metrics
函数。 - 调用 train()来微调您的模型。
>>> training_args = TrainingArguments( ... output_dir="my_awesome_asr_mind_model", ... per_device_train_batch_size=8, ... gradient_accumulation_steps=2, ... learning_rate=1e-5, ... warmup_steps=500, ... max_steps=2000, ... gradient_checkpointing=True, ... fp16=True, ... group_by_length=True, ... evaluation_strategy="steps", ... per_device_eval_batch_size=8, ... save_steps=1000, ... eval_steps=1000, ... logging_steps=25, ... load_best_model_at_end=True, ... metric_for_best_model="wer", ... greater_is_better=False, ... push_to_hub=True, ... ) >>> trainer = Trainer( ... model=model, ... args=training_args, ... train_dataset=encoded_minds["train"], ... eval_dataset=encoded_minds["test"], ... tokenizer=processor, ... data_collator=data_collator, ... compute_metrics=compute_metrics, ... ) >>> trainer.train()
训练完成后,使用 push_to_hub()方法将您的模型共享到 Hub,以便每个人都可以使用您的模型:
>>> trainer.push_to_hub()
要了解如何为自动语音识别微调模型的更深入示例,请查看这篇博客post以获取英语 ASR,以及这篇post以获取多语言 ASR。
Transformers 4.37 中文文档(四)(2)https://developer.aliyun.com/article/1564977