(以下内容搬运自飞桨PaddleSpeech语音技术课程,点击链接可直接运行源码)

1. 识别声音

通过声音,人的大脑会获取到大量的信息,其中的一个场景是:识别和归类。如:识别熟悉的亲人或朋友的声音、识别不同乐器发出的声音、识别不同环境产生的声音,等等。

我们可以根据不同声音的特征(频率,音色等)进行区分,这种区分行为的本质,就是对声音进行分类。

音色:
声音是由发声的物体的振动产生的。当发声物体的主体振动时会发出一个基音,同时其余各部分也有复合的振动,这些振动组合产生泛音。正是这些泛音决定了发生物体的音色,使人能辨别出不同的乐器甚至不同的人发出的声音。所以根据音色的不同可以划分出男音和女音;高音、中音和低音;弦乐和管乐等。

声音分类根据用途还可以继续细分:

  • 副语言识别:说话人识别(Speaker Recognition), 情绪识别(Speech Emotion Recognition),性别分类(Speaker gender classification)
  • 音乐识别:音乐流派分类(Music Genre Classification)
  • 场景识别:环境声音分类(Environmental Sound Classification)
  • 声音事件检测:各个环境中的声音事件和起始时间的检测
图片来源:http://speech.ee.ntu.edu.tw/~tlkagk/courses/DLHLP20/Speaker%20(v3).pdf

1.1 Audio Tagging

使用 PaddleSpeech 的预训练模型对一段音频做实时的声音检测,结果如下视频所示。

点击播放

2. 音频和特征提取

# 环境准备:安装 paddlespeech 和 paddleaudio
!pip install paddlespeech==1.2.0
!pip install paddleaudio==1.0.1
import warnings
warnings.filterwarnings("ignore")
import IPython
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

2.1 数字音频

2.1.1 声音信号和音频文件

下面通过一个例子观察音频文件的波形,直观地了解数字音频文件的包含的内容。

# 获取示例音频
!test -f ./dog.wav || wget https://paddlespeech.bj.bcebos.com/PaddleAudio/dog.wav
IPython.display.Audio('./dog.wav')
from paddleaudio import load
data, sr = load(file='./dog.wav', mono=True, dtype='float32')  # 单通道,float32音频样本点
print('wav shape: {}'.format(data.shape))
print('sample rate: {}'.format(sr))# 展示音频波形
plt.figure()
plt.plot(data)
plt.show()
!paddlespeech cls --input ./dog.wav
!paddlespeech help

2.2 音频特征提取

2.2.1 短时傅里叶变换

对于一段音频,一般会将整段音频进行分帧,每一帧含有一定长度的信号数据,一般使用 25ms,帧与帧之间的移动距离称为帧移,一般使用 10ms,然后对每一帧的信号数据加窗后,进行离散傅立叶变换(DFT)得到频谱图。

通过按照上面的对一段音频进行分帧后,我们可以用傅里叶变换来分析每一帧信号的频率特性。将每一帧的频率信息拼接后,可以获得该音频不同时刻的频率特征——Spectrogram,也称作为语谱图。

图片参考:DLHLP 李宏毅 语音识别课程PPT;https://www.shong.win/2016/04/09/fft/

下面例子采用 paddle.signal.stft 演示如何提取示例音频的频谱特征,并进行可视化:

import paddle
import numpy as npdata, sr = load(file='./dog.wav', sr=32000, mono=True, dtype='float32')
x = paddle.to_tensor(data)
n_fft = 1024
win_length = 1024
hop_length = 320# [D, T]
spectrogram = paddle.signal.stft(x, n_fft=n_fft, win_length=win_length, hop_length=512, onesided=True)
print('spectrogram.shape: {}'.format(spectrogram.shape))
print('spectrogram.dtype: {}'.format(spectrogram.dtype))spec = np.log(np.abs(spectrogram.numpy())**2)
plt.figure()
plt.title("Log Power Spectrogram")
plt.imshow(spec[:100, :], origin='lower')
plt.show()

2.2.2 LogFBank

研究表明,人类对声音的感知是非线性的,随着声音频率的增加,人对更高频率的声音的区分度会不断下降。

例如同样是相差 500Hz 的频率,一般人可以轻松分辨出声音中 500Hz 和 1,000Hz 之间的差异,但是很难分辨出 10,000Hz 和 10,500Hz 之间的差异。

因此,学者提出了梅尔频率,在该频率计量方式下,人耳对相同数值的频率变化的感知程度是一样的。

图片来源:https://www.researchgate.net/figure/Curve-relationship-between-frequency-signal-with-its-mel-frequency-scale-Algorithm-1_fig3_221910348

