小工具知识网

当前位置: 首页 > 行业知识 > 基于MATLAB的有限语音识别

行业知识

基于MATLAB的有限语音识别

2026-11-12 16:04:52 来源:互联网转载

前���时间参与了一个小组项目,其中涉及到了MATLAB进行“上”、“下”、“左”、“右”的语音识别。查了一些资料、进行些许调试算是把问题解决了。

目录

一、识别原理

1.MFCC算法

2.SVM算法

3.ECOC(纠错输出码)

二、代码原理

1.训练集的收集

2.模型的训练

3.收集待分类音频样本并进行分类

4.音频的向量化处理

三、其它问题


一、识别原理

对于语音识别,首先确定基本原理是利用MFCC算法提取声音特征,然后将特征转化成的向量进行分类,根据训练特点可以考虑采用基于SVM算法的纠错输出码(Error-Correcting Output Codes, ECOC)算法。

1.MFCC算法

MFCC(Mel Frequency Cepstral Coefficients)是一种用于特征提取的算法,其通过傅立叶变换、梅尔滤波和DCT等,从时域转换到梅尔频率倒谱空间,提取声音的形状特征。

1. 傅立叶变换(FFT):对音频信号进行快速傅立叶变换,从时域转换到频域。

2. 梅尔滤波器组(Mel Filterbank):将频域信号通过一个梅尔滤波器组进行过滤。梅尔滤波器组模拟人耳对频率的感知,低频分辨率高,高频分辨率低。

3. 对梅尔滤波器组输出取对数:为了弱化高能成分的影响。

4. 离散余弦变换(DCT):将对数梅尔频率能量谱转换到梅尔频率倒谱空间。DCT可以将相关性信息压缩到少数系数中。

5. 取前N个系数。这些系数即为MFCC特征。

2.SVM算法

SVM(支持向量机)算法的基本思想和工作原理是将数据映射到高维空间,在这个空间中找到最大间隔超平面进行分类,其基本原理是:

1. 将原始输入空间中的数据映射到一个高维特征空间,使得原来不线性可分的两个类在这个新空间中可以线性分开。这种映射是通过核函数来实现的。

2. 在这个新空间中找到一个超平面,使得这个超平面可以将两个类隔开,且离这两个类最近的样本点与超平面的距离最大。这两个离超平面最近的样本点称为支持向量。

3. 找到的这个最大间隔超平面就是SVM的决策面。新样本点将根据它与这个超平面之间的位置关系来判断属于哪一类。

3.ECOC(纠错输出码)

SVM在解决本问题中存在一个不可忽视的问题,那就是SVM算法是一种二分类的算法,然而实际上本问题的语音指令识别要求识别“上”、“下”、“左”、“右”四种指令。此时,纠错输出码(Error-Correcting Output Codes, ECOC)将作为一个很好的解决思路,ECOC的工作原理如下:

- ECOC将问题分解成多个二分类子问题。对于K类分类问题,ECOC的二值编码矩阵,其中每一行对应一个类,每一列对应一个二分类器。

- 二值编码矩阵中的每个元素都取0或1,用来表示该类是否属于该二分类器正例或反例集合。

三分类的一个例子

- 然后根据编码矩阵训练出L个二分类器。在预测阶段,每个样本被每个二分类器判断,获得一个长为L的二值代码向量。

- 最后将该样本的代码向量与每一行编码进行汉明距离计算,预测属于距离最小的那一行对应的类。

二、代码原理

在完成原理设计的确认后,就开始完成代码的编写。代码总体流程设计如下:

1.训练集的收集

getVoice.m用于实现基于能量特征的语音关键词触发录音功能,录音片段会自动命名并保存到文件,可以用于后续语音识别模型训练,函数流程如下:

1. 定义了关键词列表和能量阈值。

2. 初始化麦克风录音设备,设置采样参数。

3. 输入需要录制的每个类别的样本数量。

4. 开始循环录制每个类别的语音:

   - 实时从麦克风读取音频数据。

   - 计算音频能量特征,判断是否超过阈值。

   - 如果超过阈值,则将该段音频保存到文件。

   - 循环录制,直到录制数量达到设定值。

function getVoice()% 该函数用于录入音频% 音频格式满足voiceTrain% 关键词keywords={'up','down','left','right'};% 定义触发阈值,根据实际情况调整thresholds = 0.0008;% 定义声音频率fs = 44100;% 定义采样参数SamplesPerFrameSPF = 1024*32;% 定义文件位置filePath = strcat('./voice',num2str(fs),'/');% 获取麦克风设备信息% devices = audiodevinfo;% 创建麦克风输入对象reader = audioDeviceReader('Device',"Default",'SamplesPerFrame',SPF);% setup(reader);% 输入每个类别训练数量numVoice = input('请输入每个类别训练数量');% while(~isnumerictype(numVoice))%     numVoice = input('请输入每个类别训练数量');% end% 定义文件号n = 0;% 开始语音录制disp('开始实时语音识别...');for k = 1:size(keywords,2)    kw = cell2mat(keywords(k)); % 定义当前类别    disp(strcat('请说:',kw));    firstAudio = reader();    % 当前类别的理论最大文件序号    knumVoice = numVoice;    while(n = 1 && maxPoint + SPF/2 - 1  thresholds) % 能量超过阈值            % 完整文件路径            fullPath = strcat(filePath,kw,int2str(n),'.wav');            while(exist(fullPath,'file') == 2) % 文件已存在                % 设置文件序号的偏移                knumVoice = knumVoice + 1;                n = n + 1;                fullPath = strcat(filePath,kw,int2str(n),'.wav');            end            audiowrite(fullPath,audio,fs);            disp(strcat('获得数据',kw,int2str(n)));            n = n +1;        end    end    n = 0;end% release(reader);disp('识别结束,请自行清理不良音频并注意文件命名');end
2.模型的训练

