基于深度学习的声音分类

前言

今天花了一天时间来复现哭声识别,从网上找了很多资料发现整合起来还是比较困难的。这里我做一下笔记方便后面的学习,希望对大家也有一定的帮助。

基础知识

音频与我们生活有着十分联系。 我们的大脑不断处理和理解音频数据,并为您提供有关环境的信息。 一个简单的例子就是你每天与人交谈。 这个演讲被另一个人看出来进行讨论。 即使你认为自己处于一个安静的环境中,你也会听到更微妙的声音,比如树叶的沙沙声或雨水的飞溅。 这是您与音频连接的程度。所以你能以某种方式抓住你周围的音频,做一些有建设性的事情吗? 当然是! 有一些设备可以帮助您捕获这些声音并以计算机可读格式表示。 这些格式是:

  • wav(波形音频文件)格式

  • mp3(MPEG-1 Audio Layer 3)格式

  • WMA(Windows Media Audio)格式

    音频处理的是目前深度学习应用做火热的方向之一,虽然我们讨论过音频数据可用于分析。 但是音频处理的潜在应用是什么? 在这里,我将列出其中的一些:

  • 根据音频功能索引音乐集

  • 推荐用于广播频道的音乐

  • 相似性搜索音频文件(又名Shazam)

  • 语音处理和合成 - 为会话代理生成人工语音

当我们对音频数据进行采样时,我们需要更多的数据点来表示整个数据,并且采样率应该尽可能高。另一方面,如果我们在频域中表示音频数据,则需要更少的计算空间。

实战

​ 传统的语音识别技术,主要在隐马尔可夫模型和高斯混合模型两大”神器“的加持之下,取得了不错的成绩。但是深度学习算法后来者居上,节省了原先耗费在特征提取上的时间,甚至可以直接进行端到端的语音识别任务,大有燎原之势。本文主要借助 python 的音频处理库 librosa 和非常适合小白使用的深度学习库 keras。通过调用他们的 api ,我们可以快速地实现语音分类任务。

1.准备数据集

​ 我们通过一个实际的案例进行实战,首先我在github上下载了哭声数据集https://github.com/gveres/donateacry-corpus/tree/master/donateacry-android-upload-bucket,然后又使用了一些其他的城市声音数据集,整体加起来有1000个。在此数据基础上做了一些工作。数据集截图如下,baby目录下存放了457个音频数据,others下存放了大致相同的数据。

2.排序

通过自己编写的排序代码对文件夹下的文件进行统一命名。代码如下:

import sysimport osdef rename(pic_path):piclist=os.listdir(pic_path)i=1print("ok")for pic in piclist:if pic.endswith(".wav"):old_path=os.path.join(os.path.abspath(pic_path),pic)new_path=os.path.join(os.path.abspath(pic_path),str(1000+(int(i)))+'.wav')#这里对两个目录下文件进行排序,第一个我设置成1001这种,第二个others目录下设置成了9001这种。os.renames(old_path,new_path)print ("把原命名格式:"+old_path+u"转换为新命名格式:"+new_path)i=i+1if __name__ == '__main__':rename("./data/babytest/")

3.添加数据标签

首先大家要下载来的音频文件保存在一个固定的文件夹中,比如取名为“data”。我们通过函数os.listdir,获取“./data/”文件夹中所有的音频的类别,这些标签就是我们需要分类的目标。

# 加载标签def load_label(label_path):label = os.listdir(label_path)return label

4.提取mfcc系数

​ mfcc 系数,全称“Mel Frequency Cepstrum Coefficient”,音译为:梅尔频率倒谱系数,是模仿人类听觉特性而提取的特征参数,主要用于特征提取和降维处理。就像主成分分析方法(PCA),可以将高维度的数据压缩到低维,从而起到减小计算量以及过滤噪声的目的。拿我们这次的音频为例,我们选取了 5000 多个采样点 ,经过提取 mfcc 系数,得到 20 * 11 的矩阵,大大减小了计算量。

​ 首先,第一个函数 librosa.load用于读取音频文件,path 为音频路径,sr 为采样率(也就是一秒钟采样点的个数),设置为None,就按音频本身的采样率进行读取。mono 为双声道,我们读取的音频都是双声道的(注意,有些是单声道),所以也要设置为True。其次,我们并不需要这么高的采样率,所以就每三个选取一个采样点,y=y[::3]。