关于梅尔频率的计算,其会对原始频率的低频的部分进行较多的采样,从而对应更多的频率,而对高频的声音进行较少的采样,从而对应较少的频率。使得人耳对梅尔频率的低频和高频的区分性一致。

图片来源:https://ww2.mathworks.cn/help/audio/ref/mfcc.html

Mel Fbank 的计算过程如下,而我们一般都是使用 LogFBank 作为识别特征:

图片来源:https://ww2.mathworks.cn/help/audio/ref/mfcc.html

下面例子采用 paddleaudio.features.LogMelSpectrogram 演示如何提取示例音频的 LogFBank:

from paddleaudio.features import LogMelSpectrogramf_min=50.0
f_max=14000.0
#   - sr: 音频文件的采样率。
#   - n_fft: FFT样本点个数。
#   - hop_length: 音频帧之间的间隔。
#   - win_length: 窗函数的长度。
#   - window: 窗函数种类。
#   - n_mels: 梅尔刻度数量。
feature_extractor = LogMelSpectrogram(sr=sr, n_fft=n_fft, hop_length=hop_length, win_length=win_length, window='hann', f_min=f_min,f_max=f_max,n_mels=64)x = paddle.to_tensor(data).unsqueeze(0)     # [B, L]
log_fbank = feature_extractor(x) # [B, D, T]
log_fbank = log_fbank.squeeze(0) # [D, T]
print('log_fbank.shape: {}'.format(log_fbank.shape))plt.figure()
plt.imshow(log_fbank.numpy(), origin='lower')
plt.show()

2.3 声音分类方法

2.3.1 传统机器学习方法

在传统的声音和信号的研究领域中,声音特征是一类包含丰富先验知识的手工特征,如频谱图、梅尔频谱和梅尔频率倒谱系数等。

因此在一些分类的应用上,可以采用传统的机器学习方法例如决策树、svm和随机森林等方法。

一个典型的应用案例是:男声和女声分类。

图片来源:https://journals.plos.org/plosone/article/figure?id=10.1371/journal.pone.0179403.g001

2.3.2 深度学习方法

传统机器学习方法可以捕捉声音特征的差异(例如男声和女声的声音在音高上往往差异较大)并实现分类任务。

而深度学习方法则可以突破特征的限制,更灵活的组网方式和更深的网络层次,可以更好地提取声音的高层特征,从而获得更好的分类指标。

随着深度学习算法的快速发展和在分类任务上的优异表现,当下流行的声音分类模型无一不是采用深度学习网络搭建而成的,如 AudioCLIP[1]、PANNs[2] 和 Audio Spectrogram Transformer[3] 等。

图片来源:https://towardsdatascience.com/audio-deep-learning-made-simple-sound-classification-step-by-step-cebc936bbe5

2.3.3 Pretrain + Finetune

在声音分类和声音检测的场景中(如环境声音分类、情绪识别和音乐流派分类等)由于可获取的据集有限,且语音数据标注的成本高,用户可以收集到的数据集体量往往较小,这种数据量稀少的情况对于模型训练是非常不利的。

预训练模型能够减少领域数据的需求量,并达到较高的识别准确率。在CV和NLP领域中,有诸如 MobileNet、VGG19、YOLO、BERT 和 ERNIE 等开源的预训练模型,在图像检测、图像分类、文本分类和文本生成等各自领域内的任务中,使用预训练模型在下游任务的数据集上进行 finetune ,往往可以更快和更容易获得较好的效果和指标。

相较于 CV 领域的 ImageNet 数据集,谷歌在 2017 年开放了一个大规模的音频数据集 AudioSet[4],它是目前最大的用于音频分类任务的数据集。该数据集包含了 632 类的音频类别以及 2084320 条人工标记的每段 10 秒长度的声音剪辑片段(包括 527 个标签),数据总时长为 5,800 小时。

图片来源:https://research.google.com/audioset/ontology/index.html

PANNs(PANNs: Large-Scale Pretrained Audio Neural Networks for Audio Pattern Recognition[2])是基于 AudioSet 数据集训练的声音分类/识别的模型,其中PANNs-CNN14在测试集上取得了较好的效果:mAP 为 0.431,AUC 为 0.973,d-prime 为 2.732,经过预训练后,该模型可以用于提取音频的 embbedding ,适合用于声音分类和声音检测等下游任务。本示例将使用 PANNs 的预训练模型 Finetune 完成声音分类的任务。

本教程选取 PANNs 中的预训练模型 cnn14 作为 backbone,用于提取声音的深层特征,SoundClassifer创建下游的分类网络,实现对输入音频的分类。

