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,labels

train_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.function
    def __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, labels


train_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 = model

        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.function
    def __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)

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

博彦科技:以金融为起点,凭借创新技术平台真打实干

【科技明说 | 重磅专题】 成立于1995年的博彦科技,已有28年左右的发展历程。 我没有想到,博彦科技也对AIGC领域情有独钟。博彦科技自研的数字人产品SaaS平台,可以接入包括百度文心一言、阿里通义千问等AI大模型产品。可见&#…

uniapp开发微信小程序uview里的u-upload组件上传图片点击没反应,开发者工具点击正常,正式上手机上点击没反应

项目场景: 用uniapp开发的微信小程序,uview插件ui,u-upload上传文件,上传头像等方法,早就审核发布过的突然反应上传图片,文件啥的点击没反应 问题描述 原因分析: 根据查资料得知可能是因为小程…

赛宁网安多领域创新成果亮相第五届“纵横”论坛

10月27日,第五届“纵横”网络空间安全创新论坛在安徽合肥举办,来自中央国家机关、地方政府、军队有关单位、高校、科研院所和部分高新技术企业的领导、专家和代表500余人参加。 本届论坛由军事科学院和国防科技大学等单位共同主办,国防科技大…

[微信小程序踩坑]微信小程序editor富文本组件渲染字符串时,内部图片超出大小导致无法正常渲染或回显(数据传输长度为 3458 KB,存在有性能问题!)

坑一&#xff1a;回显问题 富文本组件&#xff1a; <editor id"editor" name"{{name}}" style"font-size: 28rpx;color: #C9CDD4" read-only"{{true}}" placeholder"{{placeholder}}" bind:input"onChange11"…

股权比例设计的九条生命线

股权比例设计——绝对控制线67% 【释义】一些重大事项如公司的股本变化&#xff0c;关于公司的增减资&#xff0c;修改公司章程&#xff0c; 分立/合并、变更主营项目等重大决策&#xff0c;需要2/3以上&#xff08;含2/3&#xff09;票数支持的。 股权比例设计——相对控制线…

18、SpringCloud -- 沙箱环境测试支付宝支付

目录 沙箱环境测试支付宝支付下载安装密钥:安装:生成密钥:沙箱环境配置支付宝SDK配置下载SDK&DEMO支付宝SDK导入支付宝SDK配置配置tomcat访问端口占用问题:解决方法:1、旧版沙箱配置-成功旧版沙箱自定义密钥2、新版沙箱配置-失败测试:1、点击付款2、模拟登录买家的账…

一文读懂什么是新一代BPM

