神经网络的音频分析

音频编码
Audio 对象(或音频文件)转换为适合神经网络的格式的基本工具是 NetEncoder. Wolfram 语言本身提供了几种基于不同类型的特征计算的音频编码器. 这些编码器都利用底层、并行实现以允许非常快速的计算.

编码器类型

所有编码器共享相同的预处理步骤. 第一个是提取信号的适当部分,然后向下混合到单个通道并重新采样为统一 (uniform) 频率.
可用的音频编码器是:
"Audio"
信号波形
"AudioMelSpectrogram"
信号的短时傅立叶变换
"AudioMFCC"
信号的频谱
"AudioSpectrogram"
频率在梅尔标度上等间隔的频谱
"AudioSTFT"
梅尔频谱的对数的 FourierDCT
音频编码器.
"Audio" 编码器简单地提取信号的波形. 这保留了所有信息,但结果的维度对于神经网络并不理想.
"AudioSTFT" 编码器对信号进行分区,并在每个分区上计算 Fourier 变换(整个操作称为短时傅立叶变换,或STFT). 这提供了时间和频率信息,并且由于傅立叶变换是可逆的,因此保留了原始信号中的所有信息.
"AudioSpectrogram" 编码器计算 STFT 的平方幅度,并丢弃冗余部分. 这降低了特征的维数,但是相位信息丢失了. 仍然可以计算原始信号的近似重建(有关详细信息,请参阅 InverseSpectrogram).
"AudioMelSpectrogram" 编码器将滤波器组应用于频谱图. 滤波器组的中心频率在梅尔尺度上线性地间隔开,这是一种非线性频率尺度,模仿人类对音调的感知. 这进一步降低了维度.
"AudioMFCC" 编码器计算梅尔频谱的对数的 FourierDCT 并丢弃一些高阶系数. 这实现了非常高的维数简约,同时保留了许多重要信息,尤其是对于语音信号.
绘制 "AudioMelSpectrogram" 编码器的结果:

数据增强

所有音频编码器也共享 "Augmentation" 参数. 这允许它们在计算特征(例如频谱图或 MFCC)之前对输入执行数据增强.
在处理有限或缩小尺寸的数据集时,数据增强非常有用,并且使网络对于训练数据中的人为/无关趋势更加健壮. 例如,如果你要对猫和狗的录音进行分类,并且在训练数据中所有的狗都是用嘈杂的麦克风录制的,那么网络最终可能会识别出噪音而不是狗.
音频数据增强的另一个方便用途是从训练数据中的记录中提取片段.
可用的增强是:
"TimeShift"
将输入移动一个可以随机化的量
"Noise"
通过特定的 Audio 或文件或白噪声为输入添加噪声
"Volume"
将输入与可以随机化的常数相乘
"Convolution"
通过特定的 Audio 或文件对输入卷积脉冲响应
"VTLP"
将声道长度扰动应用于输入
所有增强都可以随机化.
同时应用两个增强:
音频分类
在 "Spoken Digit Commands" 数据集上训练分类网络.
数据集通过不同的说话者集合包括 1 万个从 0 到 9 的口头数字记录组成. 数据集的训练和测试部分的说话者不重叠.
收集数据:
使用 "AudioMFCC" 编码器,因为它可以在保留语音信号中存在的大量信息的同时显著降低维数.
创建编码器和解码器:
ConvolutionLayer 支持可变长度输入. 这可以通过将 "Interleaving" 选项设置为 True 来实现. 然后可以基于 "LeNet" 架构构建非常简单的卷积网络,该架构广泛用于图像处理. 需要对最终层进行一些调整以适应音频数据的可变长度性质.
创建卷积网,在数据集上训练并测量其性能:
另一种方法是创建一个完全循环的网络. 网络基于 GatedRecurrentLayer 堆栈,后面是一个简单的分类部分. 为了添加一些正则化,在循环层的输入处使用丢弃 (dropout).
创建循环网络,在数据集上训练并测量其性能:
通过移除最后的分类层,可以获得用于音频信号的特征提取器. 此特征提取器可以与对数字分类任务重要的特征相关;换句话说,学习的嵌入将包含关于说出哪个数字的信息,但是将忽略关于说话者身份的任何信息.
使用网络学习的嵌入来绘制测试数据集:
音频事件检测
在某些情况下,目标是训练网络以在记录中定位声音事件,但数据被弱标记,其中标签仅表示记录中是否存在某个事件,而不是在哪里. 尽管数据有限,但通过对弱标记数据的训练,可以在声音事件定位中获得良好的结果.
使用来自 Wolfram Data Repository 的 "Audio Cats and Dogs" 数据集,这是一组猫和狗的录音.
检索数据集:
信号的持续时间在 1 到 18 秒之间变化.
将数据划分为训练和测试集,并绘制信号持续时间的直方图:
使用 "AudioMelSpectrogram" 编码器将音频信号馈入网络. 由于数据量相对较小,因此可以进行数据增强以使训练更有效.
创建编码器和解码器:
网络将基于循环层(GatedRecurrentLayer)的堆栈,以及一个 AggregationLayer,用于将结果汇集在时间维度中. 这允许网络输出单个分类结果而不是序列.
创建网并在数据集上训练它:
为了以可重复的方式使用网络,带有增强的编码器需要用没有它们的编码器替换.
测量网络的性能:
通过移除 AggregationLayer 并将 SoftmaxLayer 重新连接到剪裁的网络,获得返回类概率序列而不是单个分类结果的网络.
创建时间分辨网并定义一个函数以轻松获得结果:
在包含猫和狗噪声的信号上测试这个时间分辨网.
在不在训练集中的信号上测试网:
音频嵌入
嵌入可以作为对分类任务训练的副作用来学习. 可以使用不同的训练任务来使学习有意义地嵌入训练目标.