voiceTrain.m用于实现基于SVM的语音分类模型训练,函数流程如下:

1. 定义关键词列表和声音文件路径。

2. 初始化训练数据矩阵和标签向量。

3. 开始循环每个类别:

   - 按文件名顺序读取该类别下所有语音文件。

   - 对读取的音频数据进行预处理,提取特征。

   - 将特征数据添加到训练数据矩阵,同时将类别标签添加到标签向量。

4. 循环读取完一个类别后,标签值加1,表示下一个类别。

5. 循环读取完所有类别后,训练SVM多分类模型。

6. 将训练好的SVM模型保存到文件。

function voiceTrain()% 该函数用于训练SVM模型% 声音的录取应遵循相应格式% 关键词keywords={'up','down','left','right'};% 声音频率fs = 44100;% 定义文件位置filePath = strcat('./voice',num2str(fs),'/');% 训练数据,每行代表一个样本,每列代表一个特征trainData = [];% 训练标签,是一个列向量trainLable = [];% 训练类classTag = 1;for kw = keywords    k = 0; % 该类别下声音的序号    fileName = strcat(filePath,cell2mat(kw),num2str(k),'.wav'); % 文件名    while(exist(fileName,"file") == 2) % 直到文件不存在        tempData = dataProcess(audioread(fileName),fs); % 读取并处理音频        trainData = [trainData;tempData]; % 添加训练数据        trainLable = [trainLable;classTag]; % 添加训练标签        k = k + 1;        fileName = strcat(filePath,cell2mat(kw),num2str(k),'.wav'); %下一个文件名    end    disp(strcat(kw,num2str(k)));    classTag = classTag + 1;end% 训练并保存SVM模型voiceModel = fitcecoc(trainData, trainLable);save('voiceModel.mat',"voiceModel",'-mat');end
3.收集待分类音频样本并进行分类

voiceClassifier用于实现基于训练好的SVM模型进行语音实时识别的功能,代码流程如下:

1. 定义必要参数,如关键词、采样率等。

2. 初始化麦克风录音设备。

3. 设置能量阈值,加载已训练好的SVM模型。

4. 开始实时循环录音和识别:

   - 从麦克风读取音频数据。

   - 判断音频能量是否超过阈值。

   - 如果超过,则提取语音片段,进行预处理得到测试特征。

   - 将测试特征输入训练好的SVM模型进行分类。

   - 输出分类结果。

function voiceClassifier()% 定义声音频率fs = 44100;% 定义采样参数SamplesPerFrameSPF = 1024*32;% 关键词keywords={'up','down','left','right'};% 获取麦克风设备信息% devices = audiodevinfo;% 创建麦克风输入对象reader = audioDeviceReader('Device',"Default",'SamplesPerFrame',SPF);setup(reader);% 定义触发阈值thresholds = 0.0008; % 根据实际情况调整阈值% 加载训练好的SVM模型voiceModel = load('voiceModel.mat');voiceModel = voiceModel.voiceModel;% 开始实时语音识别disp('开始实时语音识别...');firstAudio = reader(); % 第一段音频while true    % 待提取的二倍长度原始音频    rawAudio = [firstAudio;reader()];    % 后半段音频将作为下次的前半段    firstAudio = rawAudio(SPF+1:end,:);    % 音频的振幅最高点作为中点    [~,maxPoint] = max(rawAudio);    % 将rawAudio振幅最高点的两侧作为判断的音频    if(maxPoint - SPF/2 >= 1 && maxPoint + SPF/2 - 1  thresholds) % 能量超过阈值%         plot(audio);%         drawnow;        % 音频的预处理        testData = dataProcess(audio,fs);        % 使用训练好的模型对测试数据进行分类        [predictedLabels,scores] = predict(voiceModel, testData);        % 输出测试结果        if(scores(predictedLabels)>-0.3)            disp(keywords(predictedLabels));            disp(num2str(scores));        end    endendend
4.音频的向量化处理

dataProcess.m用于实现语音信号的预处理以及提取MFCC特征,其同时被voiceTrain和voiceClassifier调用,代码流程如下:

1. 对原始语音信号进行低通滤波,滤除低频噪声。

2. 再进行高通滤波,滤除高频噪声。

3. 调用mfcc函数计算语音信号的MFCC特征。

4. 将提取的MFCC特征矩阵转化为行向量,作为分类模型的输入特征。

function result = dataProcess(voiceData,fs)% 输入一个声音信号,以行向量形式返回处理结果% voiceData(abs(voiceData)

上一篇:怎么架设内网服务器小白?

下一篇:Win2012源码导入秘籍,轻松上手,一键操作,快速掌握全攻略!