【語音識別】基於matlab MFCC和SVM特定人性別識別【含Matlab原始碼 533期】
一、簡介
MFCC(Mel-frequency cepstral coefficients):梅爾頻率倒譜系數。梅爾頻率是基於人耳聽覺特性提出來的, 它與Hz頻率成非線性對應關係。梅爾頻率倒譜系數(MFCC)則是利用它們之間的這種關係,計算得到的Hz頻譜特徵。主要用於語音資料特徵提取和降低運算維度。例如:對於一幀有512維(取樣點)資料,經過MFCC後可以提取出最重要的40維(一般而言)資料同時也達到了將維的目的。
MFCC一般會經過這麼幾個步驟:預加重,分幀,加窗,快速傅立葉變換(FFT),梅爾濾波器組,離散餘弦變換(DCT).其中最重要的就是FFT和梅爾濾波器組,這兩個進行了主要的將維操作。
1.預加重
將經取樣後的數字語音訊號s(n)通過一個高通濾波器(high pass filter):其中a一般取0.95左右。經過預加重後的訊號為:
預加重的目的是提升高頻部分,使訊號的頻譜變得平坦,保持在低頻到高頻的整個頻帶中,能用同樣的信噪比求頻譜。同時,也是為了消除發生過程中聲帶和嘴脣的效應,來補償語音訊號受到發音系統所抑制的高頻部分,也為了突出高頻的共振峰。
2.分幀
為了方便對語音分析,可以將語音分成一個個小段,稱之為:幀。先將N個取樣點集合成一個觀測單位,稱為幀。通常情況下N的值為256或512,涵蓋的時間約為20~30ms左右。為了避免相鄰兩幀的變化過大,因此會讓兩相鄰幀之間有一段重疊區域,此重疊區域包含了M個取樣點,通常M的值約為N的1/2或1/3。通常語音識別所採用語音訊號的取樣頻率為8KHz或16KHz,以8KHz來說,若幀長度為256個取樣點,則對應的時間長度是256/8000×1000=32ms。
3.加窗
語音在長範圍內是不停變動的,沒有固定的特性無法做處理,所以將每一幀代入窗函式,窗外的值設定為0,其目的是消除各個幀兩端可能會造成的訊號不連續性。常用的窗函式有方窗、漢明窗和漢寧窗等,根據窗函式的頻域特性,常採用漢明窗。
將每一幀乘以漢明窗,以增加幀左端和右端的連續性。假設分幀後的訊號為S(n), n=0,1…,N-1, N為幀的大小,那麼乘上漢明窗後 ,W(n)形式如下:
不同的a值會產生不同的漢明窗,一般情況下a取0.46.
4.快速傅立葉變換
由於訊號在時域上的變換通常很難看出訊號的特性,所以通常將它轉換為頻域上的能量分佈來觀察,不同的能量分佈,就能代表不同語音的特性。所以在乘上漢明窗後,每幀還必須再經過快速傅立葉變換以得到在頻譜上的能量分佈。對分幀加窗後的各幀訊號進行快速傅立葉變換得到各幀的頻譜。並對語音訊號的頻譜取模平方得到語音訊號的功率譜。設語音訊號的DFT為:
式中x(n)為輸入的語音訊號,N表示傅立葉變換的點數。
這裡需要先介紹下Nyquist頻率,奈奎斯特頻率(Nyquist頻率)是離散訊號系統取樣頻率的一半,因哈里·奈奎斯特(Harry Nyquist)或奈奎斯特-夏農取樣定理得名。取樣定理指出,只要離散系統的奈奎斯特頻率高於被取樣訊號的最高頻率或頻寬,就可以避免混疊現象。在語音系統中我通常取樣率取16khz,而人發生的頻率在300hz~3400hz之間,按照Nyquist頻率的定義就有Nyquist頻率等於8khz高於人發生的最高頻率,滿足Nyquist頻率的限制條件。FFT就是根據Nyquist頻率擷取取樣率的一半來計算,具體來說就是,假設一幀有512個取樣點,傅立葉變換的點數也是512,經過FFT計算後輸出的點數是257(N/2+1),其含義表示的是從0(Hz)到取樣率/2(Hz)的N/2+1點頻率的成分。也就是說在經過FFT計算時不僅把訊號從時域轉到了頻域並且去除了高於被取樣訊號的最高頻率的點的影響,同時也降低了維度。
5.梅爾濾波器組
由於人耳對不同頻率的敏感程度不同,且成非線性關係,因此我們將頻譜按人耳敏感程度分為多個Mel濾波器組,在Mel刻度範圍內,各個濾波器的中心頻率是相等間隔的線性分佈,但在頻率範圍不是相等間隔的,這個是由於頻率與Mel頻率轉換的公式形成的,公式如下:
式中的log是以log10為底,也就是lg。
將能量譜通過一組Mel尺度的三角形濾波器組,定義一個有M個濾波器的濾波器組(濾波器的個數和臨界帶的個數相近),採用的濾波器為三角濾波器,中心頻率為f(m),m=1,2,...,M。M通常取22-26。各f(m)之間的間隔隨著m值的減小而縮小,隨著m值的增大而增寬,如圖所示:
式中的k指經過FFT計算後的點的下標,也就是前面例子中的0~257,f(m)也對應點的下標,具體求法如下:
1.確定語音訊號最低(一般是0hz)最高(一般是取樣率的二分之一)頻率以及Mel濾波器個數
2.計算對應最低最高頻率的mel頻率
3.計算相鄰兩個mel濾波器中心頻率的距離:(最高mel頻率-最低mel頻率)/(濾波器個數+1)
4.將各個中心Mel頻率轉成頻率
5.計算頻率對應FFT中點的下標
例如:假設取樣率為16khz,最低頻率為0hz,濾波器個數為26,幀大小為512,則傅立葉變換點數也為512,那麼帶入Mel頻率與實際頻率的轉換公式中得到最低Mel頻率為0,最高Mel頻率為2840.02.中心頻率距離為:(2840.02-0)/(26+1)=105.19,這樣我們就可以得到Mel濾波器組的中心頻率:[0,105.19,210.38,...,2840.02],然後再將這組中心頻率轉成實際頻率組(按公式操作即可,這裡不列出來了),最後計算實際頻率組對應FFT點的下標,計算公式為:實際頻率組中的每個頻率/取樣率*(傅立葉變換點數 + 1)。這樣就得到FFT點下標組:[0,2,4,7,10,13,16,...,256],也就是f(0),f(1),...,f(27)。
有了這些,我們在計算每個濾波器的輸出,計算公式如下:
式中的M指濾波器的個數,N指FFT中的點數(上述的例子中是257)。經過上面的計算後每幀資料我們得到一個與濾波器個數相等的維數,降低了維數(本例中是26維)。
6.離散餘弦變換
離散餘弦變換經常用於訊號處理和影象處理,用來對訊號和影象進行有損資料壓縮,這是由於離散餘弦變換具有很強的"能量集中"特性:大多數的自然訊號(包括聲音和影象)的能量都集中在離散餘弦變換後的低頻部分,實際就是對每幀資料在進行一次將維。其公式如下:
將上述每個濾波器的對數能量帶入離散餘弦變換,求出L階的Mel-scale Cepstrum引數。L階指MFCC係數階數,通常取12-16。這裡M是三角濾波器個數。
7.動態差分引數的提取
標準的倒譜引數MFCC只反映了語音引數的靜態特性,語音的動態特性可以用這些靜態特徵的差分譜來描述。實驗證明:把動、靜態特徵結合起來才能有效提高系統的識別效能。差分引數的計算可以採用下面的公式:
式中,dt表示第t個一階差分,Ct表示第t個倒譜系數,Q表示倒譜系數的階數,K表示一階導數的時間差,可取1或2。將上式的結果再代入就可以得到二階差分的引數。
因此,MFCC的全部組成其實是由: N維MFCC引數(N/3 MFCC係數+ N/3 一階差分引數+ N/3 二階差分引數)+幀能量(此項可根據需求替換)。
這裡的幀能量是指一幀的音量(即能量),也是語音的重要特徵,而且非常容易計算。因此,通常再加上一幀的對數能量(定義:一幀內訊號的平方和,再取以10為底的對數值,再乘以10)使得每一幀基本的語音特徵就多了一維,包括一個對數能量和剩下的倒頻譜引數。另外,解釋下最開始說的40維是怎麼回事,假設離散餘弦變換的階數取13,那麼經過一階二階差分後就是39維了再加上幀能量總共就是40維,當然這個可以根據實際需要動態調整。
二、原始碼
function varargout = untitled(varargin)
% UNTITLED MATLAB code for untitled.fig
% UNTITLED, by itself, creates a new UNTITLED or raises the existing
% singleton*.
%
% H = UNTITLED returns the handle to a new UNTITLED or the handle to
% the existing singleton*.
%
% UNTITLED('CALLBACK',hObject,eventData,handles,...) calls the local
% function named CALLBACK in UNTITLED.M with the given input arguments.
%
% UNTITLED('Property','Value',...) creates a new UNTITLED or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before untitled_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to untitled_OpeningFcn via varargin.
%
% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
% instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help untitled
% Last Modified by GUIDE v2.5 23-Apr-2018 16:20:43
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @untitled_OpeningFcn, ...
'gui_OutputFcn', @untitled_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before untitled is made visible.
function untitled_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to untitled (see VARARGIN)
% Choose default command line output for untitled
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes untitled wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line.
function varargout = untitled_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
%clc
%clear variables
%close
global file
global Group2
Tw = 25; % analysis frame duration (ms)
Ts = 10; % analysis frame shift (ms)
alpha = 0.97; % preemphasis coefficient
R = [ 300 3700 ]; % frequency range to consider
M = 20; % number of filterbank channels
C = 13; % number of cepstral coefficients
L = 22; % cepstral sine lifter parameter
fs = 16000;
% hamming window (see Eq. (5.2) on p.73 of [1])
hamming = @(N)(0.54-0.46*cos(2*pi*[0:N-1].'/(N-1)));
% Read speech samples, sampling rate and precision from file
N=10;
path = 'Validation_test_set';
file = dir(path);
file(1:2) = [];
speech=zeros(N*16000,16);
speech2=zeros(N*16000,16);
samples = [1,N*16000];
N_P=14;
for i = 1:length(file)
str=strcat('Validation_test_set','\',file(i).name);
speech(:,i) = audioread(str,samples);
speech2(:,i) = audioread(str,(samples+[N_P*16000,N_P*16000]));
end
MFCCS=zeros(10000,16);
MFCCS2=zeros(10000,16);
% Feature extraction (feature vectors as columns)
for i2 = 1:length(file)
[ mfccs, FBEs, frames ] = ...
mfcc( speech(:,i2), fs, Tw, Ts, alpha, hamming, R, M, C, L );
CC=mfccs(:);
MFCCS(1:length(CC),i2)=CC;
[ mfccs2, FBEs2, frames2 ] = ...
mfcc( speech2(:,i2), fs, Tw, Ts, alpha, hamming, R, M, C, L );
CC2=mfccs2(:);
MFCCS2(1:length(CC),i2)=CC2;
end
TrainData =MFCCS;
Group=[0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 ];
Group2=zeros(size(Group));
SVMStruct = svmtrain(TrainData,Group); % train
for i3 = 1:length(file)
TestData = MFCCS2(:,i3)';
Group2(1,i3) = svmclassify(SVMStruct,TestData); % test
end
ACC=(16-sum(xor(Group2,Group)))/16;
set(handles.edit1,'string',ACC);
% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global filep
global filename
[filename,filepath]=uigetfile('*.wav','開啟檔案');%gui中開啟檔案
filep=strcat(filepath,filename);
%filep
% [filex,fs]=audioread(filep);
% sound(filex,fs);
set(handles.edit2,'string',filename);
function edit2_Callback(hObject, eventdata, handles)
% hObject handle to edit2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of edit2 as text
% str2double(get(hObject,'String')) returns contents of edit2 as a double
% --- Executes during object creation, after setting all properties.
function edit2_CreateFcn(hObject, eventdata, handles)
% hObject handle to edit2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
三、執行結果
四、備註
版本:2014a
完整程式碼或代寫加1564658423