赞
踩
语言是人类最重要的交流工具,它方便自然,准确高效。随着社会的不断发展,各种各样的机器参与了人类的生产活动和社会活动,因此人对机器的操纵就越来越重要。人们发现,人和机器之间最好的通信方式就是语音,而语音就是语言的声学表现形式。
自己在网络上浏览过很多关于语音识别或者话者识别的博文,但无外乎一下两种类型:
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.用于测试模型的音频文件:
上述测试文件提前不知道是谁说的,用于测试模型准确度。
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层,有助于提高精度。以后用到这些参数可以直接调用,无需再写。
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下所有目录的名称。所以最后列表中是一个个目录的名称。
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'] = ['SimHei'
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。