如何提取 mfcc 参数呢?传统的语音识别预处理,要经过 分帧>>加窗>>快速傅里叶变换 等一系列操作,才能提取 mfcc 参数。但是呢,我们可以调用 librosa.feature.mfcc方法,快速提取 mfcc 系数,毕竟我们只是简单地熟悉下语音处理的流程。这里要注意的是,由于我们拿到的音频文件,持续时间都不尽相同,所以提取到的 mfcc 大小是不相同的。但是神经网络要求待处理的矩阵大小要相同,所以这里我们用到了铺平操作。我们 mfcc 系数默认提取 20 帧,对于每一帧来说,如果帧长小于 11,我们就用 0 填满不满足要求的帧;如果帧长大于 11,我们就只选取前 11 个参数。我们用到的函数numpy.pad(array, pad_width, mode),其中 array 是我们需要填充的矩阵,pad_width是各个维度上首尾填充的个数。举个例子,假定我们设置的 pad_width 是((0,0), (0,2)),而待处理的 mfcc 系数是 20 * 11 的矩阵。我们把 mfcc 系数看成 20 行 11 列的矩阵,进行 pad 操作,第一个(0,0)对行进行操作,表示每一行最前面和最后面增加的数个数为零,也就相当于总共增加了 0 列。第二个(0,2)对列操作,表示每一列最前面增加的数为 0 个,但最后面要增加两个数,也就相当于总共增加了 2 行。mode 设置为 ‘constant’,表明填充的是常数,且默认为 0 。

# 提取 mfcc 参数
def wav2mfcc(path, max_pad_size=11):y, sr = librosa.load(path=path, sr=None, mono=1)y = y[::3]  #每三个点选用一个audio_mac = librosa.feature.mfcc(y=y, sr=16000)y_shape = audio_mac.shape[1]if y_shape < max_pad_size:pad_size = max_pad_size - y_shapeaudio_mac = np.pad(audio_mac, ((0, 0), (0, pad_size)), mode='constant')else:audio_mac = audio_mac[:, :max_pad_size]return audio_mac

5.数据预保存

​ 首先建立两个列表,分别用来存储 mfcc 系数和相应的标签(也就是 baby,other)。然后每提取到一个 mfcc 参数就把它添加到 mfcc_vectors 中,并且在 target 中存储它的标签名。当我们把2个文件夹所有的音频文件 全部处理完毕后,我们要把数据存储用 npy(numpy 矩阵的存储格式) 格式存储起来。这样方便程序下次的快速启动,不用预先花太多时间加载数据。

def save_data_to_array(label_path, max_pad_size=11):mfcc_vectors = []target = []labels = load_label(label_path=label_path)for i, label in enumerate(labels):path = label_path + '/' + labelwavfiles = [path + '/' + file for file in os.listdir(path)]for wavfile in wavfiles:wav = wav2mfcc(wavfile, max_pad_size=max_pad_size)mfcc_vectors.append(wav)target.append(i)np.save(DATA, mfcc_vectors)np.save(TARGET, target)

6.训练模型

将之前的处理代码整合起来,总结一下:首先主函数调用save_data_to_array("./data/", max_pad_size=11) 将当前目录中data下的两个数据集保存成npy格式。接着我们要使用get_train_test()为神经网络准备训练集和测试集了。我们借助 sklearn 中的train_test_split,把数据集分为训练集和验证集。其中训练集占 6 成,测试集占 4 成。shuffle 是指随机打乱数据集,以获得无序的数据集。之后改变 mfcc 系数的 shape,使它变成二维矩阵且第二个维度大小为 220。其次,我们要用到 keras 的One-hot 编码。举个例子,原先的标签为‘baby’,‘others’,,经过编码,凡是对应标签,就编码成 1,反之编码成 0。这里我们使用了很简单了CNN模型进行训练。

