TensorFlow案例学习:简单的音频识别

前言

以下内容均来源于官方教程:简单的音频识别:识别关键字

音频识别

下载数据集

下载地址:http://storage.googleapis.com/download.tensorflow.org/data/mini_speech_commands.zip

可以直接浏览器访问下载。
在这里插入图片描述
下载完成后将其解压到项目里,从文件夹里可以看到有8个子文件夹,文件夹的名称就是8个语音命令。
在这里插入图片描述
注意:我们只需要mini_speech_commands文件夹,其他的不需要
在这里插入图片描述

加载数据集

# 加载训练数据集、验证集
train_ds, val_ds = tf.keras.utils.audio_dataset_from_directory(directory='./data/mini_speech_commands',  # 数据集路径batch_size=64,  # 批次validation_split=0.2,  # 验证集占数据集的20%seed=0,  # 指定随机生成数据集的种子# 每个样本的输出序列长度。音频剪辑在 1kHz 时为 16 秒或更短。将较短的填充到正好 1 秒(并且会修剪较长的填充),以便可以轻松批量处理output_sequence_length=16000,subset='both'  # 训练集和验证集两者同时使用
)

获取类别

# 获取命令的类别
label_names = np.array(train_ds.class_names)
print("命令类别:", label_names)

在这里插入图片描述
刚好与子文件的名称和顺序一致。

维度压缩

文档中说,此数据集仅包含单声道音频,因此需要 对输入的音频数据进行维度压缩

  • 单声道(mono)音频只有一个声道。这意味着所有的音频信号被混合到一个通道中,不区分左右声道。在单声道音频中,所有的声音通过单个扬声器播放。单声道音频适用于大部分音频应用,如电话通信、语音录音等。

  • 多声道(stereo)音频有两个声道,左声道(left channel)和右声道(right channel)。通过左右声道的不同信号,可以在音频空间上创建立体声效果。多声道音频提供了更加丰富的音频体验,可以更好地模拟现实环境中的声音分布。常见的应用包括音乐播放、电影声音、游戏音效等。

def squeeze(audio,labels):audio = tf.squeeze(audio,axis=-1)return audio,labelstrain_ds = train_ds.map(squeeze,tf.data.AUTOTUNE)
val_ds = val_ds.map(squeeze,tf.data.AUTOTUNE)

拆分验证集
这块没太看明白在干嘛

test_ds = val_ds.shard(num_shards=2, index=0)
val_ds = val_ds.shard(num_shards=2, index=1)
for example_audio, example_labels in train_ds.take(1):print(example_audio.shape)print(example_labels.shape)

绘制音频波形
这块只是让我们可视化的观察音频的波形,这块后面可以注释掉

plt.figure(figsize=(8, 5))
rows = 3
cols = 3
n = rows * cols
for i in range(n):plt.subplot(rows, cols, i+1)audio_signal = example_audio[i]plt.plot(audio_signal)plt.title(label_names[example_labels[i]])plt.yticks(np.arange(-1.2, 1.2, 0.2))plt.ylim([-1.1, 1.1])
plt.tight_layout()
plt.show()

在这里插入图片描述

将波形转换为频谱图

将波形转换为频谱图的目的是为了更好地分析和理解音频信号。

波形是时域上的表示,它展示了音频信号在时间轴上的变化。然而,频谱图是频域上的表示,它将音频信号分解为不同的频率成分,并显示每个频率成分的能量或振幅。

通过将波形转换为频谱图,我们可以更清晰地看到音频信号中哪些频率成分对于特定的声音或事件是重要的。这对于音频处理任务(如语音识别、音频分类、音频分割等)以及音频信号理解和分析非常有帮助。

def get_spectrogram(waveform):spectrogram = tf.signal.stft(waveform, frame_length=255, frame_step=128)spectrogram = tf.abs(spectrogram)spectrogram = spectrogram[..., tf.newaxis]return spectrogram

浏览数据
打印一个示例的张量化波形和相应频谱图的形状,并播放原始音频:

for i in range(3):label = label_names[example_labels[i]]waveform = example_audio[i]spectrogram = get_spectrogram(waveform)print('Label:', label)print('Waveform shape:', waveform.shape)print('Spectrogram shape:', spectrogram.shape)print('Audio playback')display.display(display.Audio(waveform, rate=16000))

从音频数据集创建频谱图数据集

# 从音频数据集创建频谱图数据集
def make_spec_ds(ds):return ds.map(map_func=lambda audio,label: (get_spectrogram(audio), label),num_parallel_calls=tf.data.AUTOTUNE)train_spectrogram_ds = make_spec_ds(train_ds)
val_spectrogram_ds = make_spec_ds(val_ds)
test_spectrogram_ds = make_spec_ds(test_ds)