具有对比损失的暹罗 (Siamese) 网络

学习嵌入的第一个策略是使用对比损失训练暹罗网络. 这涉及将两个输入馈送到完全相同的网络,计算两个输出之间的距离并将其馈送到对比损失. 如果两个输入属于同一个类,则距离将最小化;如果它们不是同一类,则距离将最大化.
这将再次使用 "Spoken Digit Commands" 数据集. 这一次,忽略说出哪个数字,只关注说话者.
收集数据并按说话者 ID 对其进行分组:
创建一组示例说话者对. 理想情况下,它应该有尽可能多的正面例子(来自相同说话者的录音)和负面例子(来自不同说话者的录音).
创建训练队:
此示例将使用非常简单的循环网络来生成嵌入. 它还将定义一个网络来训练嵌入. 这将需要将两个输入馈送到同一网络并计算所得嵌入的距离. 使用 NetInsertSharedArrays 确保两个输入由完全相同的网络处理.
创建将生成嵌入的网和计算对比损失的网:
训练网络后,提取一个计算嵌入的等效子网.
训练对嵌入网,从训练结果中提取嵌入网:
现在使用嵌入来可视化信号集合.
可视化计算嵌入空间中的测试数据集:
或者通过测量嵌入之间的距离来比较不同的录音.
绘制测试数据集中不同示例之间的距离矩阵:
使用学习嵌入定义 NearestFunction,并从示例中找到最近和最远的信号:

预训练的音频特征提取器

从头开始学习嵌入的替代方法是利用预训练的音频分析网络. Wolfram Neural Net Repository 是一个很好的资源.
AudioIdentify 使用深度神经网络作为后端来执行音频分类. 网络在 AudioSet 数据集上进行了训练,其中每个音频信号都使用录音中存在的声音类/源进行注释. 标签被组织在大约 600 个类的本体中,这些类跨越非常广泛的声音类型或来源,从乐器和音乐类型到动物,机械和人类声音.
导入 AudioIdentify 网并将其应用于 Audio 对象:
在 AudioIdentify 网中,信号被分成固定大小的块,并且主网被应用于每个块的梅尔频谱图. 使用 NetExtract 来获取它. 与 "CNN Architectures for Large-Scale Audio Classification" 中呈现的架构类似,主网络具有 CNN 架构(基于 MobileNet v2).
NetMapOperator 的核心提取网络:
AudioIdentify 中使用的网络不仅可用于识别声音,还可用于从录音中提取特征. 这允许任何信号嵌入在语义上有意义的空间中,其中可以计算相似性和距离.
可以删除负责分类任务的最后几个层,并且可以将生成的网络重新插入到原始 NetChain 中. 该网络将为每个音频输入产生一个固定大小,语义上有意义的向量. 它可以用作系统中所有高级机器学习功能的特征提取器,或者作为训练新神经网络的起点.
创建一个特征提取器网并在 FeatureSpacePlot 中使用它:
另一个替代方案是 "VGGish Feature Extractor Trained on YouTube Data" 模型,这是一个结构相似的网络,由谷歌专门用于音频特征提取的 YouTube 数据训练的.
使用 VGGish 网络作为 FeatureSpacePlot 中的特征提取器:
音频的转移学习
有时,可用于训练网络的数据量不足以完成手头的任务. 转移学习是解决这个问题的可能方法. 不是从头开始训练网络,而是可以使用已经在不同但相关的任务上训练的网络作为起点.
首先下载 ESC-50 数据集.
下载并解析 ESC-50 数据集:
使用 AudioIdentify 中的网络作为起点.
构建特征提取网络:
不是重新训练全网并在 NetTrain 中指定 LearningRateMultipliers 选项来仅训练分类层,而是预先计算特征提取器网的结果并训练分类器. 这避免了在训练期间对完整网络的冗余计算.
也可以将数据集划分为由其创建者定义的褶层.
预先计算特征并根据原始褶层划分数据集:
构建一个简单的循环分类器网络,该网络将附加到特征提取器并在每个褶层上训练它.
定义一个简单的循环分类器并在每个褶层上训练它:
在训练之后,很容易测量每个褶层上的分类器的准确度并对它们取平均值以获得交叉验证的结果.
测量每个褶层的性能并计算它们的平均值:
作为最终测试,构建一个连接原始特征提取器的网络和训练分类器的总体均值,并在不在原始数据集中的信号上运行它.
在一个不相关的例子上测试最终网络: