应用深度学习使用 Tensorflow 对音频进行分类

在视觉和语言领域的深度学习方面取得了很多进展,文中一步步说明当我们处理音频数据时,使用了哪些类型的模型和流程。

作者 / Dimitre Oliveira

原文链接 / https://pub.towardsai.net/a-g...

图片来源: https://www.tensorflow.org/tu...\_audio

最近在视觉和语言领域的深度学习方面取得了很多进展,能很直观地理解为什么CNN在图像上表现得很好,因为像素的局部相关,以及因为它具有顺序性,像RNN或转化器这样的顺序模型在语言上也表现得非常好。但音频呢?当我们处理音频数据时,使用了哪些类型的模型和流程?

在本文中,你将学习如何处理一个简单的音频分类问题。你将学习到一些常用的、有效的方法,以及Tensorflow代码来实现。

声明:本文给出的代码是基于我为“Rainforest Connection Species Audio Detection”Kaggle比赛开发的工作,但出于演示目的,我将使用“Speech Commands(语音指令)”数据集。

波形图

我们通常有".wav "格式的音频文件,它们通常被称为 waveforms(波形),它是一个时间序列,其中有每个特定时间的信号振幅,如果我们将这些波形样本之一可视化,会得到下图这样:

直觉上人们可能会考虑使用某种RNN模型对这些数据建模为一个常规时间序列(例如股票价格预测),事实上这可以做到,但由于我们使用的是音频信号,更合适的选择是将波形样本转化为声谱图。


声谱图

声谱图是波形信号的图像表示,它显示了其随时间变化的频率强度范围,它在想评估信号随时间变化的频率分布时非常有用。下图是上文中波形图像的声谱图表示。

x 轴是采样时间,y 轴是频率


语音命令用例

为了使本教程更简单,我们将使用“Speech Commands语音命令”数据集,该数据集有一秒钟的音频片段,带有 "下"、"走"、"左"、"不"、"右"、"停"、"上 "和 "是"等口语化的词语。


使用Tensorflow进行音频处理

现在我们已经知道了如何使用深度学习模型来处理音频数据,可以继续看代码实现,我们的流水线将遵循下图描述的简单工作流程:

简单的音频处理图

值得注意,在我们的用例的第1步,将数据直接从“. wav”文件中加载的,第3个步是可选的,因为音频文件每个只有一秒钟,因为文件较长裁剪音频可能是一个好主意,也是为了保持所有样本的固定长度。

加载数据

def load_dataset(filenames):
  dataset = tf.data.Dataset.from_tensor_slices(filenames)
  return dataset

load\_datasetv函数将负责加载.wav文件并将其转换为Tensorflow数据集。

提取波形和标签

commands = np.array(tf.io.gfile.listdir(str(data_dir)))
commands = commands[commands != 'README.md']def decode_audio(audio_binary):
  audio, _ = tf.audio.decode_wav(audio_binary)
  return tf.squeeze(audio, axis=-1)def get_label(filename):
  label = tf.strings.split(filename, os.path.sep)[-2]
  label = tf.argmax(label == commands)
  return labeldef get_waveform_and_label(filename):
  label = get_label(filename)
  audio_binary = tf.io.read_file(filename)
  waveform = decode_audio(audio_binary)
  return waveform, label

在加载.wav文件后,可以用tf.audio.decode\_wav函数来对它们进行解码,它将把.wav文件变成float tensor。接下来,我们需要从文件中提取标签,在这个特定的用例中,我们可以从每个样本的文件路径中获取标签,之后只需要对它们进行一次编码。

一个例子

首先,我们得到一个像这样的文件路径:

"data/mini_speech_commands/up/50f55535_nohash_0.wav"

然后提取第二个"/"后面的文本,在这种情况下,标签是UP,最后使用commands列表对标签进行一次编码。

Commands: ['up' 'down' 'go' 'stop' 'left' 'no' 'yes' 'right'] 


Label = 'up'


After one-hot encoding: 

Label = [1, 0, 0, 0, 0, 0, 0, 0]

将波形转换为声谱表