减少训练模型时的读取延迟

train_spectrogram_ds = train_spectrogram_ds.cache().shuffle(10000).prefetch(tf.data.AUTOTUNE)
val_spectrogram_ds = val_spectrogram_ds.cache().prefetch(tf.data.AUTOTUNE)
test_spectrogram_ds = test_spectrogram_ds.cache().prefetch(tf.data.AUTOTUNE)

使用卷积神经网络创建并训练模型

# 使用卷积神经网络创建模型
input_shape = example_spectrograms.shape[1:]
print('Input shape:', input_shape)
num_labels = len(label_names)
norm_layer = tf.keras.layers.Normalization()  # 创建规范化层,便于更好的进行模型训练和推断
norm_layer.adapt(data=train_spectrogram_ds.map(map_func=lambda spec, label: spec))model = tf.keras.models.Sequential([tf.keras.layers.Input(shape=input_shape),tf.keras.layers.Resizing(32, 32),norm_layer,tf.keras.layers.Conv2D(32, 3, activation='relu'),tf.keras.layers.Conv2D(64, 3, activation='relu'),tf.keras.layers.MaxPool2D(),tf.keras.layers.Dropout(0.25),tf.keras.layers.Flatten(),tf.keras.layers.Dense(128, activation='relu'),tf.keras.layers.Dropout(0.5),tf.keras.layers.Dense(num_labels),
])model.summary()# 编译模型
model.compile(optimizer=tf.keras.optimizers.Adam(),  # 优化器loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),  # 损失函数metrics=['accuracy']  # 准确率作为评估标准
)# 训练模型,并记录训练的日志
history = model.fit(train_spectrogram_ds,validation_data=val_spectrogram_ds,epochs=10,callbacks=tf.keras.callbacks.EarlyStopping(verbose=1, patience=2),
)

在这里插入图片描述
评估性能

model.evaluate(test_spectrogram_ds, return_dict=True)

导出模型

class ExportModel(tf.Module):def __init__(self, model):self.model = model# Accept either a string-filename or a batch of waveforms.# YOu could add additional signatures for a single wave, or a ragged-batch.self.__call__.get_concrete_function(x=tf.TensorSpec(shape=(), dtype=tf.string))self.__call__.get_concrete_function(x=tf.TensorSpec(shape=[None, 16000], dtype=tf.float32))@tf.functiondef __call__(self, x):# If they pass a string, load the file and decode it.if x.dtype == tf.string:x = tf.io.read_file(x)x, _ = tf.audio.decode_wav(x, desired_channels=1, desired_samples=16000,)x = tf.squeeze(x, axis=-1)x = x[tf.newaxis, :]x = get_spectrogram(x)result = self.model(x, training=False)class_ids = tf.argmax(result, axis=-1)class_names = tf.gather(label_names, class_ids)return {'predictions': result,'class_ids': class_ids,'class_names': class_names}export = ExportModel(model)
export(tf.constant('./data/mini_speech_commands/no/012c8314_nohash_0.wav'))tf.saved_model.save(export, "saved")