3. 实践:环境声音分类

3.1 数据集准备

此课程选取了ESC-50: Dataset for Environmental Sound Classification[5] 数据集作为示例。

ESC-50是一个包含有 2000 个带标签的环境声音样本,音频样本采样率为 44,100Hz 的单通道音频文件,所有样本根据标签被划分为 50 个类别,每个类别有 40 个样本。

音频样本可分为 5 个主要类别:

  • 动物声音(Animals)
  • 自然界产生的声音和水声(Natural soundscapes & water sounds)
  • 人类发出的非语言声音(Human, non-speech sounds)
  • 室内声音(Interior/domestic sounds)
  • 室外声音和一般噪声(Exterior/urban noises)。

ESC-50 数据集中的提供的 meta/esc50.csv 文件包含的部分信息如下:

   filename,fold,target,category,esc10,src_file,take1-100038-A-14.wav,1,14,chirping_birds,False,100038,A1-100210-A-36.wav,1,36,vacuum_cleaner,False,100210,A1-101296-A-19.wav,1,19,thunderstorm,False,101296,A...
  • filename: 音频文件名字。
  • fold: 数据集自身提供的N-Fold验证信息,用于切分训练集和验证集。
  • target: 标签数值。
  • category: 标签文本信息。
  • esc10: 文件是否为ESC-10的数据集子集。
  • src_file: 原始音频文件前缀。
  • take: 原始文件的截取段落信息。

在此声音分类的任务中,我们将target作为训练过程的分类标签。

3.1.1 数据集初始化

调用以下代码自动下载并读取数据集音频文件,创建训练集和验证集。

from paddleaudio.datasets import ESC50train_ds = ESC50(mode='train', sample_rate=sr)
dev_ds = ESC50(mode='dev', sample_rate=sr)

3.1.2 特征提取

通过下列代码,用 paddleaudio.features.LogMelSpectrogram 初始化一个音频特征提取器,在训练过程中实时提取音频的 LogFBank 特征,其中主要的参数如下:

feature_extractor = LogMelSpectrogram(sr=sr, n_fft=n_fft, hop_length=hop_length, win_length=win_length, window='hann',     f_min=f_min,f_max=f_max, n_mels=64)

3.2 模型

3.2.1 选取预训练模型

选取cnn14作为 backbone,用于提取音频的特征:

from paddlespeech.cls.models import cnn14
backbone = cnn14(pretrained=True, extract_embedding=True)

3.2.2 构建分类模型

SoundClassifer接收cnn14作为backbone模型,并创建下游的分类网络:

import paddle.nn as nnclass SoundClassifier(nn.Layer):def __init__(self, backbone, num_class, dropout=0.1):super().__init__()self.backbone = backboneself.dropout = nn.Dropout(dropout)self.fc = nn.Linear(self.backbone.emb_size, num_class)def forward(self, x):x = x.unsqueeze(1)x = self.backbone(x)x = self.dropout(x)logits = self.fc(x)return logitsmodel = SoundClassifier(backbone, num_class=len(ESC50.label_list))

3.3 Finetune

  1. 创建 DataLoader
batch_size = 16
train_loader = paddle.io.DataLoader(train_ds, batch_size=batch_size, shuffle=True)
dev_loader = paddle.io.DataLoader(dev_ds, batch_size=batch_size,)
  1. 定义优化器和 Loss
optimizer = paddle.optimizer.Adam(learning_rate=1e-4, parameters=model.parameters())
criterion = paddle.nn.loss.CrossEntropyLoss()
  1. 启动模型训练
from paddleaudio.utils import loggerepochs = 20
steps_per_epoch = len(train_loader)
log_freq = 10
eval_freq = 10for epoch in range(1, epochs + 1):model.train()avg_loss = 0num_corrects = 0num_samples = 0for batch_idx, batch in enumerate(train_loader):waveforms, labels = batchfeats = feature_extractor(waveforms)feats = paddle.transpose(feats, [0, 2, 1])  # [B, N, T] -> [B, T, N]logits = model(feats)loss = criterion(logits, labels)loss.backward()optimizer.step()if isinstance(optimizer._learning_rate,paddle.optimizer.lr.LRScheduler):optimizer._learning_rate.step()optimizer.clear_grad()# Calculate lossavg_loss += loss.numpy()[0]# Calculate metricspreds = paddle.argmax(logits, axis=1)num_corrects += (preds == labels).numpy().sum()num_samples += feats.shape[0]if (batch_idx + 1) % log_freq == 0:lr = optimizer.get_lr()avg_loss /= log_freqavg_acc = num_corrects / num_samplesprint_msg = 'Epoch={}/{}, Step={}/{}'.format(epoch, epochs, batch_idx + 1, steps_per_epoch)print_msg += ' loss={:.4f}'.format(avg_loss)print_msg += ' acc={:.4f}'.format(avg_acc)print_msg += ' lr={:.6f}'.format(lr)logger.train(print_msg)avg_loss = 0num_corrects = 0num_samples = 0if epoch % eval_freq == 0 and batch_idx + 1 == steps_per_epoch:model.eval()num_corrects = 0num_samples = 0with logger.processing('Evaluation on validation dataset'):for batch_idx, batch in enumerate(dev_loader):waveforms, labels = batchfeats = feature_extractor(waveforms)feats = paddle.transpose(feats, [0, 2, 1])logits = model(feats)preds = paddle.argmax(logits, axis=1)num_corrects += (preds == labels).numpy().sum()num_samples += feats.shape[0]print_msg = '[Evaluation result]'print_msg += ' dev_acc={:.4f}'.format(num_corrects / num_samples)logger.eval(print_msg)

