在STM32上运行keyword spotting(二)样本预处理
为什么需要样本
神经网络模型的训练本质上是根据结果寻找最优解的过程,在这个过程中我们需要输入大量的样本以及正确的答案,帮助网络结构内部矫正自己的参数。
样本如何获取
speech_commands_v0.01下载地址,这里整理了数种常用的语音指令供我们使用,每种语音指令下大约有2300条语音数据,包括多种音色,不同背景噪声,具有普遍性。
为什么要筛选数据
后面我用来训练的数据是16KHZ采样率,时间长度为1S的音频,但是上述类别文件夹下的音频数据可能存在8K,或者音频长度不是完整的1S,因此我想将不符合要求的数据筛出去,保留合适的数据,并以npy的格式保存在硬盘中方便后续读取。为此我做了以下工作:
- 将类别文件夹下面的音频文件重命名,这样我可以方便的通过python读取
- 读取wav文件,筛选出符合要求的音频,读取为numpy数组并将其保存在固定文件夹下
- 通过修改
audio_name = "xxx"
,运行脚本并且将所有的类别保存 脚本如下read_audio.py:
import wave import numpy as np audio_name = "five" len = 16000 save_index = 1 print("start.") for index in range(1,2300): audio_str = "../audio/"+audio_name+"/audio_"+audio_name+"_ ("+str(index)+").wav" wav_file = wave.open(audio_str,"rb") params = wav_file.getparams() nchannels, sampwidth, framerate, nframes = params[:4] if len == nframes: str_audio_data = wav_file.readframes(nframes) wave_data = np.frombuffer(str_audio_data,dtype=np.short) np.save("../audio/np_"+audio_name+"/"+str(save_index)+".npy", wave_data) save_index +=1 wav_file.close() print("end.")
为什么要提取音频特征
我们当前的音频数据为时长为1S,采样率为16KHz的音频数据,也就是1×16000的一个矩阵,但是无论是对于人还是对于计算机来说,从这样的一串数组中发现特征是比较困难的,因此聪明的人类为了提取音频特征,根据人耳的声学原理,研究出了Mel频率倒谱系数(MeI-Freguency CeptraI Coefficients)简称为MFCC,它可以将一段音频数组转化为二维特征图,主要进行了以下步骤:
当然,关于MFCC的详细运行方式解释我不想过多阐述,你可以在其他网站搜索到,这里有一个我认为写得不错的博客,我在gitee上白嫖到了python版本与C++版本,你可以在我的工程项目中查看其源码。并且为了在嵌入式上运行,我根据C++版本重写了C版本,计算结果完全一致。总结而言,为了提取音频特征,我做了以下工作:
- 使用python脚本读取上一步中的npy文件,提取他的mfcc特征,重新保存在硬盘中
- 提取特征后,原来1×16000的音频数据转为10×49的特征图
- 通过修改
audio_name = "xxx"
,运行脚本并且将所有的类别保存 脚本如下read_audio_mfcc.py:
import numpy as np from mfcc import KWS_MFCC #mfcc.py需要和本脚本在同一目录下 audio_name = "background" all_num = 2001 #索引到2000 for index in range(1,all_num): audio_np_str = "../audio/np_"+audio_name+"/"+audio_name+"_ ("+str(index)+").npy" temp_data = np.load(audio_np_str) kws = KWS_MFCC(temp_data) mfccFeatures = kws.extract_features() u8MfccFeatures = kws.extract_uint8_features() audio_np_mfcc_str = "../audio/np_"+audio_name+"_mfcc/"+str(index)+".npy" np.save(audio_np_mfcc_str, mfccFeatures) audio_np_mfcc_str = "../audio/np_"+audio_name+"_mfcc/"+"u8_"+str(index)+".npy" np.save(audio_np_mfcc_str, u8MfccFeatures) print(index)
我的代码比较凌乱,但是如果你能明白其原理,可以重写脚本并且整理出自己的样本数据,下一章节我将阐述如何建立的卷积神经网络框架,训练模型并且测试,将最终模型转换为onnx格式的模型并测试。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
能给下你工程的源代码吗
https://github.com/tsk15535904190/kws_arm_torch