下面是保存的模型
在这里插入图片描述
完整代码

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from IPython import display# 加载训练数据集、验证集
train_ds, val_ds = tf.keras.utils.audio_dataset_from_directory(directory='./data/mini_speech_commands',  # 数据集路径batch_size=64,  # 批次validation_split=0.2,  # 验证集占数据集的20%seed=0,  # 指定随机生成数据集的种子# 每个样本的输出序列长度。音频剪辑在 1kHz 时为 16 秒或更短。将较短的填充到正好 1 秒(并且会修剪较长的填充),以便可以轻松批量处理output_sequence_length=16000,subset='both'  # 训练集和验证集两者同时使用
)# 获取命令的类别
label_names = np.array(train_ds.class_names)
print("命令类别:", label_names)# 输入数据压缩def squeeze(audio, labels):audio = tf.squeeze(audio, axis=-1)return audio, labelstrain_ds = train_ds.map(squeeze, tf.data.AUTOTUNE)
val_ds = val_ds.map(squeeze, tf.data.AUTOTUNE)# 拆分验证集
test_ds = val_ds.shard(num_shards=2, index=0)
val_ds = val_ds.shard(num_shards=2, index=1)for example_audio, example_labels in train_ds.take(1):print(example_audio.shape)print(example_labels.shape)# 绘制音频波形
# plt.figure(figsize=(8, 5))
# rows = 3
# cols = 3
# n = rows * cols
# for i in range(n):
#     plt.subplot(rows, cols, i+1)
#     audio_signal = example_audio[i]
#     plt.plot(audio_signal)
#     plt.title(label_names[example_labels[i]])
#     plt.yticks(np.arange(-1.2, 1.2, 0.2))
#     plt.ylim([-1.1, 1.1])
# plt.tight_layout()
# plt.show()# 将波形转换为频谱图
def get_spectrogram(waveform):spectrogram = tf.signal.stft(waveform, frame_length=255, frame_step=128)spectrogram = tf.abs(spectrogram)spectrogram = spectrogram[..., tf.newaxis]return spectrogram# 浏览数据
for i in range(3):label = label_names[example_labels[i]]waveform = example_audio[i]spectrogram = get_spectrogram(waveform)print('Label:', label)print('Waveform shape:', waveform.shape)print('Spectrogram shape:', spectrogram.shape)print('Audio playback')display.display(display.Audio(waveform, rate=16000))# 从音频数据集创建频谱图数据集def make_spec_ds(ds):return ds.map(map_func=lambda audio, label: (get_spectrogram(audio), label),num_parallel_calls=tf.data.AUTOTUNE)train_spectrogram_ds = make_spec_ds(train_ds)
val_spectrogram_ds = make_spec_ds(val_ds)
test_spectrogram_ds = make_spec_ds(test_ds)# 检查数据集的不同示例的频谱图
for example_spectrograms, example_spect_labels in train_spectrogram_ds.take(1):break# 减少训练模型时的读取延迟
train_spectrogram_ds = train_spectrogram_ds.cache().shuffle(10000).prefetch(tf.data.AUTOTUNE)
val_spectrogram_ds = val_spectrogram_ds.cache().prefetch(tf.data.AUTOTUNE)
test_spectrogram_ds = test_spectrogram_ds.cache().prefetch(tf.data.AUTOTUNE)# 使用卷积神经网络创建模型
input_shape = example_spectrograms.shape[1:]
print('Input shape:', input_shape)
num_labels = len(label_names)
norm_layer = tf.keras.layers.Normalization()  # 创建规范化层,便于更好的进行模型训练和推断
norm_layer.adapt(data=train_spectrogram_ds.map(map_func=lambda spec, label: spec))model = tf.keras.models.Sequential([tf.keras.layers.Input(shape=input_shape),tf.keras.layers.Resizing(32, 32),norm_layer,tf.keras.layers.Conv2D(32, 3, activation='relu'),tf.keras.layers.Conv2D(64, 3, activation='relu'),tf.keras.layers.MaxPool2D(),tf.keras.layers.Dropout(0.25),tf.keras.layers.Flatten(),tf.keras.layers.Dense(128, activation='relu'),tf.keras.layers.Dropout(0.5),tf.keras.layers.Dense(num_labels),
])model.summary()# 编译模型
model.compile(optimizer=tf.keras.optimizers.Adam(),  # 优化器loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),  # 损失函数metrics=['accuracy']  # 准确率作为评估标准
)# 训练模型,并记录训练的日志
history = model.fit(train_spectrogram_ds,validation_data=val_spectrogram_ds,epochs=10,callbacks=tf.keras.callbacks.EarlyStopping(verbose=1, patience=2),
)# 评估性能
model.evaluate(test_spectrogram_ds, return_dict=True)# 导出模型class ExportModel(tf.Module):def __init__(self, model):self.model = modelself.__call__.get_concrete_function(x=tf.TensorSpec(shape=(), dtype=tf.string))self.__call__.get_concrete_function(x=tf.TensorSpec(shape=[None, 16000], dtype=tf.float32))@tf.functiondef __call__(self, x):if x.dtype == tf.string:x = tf.io.read_file(x)x, _ = tf.audio.decode_wav(x, desired_channels=1, desired_samples=16000,)x = tf.squeeze(x, axis=-1)x = x[tf.newaxis, :]x = get_spectrogram(x)result = self.model(x, training=False)class_ids = tf.argmax(result, axis=-1)class_names = tf.gather(label_names, class_ids)return {'predictions': result,'class_ids': class_ids,'class_names': class_names}export = ExportModel(model)
export(tf.constant('./data/mini_speech_commands/no/012c8314_nohash_0.wav'))tf.saved_model.save(export, "saved")

加载使用导出的模型

使用模型预测down的音频

import tensorflow as tf# 直接加载模型的目录
new_model = tf.saved_model.load("./saved")
res = new_model('./data/mini_speech_commands/down/004ae714_nohash_0.wav')
print("结果:",res)class_names = ['down', 'go', 'left', 'no', 'right', 'stop', 'up', 'yes']
class_index = res['class_ids'].numpy()[0]
class_name = class_names[class_index]
print("类别名称:", class_name)

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/156302.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

libgdx实现淡入淡出过渡

libgdx实现淡入淡出过渡 libgdx实现淡入淡出过渡&#xff0c;环境jdk17、libgdx 1.12.02023年11月1日11:02:50最新 依赖 <properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target>&…

