赞
踩
基于Python实现的GMM算法的语音数字识别
目录
1 任务描述 1
2 实验环境 1
3 实验方案 1
3.1 MFCC 特征提取 1
3.2 GMM 分类 2
3.3 GMM 实现 3
4 运行手册 5
5 实验结果及运行截图 6
1任务描述
基于数字语音数据集,编写代码,使用 GMM 算法完成语音识别,对输入的一段音频进行分类,输出语音中的数字,如“2”、“10”。
2实验环境
操作系统使用 MacOS,Python=3.6,python-speech-features=0.6,pyaudio, scikit-learn=0.18.1。
3实验方案
3.1MFCC 特征提取
我们使用课程提供的英文数据集,包括数字 0-9 共 150 个 wav 格式的音频文件。我们使用 Python 的 wav 包读取 wav 文件,使用 python-speech-features 获得每条音频数据的 13 维 MFCC 特征。我们在本实验中对加入一阶导与二阶导
的 39 维特征同样进行了实验,但识别结果不如 13 维 MFCC 特征。我们分析原因很可能为训练数据过少导致数据的过拟合。具体来说,MFCC 特征提取算法首先进行预加重,然后对语音文件进行分帧,加窗,然后进行快速傅里叶变换,将它转换为频域上的能量分布来观察;将能量谱通过一组 Mel 尺度的三角形滤波器组,本文转载自http://www.biyezuopin.vip/onews.asp?id=15250对频谱进行平滑化,并消除谐波的作用,突显原先语音的共振峰;计算每个滤波器输出的对数能量,经离散余弦变换(DCT)得到 MFCC 系数;然后计算对数能量;最后提取动态差分参数。
在实际编写代码时,我们在 features.py 中编写了特征提取函数,返回每个数据样本的 13 维 MFCC 特征。
3.2GMM 分类
在获取了 MFCC 特征之后,我们将编写基于 GMM 的分类算法。我们使用了scikit-learn 的 GaussianMixture 高斯混合分布模型来编写程序。在本实验中,我们面的是一个十分类问题。我们将训练十个单核 GMM。对于每个数字的所有样本,我们用这部分训练数据训练同一个单核 GMM。在测试阶段,我们将每一个待分类样本输入至每一个 GMM,得到在该 GMM 下的对应评分,即该 GMM 对应数字的评分。我们对十个评分进行降序排序,将评分最高的 GMM 对应数字作为预测标签进行输出。
#!/usr/bin/env python3 import os import sys import itertools import glob import argparse from utils import read_wav from interface import ModelInterface import numpy as np def get_args(): desc = "Speaker Recognition Command Line Tool" epilog = """ Wav files in each input directory will be labeled as the basename of the directory. Note that wildcard inputs should be *quoted*, and they will be sent to glob.glob module. Examples: Train (enroll a list of person named person*, and mary, with wav files under corresponding directories): ./speaker-recognition.py -t enroll -i "/tmp/person* ./mary" -m model.out Predict (predict the speaker of all wav files): ./speaker-recognition.py -t predict -i "./*.wav" -m model.out """ parser = argparse.ArgumentParser(description=desc,epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('-t', '--task', help='Task to do. Either "enroll" or "predict"', required=True) parser.add_argument('-i', '--input', help='Input Files(to predict) or Directories(to enroll)', required=True) parser.add_argument('-m', '--model', help='Model file to save(in enroll) or use(in predict)', required=True) ret = parser.parse_args() return ret def task_enroll(input_dirs, output_model): m = ModelInterface() input_dirs = [os.path.expanduser(k) for k in input_dirs.strip().split()] dirs = itertools.chain(*(glob.glob(d) for d in input_dirs)) dirs = [d for d in dirs if os.path.isdir(d)] files = [] if len(dirs) == 0: print ("No valid directory found!") sys.exit(1) for d in dirs: label = os.path.basename(d.rstrip('/')) wavs = glob.glob(d + '/*.wav') if len(wavs) == 0: print ("No wav file found in %s"%(d)) continue for wav in wavs: try: fs, signal = read_wav(wav) m.enroll(label, fs, signal) print("wav %s has been enrolled, label: %s"%(wav, label)) except Exception as e: print(wav + " error %s"%(e)) m.train() m.dump(output_model) def task_predict(input_dirs, input_model): m = ModelInterface.load(input_model) input_dirs = [os.path.expanduser(k) for k in input_dirs.strip().split()] dirs = itertools.chain(*(glob.glob(d) for d in input_dirs)) dirs = [d for d in dirs if os.path.isdir(d)] files = [] if len(dirs) == 0: print ("No valid directory found!") sys.exit(1) gold_labels = [] pred_labels = [] for d in dirs: label_gold = os.path.basename(d.rstrip('/')) wavs = glob.glob(d + '/*.wav') if len(wavs) == 0: print ("No wav file found in %s"%(d)) continue for wav in wavs: try: fs, signal = read_wav(wav) # m.enroll(label, fs, signal) # print("wav %s has been enrolled, label: %s"%(wav, label)) label_pred, score = m.predict(fs, signal) print (wav, 'pred label->', label_pred, ", score->", score, ", gold label->", label_gold) gold_labels.append(label_gold) pred_labels.append(label_pred) except Exception as e: print(wav + " error %s"%(e)) prec = sum(np.array(gold_labels) == np.array(pred_labels)) / len(gold_labels) print("precision: %f"%(prec)) # def task_predict(input_files, input_model): # m = ModelInterface.load(input_model) # for f in glob.glob(os.path.expanduser(input_files)): # fs, signal = read_wav(f) # label, score = m.predict(fs, signal) # print (f, '->', label, ", score->", score) if __name__ == "__main__": global args args = get_args() task = args.task if task == 'enroll': task_enroll(args.input, args.model) elif task == 'predict': task_predict(args.input, args.model)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。