一、引言
pipeline(管道)是huggingface transformers库中一种极简方式使用大模型推理的抽象,将所有大模型分为音频(Audio)、计算机视觉(Computer vision)、自然语言处理(NLP)、多模态(Multimodal)等4大类,28小类任务(tasks)。共计覆盖32万个模型
今天介绍Audio音频的第四篇,零样本音频分类(zero-shot-audio-classification),在huggingface库内仅有4个音频分类模型。
二、零样本音频分类(zero-shot-audio-classification)
2.1 概述
零样本学习是AI识别方法之一。简单来说就是识别从未见过的数据类别,即训练的分类器不仅仅能够识别出训练集中已有的数据类别,还可以对于来自未见过的类别的数据进行区分。这是一个很有用的功能,使得计算机能够具有知识迁移的能力,并无需任何训练数据,很符合现实生活中海量类别的存在形式。。
2.2 意义
在传统AI识别任务中,训练阶段和测试阶段的类别是相同的,但每次为了识别新类别的样本需要在训练集中加入这种类别的数据。一些类别的样本收集代价大,即使收集到足够的训练样本,也需要对整个模型进行重新训练。这都会加大识别系统的成本,零样本学习方法便能很好的解决这个问题。
2.3 应用场景
- 未知物体识别——例如,模型在“马”、“牛”等类别上训练过,因此模型能够准确地识别“马”、“牛”的图片。当模型遇到“象”这个新类别,由于从未见过,模型无法作出判断。传统解决方案是收集大量“象”的图片,与原数据集一起重新训练。这种解决方案的代价高、速度慢。然而,人类能够从描述性知识中快速学习一个新概念。例如,一个儿童即使没有见过“象”,当提供他文本描述“象是一种的大型食草类动物,有长鼻和长牙”。儿童能够根据描述快速学会“象”这一新类别,并能在第一次见到“象”时识别出来。零样本学习与之类似,在没有任何训练样本的情况下,借助辅助知识(如属性、词向量、文本描述等)学习一些从未见过的新概念(类别)。
- 未知语言翻译——比如说要进行三种语言之间的翻译,按照传统的方法需要分别训练六个网络,在日语和韩语之间没有那么多样本的情况下,训练英语→特征空间→日语,韩语→特征空间→英语这两个网络,那么就可以自动学会韩语→特征空间→日语这个翻译过程。
- 未知类别图像合成——近年来,对抗网络GAN被用于图像合成,取得了以假乱真的效果。但传统图像合成仅能合成见过的类别的图像。零样本图像合成希望模型能够合成从未见过的类别的图像。已有一些算法通过条件GAN网络实现了零样本图像合成。
- 图像哈希——传统利用一些训练样本来学习针对某些类别的哈希算法。但这些学习到的哈希算法无法用于新类别。零样本图像哈希,希望在已知类别上学到哈希算法能够运用到新的未知类别上。一些基于属性的零样本哈希算法已经被提出。
2.4 pipeline参数
2.4.1 pipeline对象实例化参数
- model(PreTrainedModel或TFPreTrainedModel)— 管道将使用其进行预测的模型。 对于 PyTorch,这需要从PreTrainedModel继承;对于 TensorFlow,这需要从TFPreTrainedModel继承。
- tokenizer ( PreTrainedTokenizer ) — 管道将使用 tokenizer 来为模型编码数据。此对象继承自 PreTrainedTokenizer。
- feature_extractor ( SequenceFeatureExtractor ) — 管道将使用的特征提取器来为模型编码数据。此对象继承自 SequenceFeatureExtractor。
- modelcard(
str
或ModelCard
,可选)— 属于此管道模型的模型卡。 - framework(
str
,可选)— 要使用的框架,"pt"
适用于 PyTorch 或"tf"
TensorFlow。必须安装指定的框架。 - task (
str
,默认为""
)— 管道的任务标识符。 - num_workers(
int
,可选,默认为 8)— 当管道将使用DataLoader(传递数据集时,在 Pytorch 模型的 GPU 上)时,要使用的工作者数量。 - batch_size(
int
,可选,默认为 1)— 当管道将使用DataLoader(传递数据集时,在 Pytorch 模型的 GPU 上)时,要使用的批次的大小,对于推理来说,这并不总是有益的,请阅读使用管道进行批处理。 - args_parser(ArgumentHandler,可选) - 引用负责解析提供的管道参数的对象。
- device(
int
,可选,默认为 -1)— CPU/GPU 支持的设备序号。将其设置为 -1 将利用 CPU,设置为正数将在关联的 CUDA 设备 ID 上运行模型。您可以传递本机torch.device
或str
太 - torch_dtype(
str
或torch.dtype
,可选) - 直接发送model_kwargs
(只是一种更简单的快捷方式)以使用此模型的可用精度(torch.float16
,,torch.bfloat16
...或"auto"
) - binary_output(
bool
,可选,默认为False
)——标志指示管道的输出是否应以序列化格式(即 pickle)或原始输出数据(例如文本)进行。
2.4.2 pipeline对象使用参数
- audio(
str
、List[str]
或np.array
)List[np.array]
——管道处理三种类型的输入:- 包含指向音频的 http 链接的字符串
- 包含音频本地路径的字符串
- 在 numpy 中加载的音频
- candidates_labels (
List[str]
) — 该音频的候选标签 - hypothesis_template(
str
,可选,默认为) — 与候选标签"This is a sound of {}"
结合使用的句子,通过用候选标签替换占位符来尝试音频分类。然后使用 logits_per_audio 估计可能性
2.4 pipeline实战
首先下载数据集,我们采用ashraq/esc50语音数据集,其中包含2000条语音分类样本。
将数据集加载后,采用task="zero-shot-audio-classification"默认的模型laion/clap-htsat-fused进行零样本语音分类:
代码语言:javascript复制import os
os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"
os.environ["CUDA_VISIBLE_DEVICES"] = "2"
from transformers import pipeline
from datasets import load_dataset
dataset = load_dataset("ashraq/esc50")
#{'filename': '1-100210-B-36.wav', 'fold': 1, 'target': 36, 'category': 'vacuum_cleaner', 'esc10': False, 'src_file': 100210, 'take': 'B', 'audio': {'path': None, 'array': array([0.53897095, 0.39627075, 0.26739502, ..., 0.09729004, 0.11227417,0.07983398]), 'sampling_rate': 44100}}
#pipe = pipeline(task="audio-classification",model="ehcalabres/wav2vec2-lg-xlsr-en-speech-emotion-recognition")
audio = dataset["train"][1]["audio"]["array"]
classifier = pipeline(task="zero-shot-audio-classification")
result = classifier(audio, candidate_labels=["Sound of a dog", "Sound of vaccum cleaner","chirping_birds"])
print(result)
数据集中的第二行为chirping_birds,代码调用结果为
代码语言:javascript复制[{'score': 0.9998486042022705, 'label': 'chirping_birds'}, {'score': 7.838715828256682e-05, 'label': 'Sound of vaccum cleaner'}, {'score': 7.297335105249658e-05, 'label': 'Sound of a dog'}]
2.5 模型排名
在huggingface上,我们筛选零样本音频分类模型,并按下载量从高到低排序,基本没什么人用。。。
三、总结
本文对transformers之pipeline的零样本音频分类(zero-shot-audio-classification)从概述、技术原理、pipeline参数、pipeline实战、模型排名等方面进行介绍,读者可以基于pipeline使用文中的代码极简的进行零样本音频分类推理,模型目前比较冷门,但介于pipeline设计了这个task,为了完整性,还是写了这一篇。