什么是BPM 业务流程管理 (Business Process Management&#xff0c;简称BPM)&#xff0c;是一门学科&#xff0c;它通过分析、建模、执行、监控、优化等流程来改进业务流程&#xff0c;使企业核心业务流程最优化。BPM系统即根据业务环境的变化&#xff0c;推进人与人之间、人与…

如何用ChatGPT快速写出一份合格的PPT报告

我们【AI写稿专家】的小伙伴中有很多企业高管和公务员&#xff0c;大家经常有写报告写ppt的需求&#xff0c;下面小编给大家介绍一下我们新发布生成PPT的功能&#xff0c;很简单很方便&#xff0c;看完大家不到1分钟就能生成一份拿得出手的PPT报告&#xff0c;再也不用费尽心思…

编程实例:操作简单物流快运单据打印软件,可以定制打印格式

编程实例&#xff1a;操作简单物流快运单据打印软件&#xff0c;可以定制打印格式 打印格式可以定制。 编程系统化课程总目录及明细&#xff0c;零基础学编程视频教程&#xff0c;点击进入了解详情。 https://blog.csdn.net/qq_29129627/article/details/134073098?spm1001.20…

《云计算白皮书(2023年)》丨三叠云

✦ ✦✦ ✦✦ ✦✦ ✦ 这是中国信息通信研究院第九次发布云计算白皮书。本次白皮书聚焦过去一年多来云计算产业的新发展新变化&#xff0c;总结梳理国内外云计算政策、市场、技术、应用等方面的发展特点&#xff0c;并对未来发展进行展望。【目 录】 一、全球云计算发展概述…

如何创建 Spring Boot 项目

如果有pom.xml有插件异常&#xff0c;可以先删除。 maven配置要配置好 然后yaml&#xff0c;再启动就行 server:port: 9991 spring:application:name: demo3参考 如何创建 Spring Boot 项目_创建springboot项目_良月初十♧的博客-CSDN博客

k8spod

pod基本概念 (几种容器) pod 是k8s最小的创建和运行单元 一个pod包含几个容器&#xff0c;1个根容器/父容器/基础容器&#xff0c;一个或者多个应用容器/业务容器&#xff0c;pause容器 pod里面容器共享 network UTS IPC命令空间 k8s 创建的Pod 分为两种&#xff1a; 自主…

高阶数据结构学习 —— 图(3)

文章目录 1、最小生成树概念2、Kruskal算法3、Prim算法 1、最小生成树概念 先看一下连通图和生成树的概念 连通图。在无向图中&#xff0c;若从顶点v1到顶点v2有路径&#xff0c;则称顶点v1与顶点v2是连通的。如果图中任意一对顶点都是连通的&#xff0c;则称此图为连通图。 生…

软件产品如何进行跨浏览器测试?

跨浏览器测试是确保Web应用程序的功能在不同浏览器、浏览器版本和操作系统之间保持一致的过程&#xff0c;从而为其用户提供轻松的用户体验。跨浏览器测试涉及浏览器和操作系统的组合&#xff0c;以测试应用程序的响应能力和兼容性。 一、跨浏览器测试的作用   1、发现兼容性…

vite+vue3路由切换滚动条位置重置el-scrollbar

vitevue3路由切换滚动条位置重置 本文目录 vitevue3路由切换滚动条位置重置使用原生滚动条使用el-scrollbaruseRoute和useRouter 当切换到新路由时&#xff0c;想要页面滚到顶部&#xff0c;或者是保持原先的滚动位置&#xff0c;就像重新加载页面那样&#xff0c;vue-router 可…

玻色量子成功研制光量子计算专用光纤恒温控制设备——“量晷”

​近日&#xff0c;北京玻色量子科技有限公司&#xff08;以下简称“玻色量子”&#xff09;成功研制出一款高精度量子计算专用光纤恒温控制设备——“量晷”&#xff0c;该设备能将光纤的温度变化稳定在千分之一摄氏度量级&#xff0c;即能够做到0.001C的温度稳定维持&#xf…

贪心算法学习------优势洗牌

目录 一&#xff0c;题目 二&#xff0c;题目接口 三&#xff0c;解题思路和代码 全部代码&#xff1a; 一&#xff0c;题目 给定两个数组nums1和nums2,nums1相对于nums2的优势可以用满足nums1[i]>nums2[i]的索引i的数目来描述。 返回nums1的任意排序&#xff0c;使其优…

视频监控平台EasyCVR分组接口出现“pending”报错,该如何解决?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台可拓展性强、视频能力灵活&#xff0c;能对外分发RTMP、RTSP、…

高级工技能等级认定---网络设备安全

目录 一、DHCP 安全配置 二、SSH配置 三、标准ACL的配置 四、配置交换机端口安全 五、三层交换和ACL的配置 一、DHCP 安全配置 配置要求&#xff1a; 1.给交换机配置enable密码. 2.在交换机上创建VLAN 100&#xff0c;将F0/1-3口改为Access口&#xff0c;并加入到VLAN …

C++——多态

作者&#xff1a;几冬雪来 时间&#xff1a;2023年10月31日 内容&#xff1a;C部分多态内容讲解 目录 前言&#xff1a; 什么是多态&#xff1a; 虚函数&#xff1a; 协变&#xff1a; c11中override和final&#xff1a; final&#xff1a; override&#xff1a; 重…