3.4 音频预测

执行预测,获取 Top K 分类结果:

top_k = 10
wav_file = './dog.wav'waveform, sr = load(wav_file, sr=sr)
feature_extractor = LogMelSpectrogram(sr=sr, n_fft=n_fft, hop_length=hop_length, win_length=win_length, window='hann', f_min=f_min, f_max=f_max, n_mels=64)
feats = feature_extractor(paddle.to_tensor(paddle.to_tensor(waveform).unsqueeze(0)))
feats = paddle.transpose(feats, [0, 2, 1])  # [B, N, T] -> [B, T, N]logits = model(feats)
probs = nn.functional.softmax(logits, axis=1).numpy()sorted_indices = probs[0].argsort()msg = f'[{wav_file}]\n'
for idx in sorted_indices[-1:-top_k-1:-1]:msg += f'{ESC50.label_list[idx]}:{probs[0][idx]:.5f}\n'
print(msg)

4. 作业

  1. 使用开发模式安装 PaddleSpeech
    环境要求:docker, Ubuntu 16.04,root user。
    参考安装方法:使用Docker安装paddlespeech
  2. 在 MusicSpeech 数据集上完成 music/speech 二分类。
  3. 在 GTZAN Genre Collection 音乐分类数据集上利用 PANNs 预训练模型实现音乐类别十分类。

关于如何自定义分类数据集,请参考文档 PaddleSpeech/docs/source/cls/custom_dataset.md

5. 关注 PaddleSpeech

请关注我们的 Github Repo,非常欢迎加入以下微信群参与讨论:

  • 扫描二维码
  • 添加运营小姐姐微信
  • 通过后回复【语音】
  • 系统自动邀请加入技术群

6. 参考文献

[1] Guzhov, A., Raue, F., Hees, J., & Dengel, A.R. (2021). AudioCLIP: Extending CLIP to Image, Text and Audio. ArXiv, abs/2106.13043.

[2] Kong, Q., Cao, Y., Iqbal, T., Wang, Y., Wang, W., & Plumbley, M.D. (2020). PANNs: Large-Scale Pretrained Audio Neural Networks for Audio Pattern Recognition. IEEE/ACM Transactions on Audio, Speech, and Language Processing, 28, 2880-2894.

[3] Gong, Y., Chung, Y., & Glass, J.R. (2021). AST: Audio Spectrogram Transformer. ArXiv, abs/2104.01778.

[4] Gemmeke, J.F., Ellis, D.P., Freedman, D., Jansen, A., Lawrence, W., Moore, R.C., Plakal, M., & Ritter, M. (2017). Audio Set: An ontology and human-labeled dataset for audio events. 2017 IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP), 776-780.

[5] Piczak, K.J. (2015). ESC: Dataset for Environmental Sound Classification. Proceedings of the 23rd ACM international conference on Multimedia.

P.S. 欢迎关注我们的 github repo PaddleSpeech, 是基于飞桨 PaddlePaddle 的语音方向的开源模型库,用于语音和音频中的各种关键任务的开发,包含大量基于深度学习前沿和有影响力的模型。