下一步是将波形文件转换为声谱图,幸运的是Tensorflow有一个函数可以做到这一点, tf.signal.stft应用短时Fourier变换(STFT)将音频转换为时频域,然后我们应用 tf.abs 算子去除信号相位,只保留幅值。注意,tf.signal.stft函数有一些参数,如frame\_length 和frame\_step,它们会影响生成的声谱图,我不会详细介绍如何调整它们,但你可以参考这个视频来了解更多。(:https://www.coursera.org/lect...

def get_spectrogram(waveform, padding=False, min_padding=48000):
  waveform = tf.cast(waveform, tf.float32)
  spectrogram = tf.signal.stft(waveform, frame_length=2048, frame_step=512, fft_length=2048)
  spectrogram = tf.abs(spectrogram)
  return spectrogramdef get_spectrogram_tf(waveform, label):
  spectrogram = get_spectrogram(waveform)
  spectrogram = tf.expand_dims(spectrogram, axis=-1)
  return spectrogram, label

将声谱图转化为RGB图像

最后一步是将声谱图转换为RGB图像,这一步是可选的,但这里我们将使用在ImageNet数据集上预训练的模型,该模型需要输入3个通道的图像。否则,你只可以保留一个通道的声谱图。

def prepare_sample(spectrogram, label):
  spectrogram = tf.image.resize(spectrogram, [HEIGHT, WIDTH])
  spectrogram = tf.image.grayscale_to_rgb(spectrogram)
  return spectrogram, label

将所有的东西结合起来

HEIGHT, WIDTH = 128, 128
AUTO = tf.data.AUTOTUNEdef get_dataset(filenames, batch_size=32):
  dataset = load_dataset(filenames)
    
  dataset = files_ds.map(get_waveform_and_label, num_parallel_calls=AUTO)
  dataset = dataset.map(get_spectrogram_tf, num_parallel_calls=AUTO)
  dataset = dataset.map(prepare_sample, num_parallel_calls=AUTO)  dataset = dataset.shuffle(256)
  dataset = dataset.repeat()
  dataset = dataset.batch(batch_size)
  dataset = dataset.prefetch(AUTO)
  return dataset

将所有东西集合在一起,有 get\_dataset 函数将文件名作为输入,在执行了上面描述的所有步骤后,返回一个带有RGB光谱图图像及其标签的Tensorflow数据集。


模型

def model_fn(input_shape, N_CLASSES):
  inputs = L.Input(shape=input_shape, name='input_audio')
  base_model = efn.EfficientNetB0(input_tensor=inputs, 
                                  include_top=False, 
                                  weights='imagenet')

  x = L.GlobalAveragePooling2D()(base_model.output)
  x = L.Dropout(.5)(x)
  output = L.Dense(N_CLASSES, activation='softmax',name='output')(x)
    
  model = Model(inputs=inputs, outputs=output)

  return model

我们的模型将有一个EfficientNetB0主干,在其顶部添加了一个GlobalAveragePooling2D,然后是一个Dropout,最后一个Dense层将进行实际的多类分类。

对于一个小的数据集,EfficientNetB0可能是一个很好的基线,即使是一个快速而轻巧的模型,它也有不错的准确性。


训练

model = model_fn((None, None, CHANNELS), N_CLASSES)model.compile(optimizer=tf.optimizers.Adam(), 
              loss=losses.CategoricalCrossentropy(), 
              metrics=[metrics.CategoricalAccuracy()])

model.fit(x=get_dataset(FILENAMES), 
          steps_per_epoch=100, 
          epochs=10)

训练代码对于Keras模型来说是非常标准的,所以你可能不会在这里找到任何新东西。


结论

现在你应该对将深度学习应用于音频文件的工作流程有了更清楚的了解,虽然这不是你能做到的唯一方法,但它是关于易用性和性能之间的权衡的最佳选择。如果你打算对音频进行建模,你可能还要考虑其他有前途的方法,如变压器。

作为额外的预处理步骤,截断或填充波形可能是一个好主意,如果你的样本有不同的长度,或者如果样本太长,只需要其中的一小部分,你可以在下面的参考资料部分找到如何做的代码。

参考文献

- Simple audio recognition: Recognizing keywords

https://www.tensorflow.org/tu...\_audio

- Rainforest-Audio classification Tensorflow starter

https://www.kaggle.com/dimitr...

- Rainforest-Audio classification TF Improved

https://www.kaggle.com/dimitr...

详情请扫描图中__二维码__或点击__阅读原文__了解大会更多信息。

248 声望
67 粉丝
0 条评论
推荐阅读
要能力、要稳定也要降本——百度多媒体技术回顾
摘要:多媒体技术生态进入到存量市场,客户既要又要还要成为常态。如何将能力、质量与稳定性、成本不断优化,就是各个多媒体技术平台的必修课。本文以百度智能视频云为例,纵览了其在RTC、边缘计算、视频编码等关...

LiveVideoStack

封面图
定档 6 月!SegmentFault AI Hackathon 杭州站启动
AI 掀起巨浪,你我应是冲浪者。创业团队、互联网大厂、国家队的大模型角力如火如荼,各类开源模型、垂直模型的出现也推动着越来越多 AGI 应用的陆续落地。

SegmentFault思否7阅读 59k评论 2

封面图
用 AI 生成漂亮小姐姐(一)——Stable Diffusion 小白搭建教程
最近 AIGC、ChatGPT 等话题持续发酵,热门程度不亚于之前的 “元宇宙”。抖音、小红书到处都是机器对话、AI 绘图的视频。我看见别人生成的漂亮小姐姐图片眼馋得不行,终于按捺不住自己的好奇心,也尝试一下搭建。本...

WalkerD15阅读 1.7k评论 3

Science AI 大潮已至,科技部亲自下场出大动作
生成式 AI 爆火,中国如何在 AI 时代实现弯道超车?对此,科技部亲自给出答案:启动 AI for Science 专项部署工作。可以预见,AI for Science 新一轮大潮即将来临。

超神经HyperAI3阅读 80k

封面图
TOPI 简介
这是 TVM 算子清单(TOPI)的入门教程。 TOPI 提供了 numpy 风格的通用操作和 schedule,其抽象程度高于 TVM。本教程将介绍 TOPI 是如何使得 TVM 中的代码不那么样板化的。

超神经HyperAI1阅读 90.7k

编译 MXNet 模型
本篇文章译自英文文档 Compile MXNet Models。作者是 Joshua Z. Zhang,Kazutaka Morita。更多 TVM 中文文档可访问 →TVM 中文站。本文将介绍如何用 Relay 部署 MXNet 模型。首先安装 mxnet 模块,可通过 pip 快速...

超神经HyperAI1阅读 61.1k

横向对比 11 种算法,多伦多大学推出机器学习模型,加速长效注射剂新药研发
内容一览:长效注射剂是解决慢性病的有效药物之一,不过,该药物制剂的研发耗时、费力,颇具挑战。对此,多伦多大学研究人员开发了一个基于机器学习的模型,该模型能预测长效注射剂药物释放速率,从而提速药物整...

超神经HyperAI1阅读 50k

封面图
248 声望
67 粉丝
宣传栏