LV.12 D13 UART实验 学习笔记

一、UART帧格式详解 UART Universal Asynchronous Receiver Transmitter 即 通用异步收发器&#xff0c;是一种通用的串行、异步通信总线 该总线有两条数据线&#xff0c;可以实现全双工的发送和接收&#xff0c;在嵌入式系统中常用于主机与辅助设备之间的通信。 通…

Day42 力扣动态规划 :123.买卖股票的最佳时机III |188.买卖股票的最佳时机IV

Day42 力扣动态规划 :123.买卖股票的最佳时机III &#xff5c;188.买卖股票的最佳时机IV 123.买卖股票的最佳时机III第一印象看完题解的思路dp数组&#xff1a;递推公式&#xff1a;初始化遍历顺序 实现中的困难感悟代码 188.买卖股票的最佳时机IV第一印象初始化递推公式看完题…

算法通过村第十八关-回溯|青铜笔记|什么叫回溯(后篇)

文章目录 前言回溯热身问题输出二叉树的所有路径&#xff1a;路径总和问题&#xff1a; 总结 前言 提示&#xff1a;今夜思量千条路&#xff0c;明朝依旧卖豆腐。 --谚语 回溯是非常重要的算法思想之一&#xff0c;主要解决一些暴力枚举也搞不定的问题&#xff08;这里埋个坑&a…

汽车配件商城小程序制作 | 汽车配件售卖,高门槛但高利润

通过汽车配件商城小程序给别人的供货&#xff0c;利润可高达60%&#xff0c;但甚少有人关注汽车配件销售的行业。具体情况是怎么样的呢&#xff0c;下面给大家简单分析。 据数据显示&#xff0c;国内有4亿多辆汽车&#xff0c;这些汽车坏了要修&#xff0c;也要偶尔进行保养&am…

集成测试、单元测试、系统测试之间的关系和区别

前言 为了使软件正常工作&#xff0c;所有单元都应集成在一起并正常运行。集成测试就像是要求不同工种的工人修建一个房子&#xff0c;希望他们都团结协作。如何判断他们在一起是否可以按照计划完成建设呢&#xff1f;唯一了解的方法是通过将它们全部拉在一起并测试它们如何相互…

正则表达式续篇

位置锚定&#xff1a; ^:行首锚定&#xff0c;表示以什么为开头 例如&#xff1a; $:行尾锚定&#xff0c;表示以什么为结尾 例如&#xff1a; ^&#xff1a;匹配的是空行 例如&#xff1a; ^root$&#xff1a;匹配整行&#xff0c;而且整行只能有这一个字符串 实验&#x…

百度地图直接用的封装好的--自用vue的(每次项目都要有百度地图,还是搞个封装的差不多的以后可以直接拿来用)

自用的封装好的,有弹窗,轨迹回放,画点画地图 完整代码使用 百度地图的官方文档 百度地图必须的三个引用 完整代码 <template><AButton style"background-color: #3ba7ea;color: white;width: 100px;float: right" click"buttonClick">轨迹回放…

chatgpt接口调用

在线接口文档&#xff1a; https://app.apifox.com/invite?tokensymrLP7sojF6N31kZqnpZ 接口地址 https://chat.xutongbao.top/api/light/chat/createChatCompletion 请求方式 POST 请求参数 token String, 必须 prompt Array, 必须 例子一&#xff1a; 包含上下文 [ { "…

报修软件有什么用?企业如何做好设备管理与维护?

在当今的商业环境中&#xff0c;设备设施的维护和管理已经成为企业运营的重要环节。无论是学校、酒店、物业等大型企事业单位&#xff0c;还是运维集成商、制造工厂等企业单位&#xff0c;都需要对设备设施进行有效的管理。报修软件作为一种智能化的解决方案&#xff0c;为设备…

codeMirror代码编辑器,如何定位并在编辑区域输入内容

背景 最近在写UI自动化&#xff0c;发现普通的方法不能在CodeMirror编辑器里面输入内容&#xff0c;只能通过JS的方式输入内容。 于是琢磨了一下selenium和playwright这2种自动化工具&#xff0c;在CodeMirror编辑器里面输入内容的差别。 注意&#xff1a;这里在定位CodeMirr…

人脸检索 M:N(视频,摄像头),调用百度API

目录 创建百度智能云账号 代码部分&#xff1a; 创建百度智能云账号 网址&#xff1a; 百度智能云-云智一体深入产业 点击导航栏中的产品&#xff0c;再选择人脸与人体 再选择人脸搜索 进入后&#xff0c;可以先去领取免费资源&#xff0c;如果不领取&#xff0c;后面是无法…