import os
import keras
import librosa
import numpy as np
import matplotlib.pyplot as plt
from keras import Sequential
from keras.utils import to_categorical
from keras.layers import Dense
from sklearn.model_selection import train_test_splitDATA = 'data.npy'
TARGET = 'target.npy'# 加载标签
def load_label(label_path):label = os.listdir(label_path)return label# 提取 mfcc 参数
def wav2mfcc(path, max_pad_size=11):y, sr = librosa.load(path=path, sr=None, mono=1)y = y[::3]  #每三个点选用一个audio_mac = librosa.feature.mfcc(y=y, sr=16000)y_shape = audio_mac.shape[1]if y_shape < max_pad_size:pad_size = max_pad_size - y_shapeaudio_mac = np.pad(audio_mac, ((0, 0), (0, pad_size)), mode='constant')else:audio_mac = audio_mac[:, :max_pad_size]return audio_mac# 存储处理过的数据,方便下一次的使用
def save_data_to_array(label_path, max_pad_size=11):mfcc_vectors = []target = []labels = load_label(label_path=label_path)for i, label in enumerate(labels):path = label_path + '/' + labelwavfiles = [path + '/' + file for file in os.listdir(path)]for wavfile in wavfiles:wav = wav2mfcc(wavfile, max_pad_size=max_pad_size)mfcc_vectors.append(wav)target.append(i)np.save(DATA, mfcc_vectors)np.save(TARGET, target)# return mfcc_vectors, target# 获取训练集与测试集
def get_train_test(split_ratio=.6, random_state=42):X = np.load(DATA)y = np.load(TARGET)assert X.shape[0] == y.shape[0]X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=(1 - split_ratio), random_state=random_state,shuffle=True)return X_train, X_test, y_train, y_testdef main():x_train, x_test, y_train, y_test = get_train_test()x_train = x_train.reshape(-1, 220)x_test = x_test.reshape(-1, 220)y_train_hot = to_categorical(y_train)y_test_hot = to_categorical(y_test)model = Sequential()model.add(Dense(64, activation='relu', input_shape=(220,)))model.add(Dense(64, activation='relu'))model.add(Dense(64, activation='relu'))model.add(Dense(2, activation='softmax'))model.compile(loss=keras.losses.categorical_crossentropy,optimizer=keras.optimizers.RMSprop(),metrics=['accuracy'])history = model.fit(x_train, y_train_hot, batch_size=100, epochs=100, verbose=1,validation_data=(x_test, y_test_hot))plot_history(history)def save():label_path = './data/'save_data_to_array(label_path, max_pad_size=11)def plot_history(history):plt.plot(history.history['acc'],label='train')plt.plot(history.history['val_acc'],label='validation')plt.legend()plt.show()if __name__ == "__main__":save_data_to_array("./data/", max_pad_size=11) main()

7. 验证

import wave
import numpy as np
import os
from keras.models import load_model# 提取 mfcc 参数
def wav2mfcc(path, max_pad_size=11):y, sr = librosa.load(path=path, sr=None, mono=1)y = y[::3]  #每三个点选用一个audio_mac = librosa.feature.mfcc(y=y, sr=16000)y_shape = audio_mac.shape[1]if y_shape < max_pad_size:pad_size = max_pad_size - y_shapeaudio_mac = np.pad(audio_mac, ((0, 0), (0, pad_size)), mode='constant')else:audio_mac = audio_mac[:, :max_pad_size]return audio_macif __name__ == '__main__':# 构建模型model = load_model('classaud.h5') # 加载训练模型wavs=[]wavs.append(wav2mfcc("./7816.wav",11))X=np.array(wavs)X= X.reshape(-1, 220)print(X.shape)result=model.predict(X[0:1])[0] # print("识别结果",result)#  因为在训练的时候,标签集的名字 为:  0:seven   1:stop    0 和 1 是下标name = ["baby crying","other"] # 创建一个跟训练时一样的标签集ind=0 # 结果中最大的一个数for i in range(len(result)):if result[i] > result[ind]:ind=1print("识别的语音结果是:",name[ind])