【飞桨PaddleSpeech语音技术课程】— 声音分类相关推荐

  1. 【飞桨PaddleSpeech语音技术课程】— 一句话语音合成全流程实践

    (以下内容搬运自飞桨PaddleSpeech语音技术课程,点击链接可直接运行源码) 一句话语音合成全流程实践 点击播放视频 1 声音克隆介绍 & 语音合成基本概念回顾 语音合成(Speech ...

  2. 【飞桨PaddleSpeech语音技术课程】— 语音唤醒

    (以下内容搬运自飞桨PaddleSpeech语音技术课程,点击链接可直接运行源码) 1. KWS 概述 随着人工智能的飞速发展,市场上推出了各式各样的智能设备,AI 语音的发展更是使得语音助手成为各大 ...

  3. 【飞桨PaddleSpeech语音技术课程】— 语音合成

    (以下内容搬运自飞桨PaddleSpeech语音技术课程,点击链接可直接运行源码) 『听』和『说』 人类通过听觉获取的信息大约占所有感知信息的 20% ~ 30%.声音存储了丰富的语义以及时序信息,由 ...

  4. 【飞桨PaddleSpeech语音技术课程】— 语音识别-Deepspeech2

    (以下内容搬运自飞桨PaddleSpeech语音技术课程,点击链接可直接运行源码) 语音识别--DeepSpeech2 0. 视频理解与字幕 # 下载demo视频 !test -f work/sour ...

  5. 【飞桨PaddleSpeech语音技术课程】— 语音识别-定制化识别

    (以下内容搬运自飞桨PaddleSpeech语音技术课程,点击链接可直接运行源码) 定制化语音识别 1. 背景 在一些特定场景下,要求ASR系统对某些固定句式的关键词准确识别. 打车报销单场景,要求日 ...

  6. 【飞桨PaddleSpeech语音技术课程】— 流式语音合成技术揭秘与实践

    (以下内容搬运自飞桨PaddleSpeech语音技术课程,点击链接可直接运行源码) PP-TTS:流式语音合成原理及服务部署 1 流式语音合成服务的场景与产业应用 语音合成(Speech Sysnth ...

  7. 【飞桨PaddleSpeech语音技术课程】— 语音翻译

    (以下内容搬运自飞桨PaddleSpeech语音技术课程,点击链接可直接运行源码) End-to-End Speech (to Text) Translation 前言 背景知识 语音翻译(ST, S ...

  8. 《飞桨PaddleSpeech语音技术课程》一句话语音合成全流程实践

    一句话语音合成全流程实践 PaddleSpeech r1.2.0 发新内容 1 声音克隆介绍 & 语音合成基本概念回顾 语音合成(Speech Sysnthesis),又称文本转语音(Text ...

  9. 【飞桨PaddleSpeech语音技术课程】— 语音识别-Transformer

    使用 Transformer 进行语音识别 0. 视频理解与字幕 # 下载demo视频 !test -f work/source/subtitle_demo1.mp4 || wget -c https ...

最新文章

  1. Matlab实现连通域标记算法求图像连通域
  2. AOP 中必须明白的概念-切入点(Pointcut)
  3. 连接excel执行Insert Into语句出现“操作必须使用一个可更新的查询”的解决
  4. jpa怎么传参到in中_Java中如何处理开关状态的属性字段?
  5. 逻辑思维与C/C++解题
  6. ASP中如何在退出一个页面时自动清空session变量
  7. 介绍下Javascript原型和原型链的特点?
  8. web和python哪个好_用python开发app和web哪个比较容易?
  9. 非学习的点云配准方法汇总
  10. 无线通信与编码_Rake接收机_三种合并算法_MATLAB仿真代码
  11. 领导不待见这4种员工,能力再强也不会被重用,提前被辞退
  12. 前端使用vue+ js-xlsl + elemen-ui实现导出Excel表格(绝对好使, 前端有问题直接关注我, 或者评论立刻给你回应, 专业解决)
  13. 程序员外包兼职平台介绍
  14. 服务器 t610硬盘开关,戴尔服务器T610
  15. Monorepo 項目管理方案:lerna + yarn workspace / pnpm
  16. 分糖果系列一(DP+暴力)
  17. 服务器安全文件,文件服务器安全防护系统-虹安 - 数据防泄密,文档加密,源代码防泄密,数据防泄漏,DLP数据防泄密整体解决方案提供商...
  18. 网页保存mhtml格式
  19. 运营技巧|如何把产品运营好?
  20. 教学ppt设计与制作

热门文章

  1. 将视频分帧后用于制作图片数据集方法
  2. 移动端图片上传裁切(版权归秒为所有,仅为搬运)
  3. java编写的打印标签图片文档的软件
  4. Photoshop CS4 存储与载入选区
  5. IDEA:idea中的Git冲突解决(非常重要)
  6. 将一句话的单词进行倒置,标点符号不倒置
  7. java ppt 绘图,Java 在PPT中绘制图形
  8. 七句话讲清NSA单模与SA+NSA双模5G手机的真实区别
  9. log4j配置说明及范本
  10. 镇海三日游——ZJOI2019游记