ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

PaddleSpeech 中的 PANNs 音频分类模型:panns 模块架构解析与训练部署实战

PaddleSpeech 中的 PANNs 音频分类模型:panns 模块架构解析与训练部署实战 PaddleSpeech 中的 PANNs 音频分类模型panns 模块架构解析与训练部署实战【免费下载链接】PaddleSpeechEasy-to-use Speech Toolkit including Self-Supervised Learning model, SOTA/Streaming ASR with punctuation, Streaming TTS with text frontend, Speaker Verification System, End-to-End Speech Translation and Keyword Spotting. Won NAACL2022 Best Demo Award.项目地址: https://gitcode.com/gh_mirrors/pa/PaddleSpeech导读本文围绕 PaddleSpeech 音频分类Audio Classification / CLS子系统的核心模型模块paddlespeech.cls.models.panns.panns展开该模块是docs/source/api/paddlespeech.cls.models.panns.panns.rst通过automodule指令自动生成 API 文档的对象也是 ESC-50 环境声音分类示例 与 TESS 情绪语音分类示例 的骨干网络来源。读完本文你将掌握 PANNs 系列模型CNN14 / CNN10 / CNN6的网络结构与前向细节、预训练权重的加载机制、SoundClassifier分类头的工作原理以及从 YAML 配置、模型微调、静态图导出到 C/Android 端部署的完整实战链路。模块概览API 文档指令背后的真实代码docs/source/api/paddlespeech.cls.models.panns.panns.rst的内容是 Sphinx 的标准 API 文档骨架paddlespeech.cls.models.panns.panns module .. automodule:: paddlespeech.cls.models.panns.panns :members: :undoc-members: :show-inheritance:它本身不携带实现而是在文档构建时把paddlespeech.cls.models.panns.panns模块的公开成员、类与方法原样渲染为参考文档。因此该文档的技术主体即模块源码 panns.py其对外导出的 API 集合定义在文件末尾__all__ [CNN14, CNN10, CNN6, cnn14, cnn10, cnn6]同时同级目录的 classifier.py 提供SoundClassifier分类头而init.py 通过from .classifier import *与from .panns import *将两者合并导出形成paddlespeech.cls.models命名空间下完整的音频分类模型族。基础卷积块ConvBlock 与 ConvBlock5x5ConvBlock双 3×3 卷积残差式堆叠ConvBlock是 CNN14 / CNN10 的基本构件每个块内部包含两个kernel_size(3, 3)、padding(1, 1)、无偏置bias_attrFalse的二维卷积以及对应的两个BatchNorm2D激活函数统一为 ReLU。其forward的签名是def forward(self, x, pool_size(2, 2), pool_typeavg):池化行为由pool_type决定且实现了 PANNs 论文中的三种策略maxF.max_pool2d(x, kernel_sizepool_size)avgF.avg_pool2d(x, kernel_sizepool_size)默认avgmax平均池化与最大池化结果逐元素相加其他取值直接抛出Exception提示仅支持max、avg与avgmax这种avgmax 双路池化是 PANNs 对特征时间维度进行压缩的关键技巧能同时保留响度均值与瞬态峰值信息。ConvBlock5x5单 5×5 卷积块ConvBlock5x5是 CNN6 的构件结构与ConvBlock类似但每个块只包含一个kernel_size(5, 5)、padding(2, 2)的卷积加一个BatchNorm2D同样支持三种池化模式。5×5 大卷积核以更少的层数获得更大的感受野适合更轻量的骨干。三个骨干网络CNN14、CNN10、CNN6三个网络共享同一个前端 卷积骨干 全局汇聚 分类头的整体框架区别在于卷积块数量、通道数与输出嵌入维度。CNN146 个卷积块、embedding 2048 维从源码 panns.py#L109-L169 可以看到其结构组成部分配置说明bn0BatchNorm2D(64)对输入频谱做批归一化conv_block11 → 64 通道池化 (2, 2)conv_block264 → 128 通道池化 (2, 2)conv_block3128 → 256 通道池化 (2, 2)conv_block4256 → 512 通道池化 (2, 2)conv_block5512 → 1024 通道池化 (2, 2)conv_block61024 → 2048 通道池化 (1, 1)最后一层不做空间下采样fc1Linear(2048, 2048)嵌入层emb_size 2048fc_audiosetLinear(2048, 527)对应 AudioSet 的 527 个类别每个卷积块之后都施加F.dropout(x, p0.2)仅在训练时生效全局汇聚采用x.mean(axis3)与x.max(axis2) x.mean(axis2)的组合即先对频率轴求均值、再对时间轴做 maxmean 融合最后接p0.5的 dropout 与 ReLU 激活的fc1。CNN10 与 CNN6轻量变体CNN10由 4 个ConvBlock组成通道沿 1 → 64 → 128 → 256 → 512 扩展emb_size 512汇聚方式与 CNN14 一致。可以推断它用更少的参数换取更快的推理适合资源受限场景。CNN6由 4 个ConvBlock5x5组成通道同样扩展至 512emb_size 512是三者中最轻量的选择。一个小提醒CNN10/CNN6的类注释沿用了 14-layer CNNs 的说明文案属于上游注释的笔误实际结构以构造代码为准。双模式输出embedding 还是 AudioSet logits三个网络的前向尾部都由extract_embedding标志控制extract_embeddingTrue默认直接返回fc1之后、经p0.5dropout 的 512/2048 维嵌入向量供下游SoundClassifier接自定义分类头extract_embeddingFalse对fc_audioset(x)施加F.sigmoid输出 AudioSet 527 类的多标签概率。注意forward开头先执行x x.transpose([0, 3, 2, 1])在bn0前后交换张量维度说明模块期望的输入布局为(batch, 1, n_mels, frames)经转置到通道维后做归一化使用时应保证特征张量的维度顺序与之一致。工厂函数与预训练权重加载模块提供三个工厂函数cnn14/cnn10/cnn6签名统一为def cnn14(pretrained: boolFalse, extract_embedding: boolTrue) - CNN14:预训练权重表定义在模块顶部 panns.py#L24-L28pretrained_model_urls { cnn14: https://bj.bcebos.com/paddleaudio/models/panns_cnn14.pdparams, cnn10: https://bj.bcebos.com/paddleaudio/models/panns_cnn10.pdparams, cnn6: https://bj.bcebos.com/paddleaudio/models/panns_cnn6.pdparams, }当pretrainedTrue时通过load_state_dict_from_url来自 download.py下载权重保存到os.path.join(MODEL_HOME, panns)MODEL_HOME定义于 env.py随后用model.set_state_dict(state_dict)注入模型。这意味着只要网络可访问第一次实例化cnn14(pretrainedTrue)便会自动获取 AudioSet 预训练参数无需手动下载。分类头SoundClassifierpanns/classifier.py 中的SoundClassifier把 PANNs 骨干封装为端到端分类模型class SoundClassifier(nn.Layer): def __init__(self, backbone, num_class, dropout0.1): self.backbone backbone self.dropout nn.Dropout(dropout) self.fc nn.Linear(self.backbone.emb_size, num_class) def forward(self, x): # x: (batch_size, num_frames, num_melbins) - (batch_size, 1, num_frames, num_melbins) x x.unsqueeze(1) x self.backbone(x) x self.dropout(x) logits self.fc(x) return logits它接收形状为(batch, num_frames, num_melbins)的对数梅尔频谱先unsqueeze(1)补出单通道维匹配骨干的(batch, 1, n_mels, frames)输入约定经骨干提取嵌入后接Linear(emb_size, num_class)输出各类别 logits。分类头层的维度由backbone.emb_size动态决定因此更换骨干只需替换backbonenum_class则来自数据集类别数。配置文件全解特征与训练超参数ESC-50 示例panns.yamlexamples/esc50/cls0/conf/panns.yaml 是官方微调配置逐段说明如下data: dataset: paddle.audio.datasets:ESC50 num_classes: 50 train: mode: train split: 1 dev: mode: dev split: 1 model: backbone: paddlespeech.cls.models:cnn14 feature: sr: 32000 n_fft: 1024 hop_length: 320 window: hann win_length: 1024 f_min: 50.0 f_max: 14000.0 n_mels: 64 training: epochs: 50 learning_rate: 0.00005 num_workers: 2 batch_size: 16 checkpoint_dir: ./checkpoint save_freq: 10 log_freq: 10 predicting: audio_file: /audio/dog.wav top_k: 10 checkpoint: ./checkpoint/epoch_50/model.pdparams要点说明特征对齐sr32000、n_fft1024、hop_length320、n_mels64、f_min50、f_max14000与 custom_dataset.md 中特征配置必须与预训练模型对齐的要求一致——预训练权重是在 32 kHz 采样率、64 维梅尔滤波组上训练的微调时不可随意改动backbone使用dynamic_import字符串加载机制见 dynamic_import.pypaddlespeech.cls.models:cnn14即模块路径:符号名split指定 ESC-50 的折数fold训练集使用fold ! split的样本验证集使用fold split实现单折交叉验证top_k控制预测时输出概率最高的类别个数。TESS 示例四种特征后端对比examples/tess/cls0/conf 下提供了四份配置用于对比不同前端特征对同一骨干的影响配置文件feat_type特征专属参数训练轮数 / 学习率panns_logmelspectrogram.yamllogmelspectrogramn_mels: 645 / 0.0005panns_melspectrogram.yamlmelspectrogramn_mels: 6410 / 0.0005panns_mfcc.yamlmfccn_mfcc: 64,n_mels: 645 / 0.0005panns_spectrogram.yamlspectrogramn_fft: 126无梅尔10 / 0.0005四份配置的data.train/dev段都带有feat_type字段model.backbone均为cnn14说明同一骨干可以在不同特征表示上微调便于在 TESS 7 类情绪数据集上做特征工程消融实验。训练与评估实战一键脚本流水线examples/esc50/cls0/run.sh 按 stage 组织完整流程stage脚本功能1./local/train.sh ${ngpu} ${cfg_path}训练 / 微调2./local/infer.sh ${cfg_path}加载 checkpoint 推理3./local/export.sh ${ckpt} ${output_dir}导出静态图4./local/static_model_infer.sh ${infer_device} ${graph_dir} ${audio_file}静态图部署推理按照 docs/source/cls/quick_start.md 的引导进入示例目录后执行cd examples/esc50/cls0 source path.sh CUDA_VISIBLE_DEVICES0 ./run.sh 1path.sh会把MAIN_ROOT加入PYTHONPATH并将BIN_DIR指向paddlespeech/cls/exps/pannstrain.sh内部根据ngpu决定是否调用paddle.distributed.launch做多卡分布式训练。没有 GPU 时将CUDA_VISIBLE_DEVICES置空即可回退到 CPU。训练主循环的数据流paddlespeech/cls/exps/panns/train.py 是训练入口其核心流程yaml.safe_load解析配置分别取出model、data、feature、training四段dynamic_import(data_conf[dataset])实例化数据集用DistributedBatchSamplerDataLoader构建(waveforms, labels)数据流用LogMelSpectrogram(**feat_conf)在线提取特征paddle.transpose(feats, [0, 2, 1])转成[N, length, n_mels]送入模型构建backbone_class(pretrainedTrue, extract_embeddingTrue)SoundClassifier配Adam优化器与CrossEntropyLoss每个 batch 依次loss.backward()→optimizer.step()→clear_grad()统计 loss 与argmax准确率按log_freq打印、按save_freq保存 checkpoint。源码注释特别提示当 batch 内波形长度不一致时需要自行 padding这与 deploy/predict.py 中np.pad对齐max_length的处理逻辑相互印证。推理与部署动态图推理top-k 输出paddlespeech/cls/exps/panns/predict.py 通过soundfile_load读取 wavLogMelSpectrogram提特征加载predicting.checkpoint后计算F.softmax(logits, axis1)按概率降序输出top_k个label: prob结果。静态图导出paddlespeech/cls/exps/panns/export_model.py 将动态模型转静态图model paddle.jit.to_static( model, input_spec[ paddle.static.InputSpec( shape[None, None, 64], dtypepaddle.float32) ], full_graphTrue) paddle.jit.save(model, os.path.join(args.output_dir, inference))注意InputSpec的形状[None, None, 64]与训练时[N, length, n_mels64]的约定一致导出的inference.pdmodel/inference.pdiparams即静态推理产物。静态图部署推理deploy/predict.py 基于paddle.inference提供生产级推理入口支持的参数--devicecpu/gpu/xpu/gcu--use_tensorrt与--precisionfp32/fp16GPU 下启用 TensorRT 加速--cpu_threads默认 10与--enable_mkldnnCPU 下线程数与 MKL-DNN 加速当检测到 Paddle 版本 3.0.0-beta 时改用inference.Config(model_dir, inference)的新式加载方式。调用方式对应 stage 4./local/static_model_infer.sh cpu ./export /path/to/test.wav输出形如Wav: xxx.wav Label: Dog。C 运行时与端侧部署除了 Python 侧PANNs 模型还通过 FastDeploy 接入 PaddleSpeech 的 C 运行时相关代码位于 runtime/engine/audio_classification/nnetpanns_interface.cc的ClsCreateInstance从配置读取推理参数默认值见 panns_interface.cc#L26-L40wav_normal默认 true与wav_normal_type默认linear波形归一化samp_freq默认 32000、frame_length_ms32、frame_shift_ms10、num_bins64、low_freq50、high_freq14000、dither0.0FBank 前端参数与 Python 侧特征配置对齐model_path/param_path/dict_path模型文件与标签表num_cpu_thread默认 12CPU 线程数。panns_nnet.cc的Init用上述参数构造 FBank 选项并通过fastdeploy::Runtime按编译宏选择USE_PADDLE_INFERENCE_BACKENDPaddle Inference、USE_ORT_BACKENDONNX Runtime或USE_PADDLE_LITE_BACKENDLite后端加载模型。运行示例见 runtime/examples/audio_classification/README.md../../build/Linux/x86_64/engine/audio_classification/nnet/panns_nnet_main --conf_path./conf --scp_path./scp --topk1输出如test.wav{Clock alarm:16.5309}即 wav 文件名 top-1 标签 得分。同一份 README 还说明了通过 build_android.sh 构建 Android 动态库、拷贝panns_interface.h与.so到examples/audio_classification/android_demo再以adb push部署 conf / label_list / wav 到/data/local/tmp的端侧流程说明 PANNs 模型从云端服务到移动端均可运行。自定义数据集把 PANNs 迁移到自己的音频分类任务docs/source/cls/custom_dataset.md 给出了完整迁移方案继承基类paddlespeech.audio.datasets.dataset.AudioClassificationDataset提供label_list与_get_data从每行wav路径 标签的 meta 文件构建数据集如 ESC50 的实现见 esc50.py它内置 50 类标签、自动下载解压ESC-50-master.zip并按 fold 划分 train/dev。随后用cnn14(pretrainedTrue, extract_embeddingTrue)SoundClassifier(backbone, num_classlen(label_list))即可微调from paddlespeech.cls.models import cnn14, SoundClassifier backbone cnn14(pretrainedTrue, extract_embeddingTrue) model SoundClassifier(backbone, num_classlen(train_ds.label_list)) optimizer paddle.optimizer.Adam(learning_rate1e-6, parametersmodel.parameters()) criterion paddle.nn.loss.CrossEntropyLoss()训练循环中特征配置32 kHz、64 维梅尔必须与预训练一致仅替换数据集与num_class即可把 AudioSet 预训练知识迁移到诸如环境声音、情绪语音等自定义音频分类任务上。小结paddlespeech.cls.models.panns.panns是 PaddleSpeech 音频分类链路中承上启下的核心模块向上承接SoundClassifier与微调/推理脚本向下通过 FBank 特征与预训练权重对齐横向又打通了 FastDeploy 驱动的 C/Android 部署。从 panns.py 的 CNN14/CNN10/CNN6 结构到 panns.yaml 的逐项超参数再到 quick_start.md 与 custom_dataset.md 的实操指南读者可以依据本文按结构理解 → 配置微调 → 静态导出 → 多端部署的路径完整走通一个音频分类项目。【免费下载链接】PaddleSpeechEasy-to-use Speech Toolkit including Self-Supervised Learning model, SOTA/Streaming ASR with punctuation, Streaming TTS with text frontend, Speaker Verification System, End-to-End Speech Translation and Keyword Spotting. Won NAACL2022 Best Demo Award.项目地址: https://gitcode.com/gh_mirrors/pa/PaddleSpeech创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表