keras实现声音二分类相关推荐

  1. 从零开始学keras之电影二分类

    二分类问题可能是应用最广泛的机器学习问题.在这个例子中,你将学习根据电影评论的文字内容将其划分为正面或负面. 本博客使用 IMDB 数据集,它包含来自互联网电影数据库(IMDB)的 50 000 条严 ...

  2. 【深度学习】Keras实现回归和二分类问题讲解

    [深度学习]Keras实现回归和二分类问题讲解 文章目录 [深度学习]Keras实现回归和二分类问题讲解 1 回归问题1.1 波士顿房价预测数据集1.2 构建基准模型1.3 数据预处理1.4 超参数 ...

  3. Keras之MLP:利用MLP【Input(8)→(12)(relu)→O(sigmoid+二元交叉)】模型实现预测新数据(利用糖尿病数据集的八个特征实现二分类预测

    Keras之MLP:利用MLP[Input(8)→(12)(relu)→O(sigmoid+二元交叉)]模型实现预测新数据(利用糖尿病数据集的八个特征实现二分类预测 目录 输出结果 实现代码 输出结果 ...

  4. Keras之DNN:利用DNN【Input(8)→(12+8)(relu)→O(sigmoid)】模型实现预测新数据(利用糖尿病数据集的八个特征进行二分类预测

    Keras之DNN:利用DNN[Input(8)→(12+8)(relu)→O(sigmoid)]模型实现预测新数据(利用糖尿病数据集的八个特征进行二分类预测 目录 输出结果 设计思路 实现代码 输出 ...

  5. Keras之DNN:基于Keras(sigmoid+binary_crossentropy+predict_proba)利用DNN实现分类预测概率——DIY二分类数据集预测新数据点

    #Keras之DNN:基于Keras(sigmoid+binary_crossentropy+predict_proba)利用DNN实现分类预测概率--DIY二分类数据集&预测新数据点 目录 ...

  6. Keras之DNN::基于Keras(sigmoid+binary_crossentropy+predict_classes)利用DNN实现二分类——DIY二分类数据集预测新数据点

    Keras之DNN::基于Keras(sigmoid+binary_crossentropy+predict_classes)利用DNN实现二分类--DIY二分类数据集&预测新数据点 目录 输 ...

  7. Keras之ML~P:基于Keras中建立的简单的二分类问题的神经网络模型(根据200个数据样本预测新的5个样本)——概率预测

    Keras之ML~P:基于Keras中建立的简单的二分类问题的神经网络模型(根据200个数据样本预测新的5个样本)--概率预测 目录 输出结果 核心代码 输出结果 核心代码 # -*- coding: ...

  8. Keras之ML~P:基于Keras中建立的简单的二分类问题的神经网络模型(根据200个数据样本预测新的5+1个样本)——类别预测

    Keras之ML~P:基于Keras中建立的简单的二分类问题的神经网络模型(根据200个数据样本预测新的5+1个样本)--类别预测 目录 输出结果 核心代码 输出结果 核心代码 # -*- codin ...

  9. Keras深度学习(2)-二分类问题之电影评论分类

    二分类问题可能是应用最广泛的机器学习问题.在这个例子中,你将学习根据电影评论的文字内容将其划分为正面或负面. 本节使用 IMDB 数据集,它包含来自互联网电影数据库(IMDB)的 50 000 条严重 ...

  10. R语言使用keras包实现包含多个全连接层的二分类预测模型:在模型训练过程中动态可视化每个epoch后的loss值以及accuray值

    R语言使用keras包实现包含多个全连接层的二分类预测模型:在模型训练过程中动态可视化每个epoch后的loss值以及accuray值 目录

最新文章

  1. 网络推广——网络推广专员如何提升企业网站转化率?
  2. 【转】windows Server2012安装iis
  3. easyui关于dialog弹出位置的问题记录
  4. thinkPHP 中去除URL中的index.php
  5. T440安装Win7系统
  6. 深圳大学移动互联网应用期末大作业——垃圾分类app
  7. 心理学和管理学的一些效应学习
  8. 关于mysql的mysqlAccess denied for user'root'@'IP地址'
  9. python后端 工作 知乎_[Python]知乎后端实习生面试心得
  10. 驾考笔记:科目二考试满分攻略——超详细的点位细节梳理,各种意外情况处理方案整理
  11. Netty实战二-实现UDP的单播和广播
  12. Excel基础(01)认识excel
  13. php 蛋糕一刀均分试题,5个小朋友分一个蛋糕,只准切三刀,该怎样才能平分
  14. JDBC 增、查、删、改 和 防止sql注入登录
  15. 《分析服务从入门到精通读书笔记》第一章、数据分析基础(1)
  16. html js获取天气预报,原生JS实现天气预报
  17. 一款系统优化工具,给Windows调教得服服帖帖
  18. 固态继电器的五大优势
  19. Linux电脑自动重启,修复win10下distributedcom(10016)导致电脑自动重启的方法
  20. 微信小程序中使用async/await

热门文章

  1. matlab绘制散点密度,MATLAB实例:散点密度图
  2. 学习 stm32 无线蓝牙模块HC05配置与应用(手机蓝牙连接发送参数)
  3. atk-hc05 蓝牙
  4. 怎么把图片进行压缩?分享几种压缩图片的方法
  5. 在 LaTeX 中插入表格
  6. 虚拟机安装后找不到操作系统
  7. 大学生心理健康调研报告
  8. 水晶头做网线颜色排列
  9. 什么是自动化与自主化?
  10. 阿里云弹性手机购买与配置