基于Python的话者识别系统

基于Python的话者识别系统

一:写在开头

语言是人类最重要的交流工具,它方便自然,准确高效。随着社会的不断发展,各种各样的机器参与了人类的生产活动和社会活动,因此人对机器的操纵就越来越重要。人们发现,人和机器之间最好的通信方式就是语音,而语音就是语言的声学表现形式。
自己在网络上浏览过很多关于语音识别或者话者识别的博文,但无外乎一下两种类型:
1.难度很高,学术性很强,动不动就是隐形马尔科夫技术等,对于大部分人来说很不友好,难以理解。
2.大量的只言片语和一些单纯的理论知识,没有具体实现一个语音系统的代码和思路梳理。
所以博主想用简单的思路和易于理解的代码完成。由于本人目前在读大学,水平不足,难免会有错误和疏漏,还请前辈,同辈和后辈斧正。

该项目使用到的声学基础

1.音频采样:采样就是从一个时间上连续变化的 模拟信号取出若干个有代表性的样本值,来代表这个连续变化的模拟信号。
在这里插入图片描述
2.采样率:采样频率是指将模拟声音波形进行数字化时,每秒钟抽取声波幅度样本的次数。
常用的音频采样频率有8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等,采样频率越高声音的还原就越真实越自然。单位用赫兹(Hz)。

3.音频帧:音频跟视频很不一样,视频每一帧就是一张图像,而从上面的正弦波可以看出,音频数据是流式的,本身没有明确的一帧帧的概念。在实际的应用中,为了音频算法处理/传输的方便,一般约定俗成取2.5ms~60ms为单位的数据量为一帧音频。

4.MFCC(梅尔频率倒谱系数): MFCCs(Mel Frequency Cepstral Coefficents)是一种在自动语音和说话人识别中广泛使用的特征,考虑到了人类的听觉特征,先将线性频谱映射到基于听觉感知的Mel非线性频谱中,然后转换到倒谱上。

5.预加重:预加重的目的是提升高频部分,使信号的频谱变得平坦。

6.分帧:通常语音识别所采用语音信号的采样频率为8KHz或16KHz,以8KHz来说,若帧长度为256个采样点,则对应的时间长度是256/8000×1000=32ms。

7.加窗:语音在长范围内是不停变动的,没有固定的特性无法做处理,所以将每一帧代入窗函数,窗外的值设定为0,其目的是消除各个帧两端可能会造成的信号不连续性。常用的窗函数有方窗、汉明窗和汉宁窗等,根据窗函数的频域特性,常采用汉明窗。

开发环境

1.配置:Windows 10
2.工具:Python 3.6
3.IDE: Pycharm
4.第三方库:pandas,sklearn,numpy,librosa,matplotlib,python_speech_features
5.使用到的算法:支持向量机,随机森林,K近邻,分层交叉验证
6.用于训练模型的音频文件:
在这里插入图片描述
7.用于测试模型的音频文件:
在这里插入图片描述
上述测试文件提前不知道是谁说的,用于测试模型准确度。

代码实现部分

1.config.py(配置信息文件)
import numpy
class Paths:
    DATA_PATH="音频文件"
    TEST_PATH="测试文件/test3.WAV"

class Audio:
    #采样率
    samp_rate=16000
    #采样点个数(音频处理单元,也就是一个音频帧里有多少次采样)
    fsize=400
    #每一音频帧的时间长度
    #每秒有16000次采样,而每个帧有400次采样,所以一个帧的时间是400/160000
    flen=fsize/samp_rate


    #连续窗口之间的步长
    hlen=0.01

class Windowing:
    hamming=lambda x: 0.54-0.46*numpy.cos((2*numpy.pi*x)/(400-1))


class Model:
    # KFold的n_splits
    n_splits=1000

在这里解释一下配置信息,Path类指定了访问音频文件的路径。Audio类中是提取MFCC时使用到的参数,可以参考前面所写的声学基础。Windowing类是用lambda表达式实现的一个汉明窗函数,用于加窗操作。Model类中是用于分层K折交叉验证的层数,规定分1000层,有助于提高精度。以后用到这些参数可以直接调用,无需再写。

2.FileFinder.py(获得训练用的音频文件工具类)
import os

def get_subdir(a_dir):
    return [name for name in os.listdir(a_dir) if os.path.isdir(os.path.join(a_dir, name))]

a.在这里用到了Python的os模块,os模块提供了多数操作系统的功能接口函数。当os模块被导入后,它会自适应于不同的操作系统平台,根据不同的平台进行相应的操作,在python编程时,经常和文件、目录打交道,所以离不了os模块。
b.这里定义了一个获取子目录的方法,并且会传入参数a_dir,这个a_dir将来会从Path类中取,然后传入。首先返回的是一个列表,关键是列表里面是什么,先看if语句,这里用到了os.path.isdir(),很明显用来判断传入的参数是不是一个目录,又使用了os.path.join来拼接a_dir和name,最后使用for循环遍历出a_dir下所有目录的名称。所以最后列表中是一个个目录的名称。

3.SignalProcesser.py(信号处理工具类)
import librosa
import numpy
import librosa.display
from matplotlib import pyplot as plt
#在个人音频训练文件夹中得到每一个音频的样本数组
def get_sample_arrays(train_dir,folder_name,samp_rate):
    #得到路径
    path_audios=librosa.util.find_files(train_dir+"/"+folder_name)
    #定义一个列表来存储每个音频文件的样本数组
    audios=[]
    for audio in path_audios:
        x, sr = librosa.load(audio, sr=16000, mono=True)
        audios.append(x)
        #画出所有音频文件的波形图
        plt.show()
        librosa.display.waveplot(x,sr)
        plt.rcParams['axes.unicode_minus']=False
        plt.rcParams['font.sans-serif']=['SimHei']
        plt.title("波形图")
        plt.show()

    #画出所有音频文件的频谱图
    for audio2 in path_audios:
         x, sr = librosa.load(audio2, sr=samp_rate, mono=True)
         melspec=librosa.feature.melspectrogram(x,sr)
         logmelspec=librosa.power_to_db(melspec)
         plt.rcParams['axes.unicode_minus'] = False
         plt.rcParams['font.sans-serif'] = ['Si
  • 32
    点赞
  • 162
    收藏
    觉得还不错? 一键收藏
  • 65
    评论
评论 65
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值