語音識別MFCC系列(四)——MFCC特徵參數提取

最好先看下下面三篇(其中系統的講述了離散傅里葉變換,能量密度譜爲什麼是DFT係數的平方除以總點數,爲什麼512點的離散傅里葉變換隻選前257個分量,離散餘弦變換,爲什麼採樣頻率要大於真實信號最大頻率的兩倍,頻譜混疊,頻譜泄露,爲什麼要用窗函數等等),做知識儲備,如果上述問題不懂,一定要去看哦,都可以找到答案。然後MFCC的提取過程就特別好理解。因爲我就是這麼學過來的!本文是我看了代碼以後做的總結,我覺得這篇總結有些東西寫的不清楚,就參考這個改的。

語音識別MFCC系列(一)——連續信號、傅里葉變換

語音識別MFCC系列(二)——離散信號、離散傅里葉變換

語音識別MFCC系列(三)——離散餘弦變換DCT

 

                                  

 一、數據準備

格式爲.wav的音頻文件,可以從這裏下載,.wav文件存儲的是錄音設備按固定頻率採取的真實聲波的某個點。

                             

採樣頻率一般爲8000Hz和16000Hz,採樣頻率需要大於真實信號最大頻率的2倍,纔不會導致頻譜混疊。比如聲卡採樣率是8000HZ,那麼可以認爲原始信號的最大頻率處是4000HZ,注意,原始信號的源頭是聲帶一張一合把肺部氣體排出,這一張一合的頻率叫做基音頻率(聲音波由3個階段,聲帶發出的基音頻率是第一階段;第二階段是氣體聲波經過長約17cm的聲道,據說第二階段作爲聲音音色音質以及文本無關聲紋識別中的重要部位,也是共振峯產生的場所;第三階段是脣口鼻舌,這些部位影響聲音的發音,比如元音輔音等),爲了理解清晰,原始信號的頻率可以默認爲是聲帶一張一合的頻率,而聲卡採樣頻率則是1秒鐘採取多少個點,所以這兩者有本質的區別,但都是頻率。

使用python(scipy和numpy庫)的(rate,signal) = scipy.io.wavfile.read("Ansel.wav"),讀取信號signal = [ 0 0 -1 ..., 627 611 702],這是個含有107000個元素的數組,還可以得到該聲音文件的採樣頻率,此處頻率rate=8000Hz。

二,預加重,{A(1*107000)}

個人理解爲,由於聲帶和嘴脣的效應,人的發音系統會抑制語音信號的高頻部分,那麼低頻段能量大,高頻段能量小,高頻部分的幅值會比較小,高頻部分的信噪比(信號幅值/噪音幅值)比較小,換言之,你能從一堆茂密高大的雜草裏找到你種的那根正品草嗎!預加重就是解決這些問題的,相當於高通濾波器,提高高頻部分啦。

                                                                s _ { 2 } ( n ) = s ( n ) - \alpha s ( n - 1 )

一般\alpha取值爲0.95/0.97。

做法:signal = [ 0 0 -1 ..., 627 611 702]含有107000個點,針對這些點,套用公式signal[i]=signal[i+1]-0.97*signal[i],得到一個新的數組A=[ 0. 0. -1. ..., -40.36 2.81 109.33],數組大小還是107000。

三,分幀,{B(1336*200)}

                                                     

分幀原理就不說了,做法:把上述數組A的元素值,200個爲一幀,80個爲幀移,總共可以得到1336幀,因爲不是整除,1336*80+200=107080,多出的80個點用0填補,所以得到1336*200的二維數組B。

上述200個爲一幀,80個爲幀移是這樣來的,因爲默認語音信號具有短時平穩性,這平穩性不是說短時採樣得到的值相等,而是認爲短時間內聲帶、聲道、脣口鼻腔這3個聲音信號源頭具有平穩性,據說是人體肌肉活動短時平穩。短時默認是0.025s,兩個相鄰短時間隔默認是0.01s,因爲我分析的.wav文件是8000HZ, 所以0.025s內有0.025*8000=200個採樣點,幀移0.01*8000=80個採樣點。

四,加窗,{C(1336*200)}

漢明窗函數是一個餘弦函數,作用是爲了緩解頻率混疊,接下來說下具體怎麼加窗。設一幀內信號是S ( n ) , n = 0,1 , \dots , N - 1,則乘上漢明窗後爲S ^ { \prime } ( n ) = S ( n ) * W ( n ),其中漢明窗爲:

                             W ( n , a ) = ( 1 - a ) - a \cos ( 2 \pi n / ( N - 1 ) ) , 0 \leq n \leq N - 1

不同的a產生不同的漢明窗,通常a取0.46。我們根據上式得到一個1336*200的窗數組C。分幀後的數組B和窗函數數組C具有相同的維度,把它們對應位置的元素值相乘,即可以得到加窗後的二維數組C,C[i[j]=B[i][j]*C[i][j]]。

五,離散傅里葉變換(DFT),{D(1336*257),E(1336*257),F(1336*1)}

已知經過加窗後的信號C具有1336*200維,也就是說有1336行(幀),每行200個點,每相鄰兩行之間有120個重合點(幀移80)。那麼對它做DFT,做法:對有1336幀,每一幀都作N=512的DFT(N爲2的冪次方可做快速傅里葉變換),得到257個頻率分量。得到1336*257維的頻域信號D,幀數還是1336,對每一幀的257個點的值(個人認爲是振幅)取平方,再乘以1/512,便得到1336*257的能量密度譜,然後對每一幀的257個能量值簡單相加,得到該幀的能量總值,一共有1336幀,於是有1336個能量總值,即擁有1336個元素值,記爲數組F,數組中每個元素值代表一幀的能量總值。

六,獲得梅爾濾波器{G(26*257)}

                                                

如上圖,梅爾值是一個新的量度,相比頻率量度,梅爾更接近人耳的聽覺機理,通俗的說,就像納米和米一樣,如果我們用納米衡量我們身邊的事物會是一種什麼感受?所以頻率f的某一個值對應着梅爾的某一個值m,該映射關係可以用下式描述:

                                                                 m = 2595 \log _ { 10 } \left( 1 + \frac { f } { 700 } \right)

                                                                 f = 700 \left( 10 ^ { m / 2595 } - 1 \right)

我們看第一個公式,我們的採樣頻率除以2就是真實信號的最大頻率,真實信號的最小頻率爲0,依據公式的單調性,我們以這個最大頻率和最小頻率爲界限分別得到梅爾刻度的最大最小值,可以把信號的所有頻率值刻畫在這個梅爾區間之內。梅爾濾波器個數一般默認26個,在上述最大最小梅爾區間等間距插入26個值,包括邊界,就是28個梅爾值m,算出對應28個頻率值f。接下來對這28個頻率值,依次代入公式

                                                                       k=\frac{(512+1)*f}{8000}

便可以得到28個k值,k位於0-256。512是傅利葉變換的N,8000是採樣頻率。這個式子是把頻率對應到頻譜中257個頻率分量的某個,比如說之前算的f是2000,而257個頻率分量的第200個頻率是2000,那求出的k就是200。

                                  

三角濾波器如上圖所示,橫座標是0-256,頻率響應定義爲:

                                H _ { m } ( k ) = \left\{ \begin{array} { l } { 0 , k < f ( m - 1 ) } \\ { \frac { 2 ( k - f ( m - 1 ) ) } { ( f ( m + 1 ) - f ( m - 1 ) ( f ( m ) - f ( m - 1 ) ) } , f ( m - 1 ) \leq k \leq f ( m ) } \\ { \frac { 2 ( f ( m + 1 ) - k ) } { ( f ( m + 1 ) - f ( m - 1 ) ) ( f ( m ) - f ( m - 1 ) ) } , f ( m ) \leq k \leq f ( m + 1 ) } \\ { 0 , k \geq f ( m + 1 ) } \end{array} \right.

 上式中的m代表第幾個濾波器,k爲橫座標0-256。26個濾波器就是算257個頻率分量分別屬於26個頻率帶的概率,舉個不嚴密例子哈,第一個濾波器的頻率帶是0-10,那麼第250個頻率分量很明顯不屬於這個頻率帶,那這個概率就是0,那第5個頻率分量很明顯位於頻率帶的中心,那這個概率就是1。接下來根據上式計算26個濾波器的二維數組,也就是26*257二維數組G。

 

七,得到能量特徵參數的和能量總值{H(1336*26)}

因爲我們上一步已經算出257個頻率分量分別屬於26個頻率帶的概率(這裏有點像模糊聚類啦),那我們就按這個概率乘以頻率分量對應的能量相加,就是算出26個頻率帶對應的能量啦!爲什麼呢,因爲人耳可能分辨不出相差很小的頻率,就是說一個頻率帶的聽起來沒差,那我們就不需要那麼細緻的算每個分量的能量,而只要算出每個頻率帶的能量即可!

做法:把第五步得到的二維矩陣能量譜E(1336*257),乘以第六部的二維數組梅爾濾波器G(26*257)的轉置,矩陣的轉置可得到257*26的矩陣,然後滿足矩陣乘法定律,得到參數H=E*G.T,此處的H其實是1336*26的二維矩陣。

還有個參數是第五步計算出來的每幀能量總值F(1336*1),即擁有1336個元素值的一維數組F。

八,作自然對數運算,離散餘弦變換(DCT)和升倒譜運算{J(1336*13),K(13*1),L(1336*13),feat[1336*13]}

對H的每一個元素值做ln運算,即H[i][j]=ln(H[i][j]),據說是因爲人耳聽到的聲音大小和信號本身的大小是冪次方關係,所以要求個對數。接着對feat的每一行做DCT。因爲大部分信號數據一般集中在變換後的低頻區,所以對每一幀只取前13個數據就好了,於是得到1336*13的二維數組J。

針對1336*13的二維數組J做升倒譜操作(升倒譜我不懂),默認升倒譜系數爲22,這個過程做法是先產生一個擁有13個元素的一維數組K,這13個元素的值K[i]=1+(22 /2)*sin(pi*i/22),其中22是升倒譜系數,pi是圓周率3.1415926。得到這個數組K之後,針對1336*13的二維數組J,J[i][j] = J[i][j]*K[j],得到1336*13的二維數組L,這其實就是mfcc參數的第一組。如果這組參數想要加上能量作爲其表示方式,可以把這1336幀,也就是每一行的的第一個元素用一維數組F的每個值替換,即L[i][0] = F[i]。

我們把這經過錯綜複雜得到的L記爲feat,它是個二維數組,擁有1336*13個值,這也是mfcc參數的基礎參數,也是第一組,默認是有3組,接下來計算第二和第三組參數。

九,計算第二組和第三組參數{feat[1336*13],feat'[1336*13],feat''[1336*13]}

第二組參數其實就是在已有的基礎參數下作一階微分操作,第三組參數在第二組參數下作一階微分操作,這裏的微分採用下式,這個式子來自何強,何英的“Matlab擴展編程”一書:

                                                               d _ { t } = \frac { \sum _ { n = 1 } ^ { N } n \left( c _ { t + n } - c _ { t - n } \right) } { 2 \sum _ { n = 1 } ^ { N } n ^ { 2 } }

其中t爲第幾幀,n爲該幀前後第幾個,N爲 n的最大值,一般取2。

 

做法:抽取一個計算一階微分的函數,然後把1336*13的二維數組feat作爲參數傳入,返回feat的一階微分feat‘,feat'同樣有1336*13個元素值。其實這個過程是把feat按照行作循環,每一行擁有13個元素值,如果不考慮邊際效應,feat'[i][j]={feat[i+1][j]-feat[i-1][j] + 2(feat[i+2][j]-feat[i-2][j]) + 3(feat[i+3][j]-feat[i-3][j]) + ... + n(feat[i+n][j]-feat[i-n][j])} / M,M作爲分母,是這個函數輸入的big_theta來決定的,big_theta默認值是2,此處的M值可以算出是10,過程參照函數代碼。最後得到的輸出是1336*13的二維數組feat',也是mfcc參數的第二組參數。

第三組參數同上,把feat'作爲參數運用抽取出來的函數作計算,得到輸出記爲feat'',feat''二維數組同樣有1336*13個元素值,這是mfcc參數的第三組參數。

十,得到最後輸出{mfcc(1336*39)}

由前八步和第九步,可以得到feat,feat'和feat'',這3個參數都是擁有1336*13個元素值的二維數組,而且這三個二維數組的每一行第一個元素值可以根據需要,用該行(幀)的能量總值替換。把feat,feat‘和feat''拼在一起,即基於feat,每一行橫向追加feat'和feat''每行的元素值,得到擁有1336*39個元素值的一個二維數組,也就是mfcc係數,這就是最後得到的結果。

得到的mfcc係數,可供語音識別或聲紋識別(文本無關,文本相關)等技術,但語音識別需要語料庫,因此還需要建立語音模型來訓練語音,經典的語音模型有HMM,新興的有神經元模型。

 

參考網址:https://zhuanlan.zhihu.com/p/27416870

                  http://practicalcryptography.com/miscellaneous/machine-learning/guide-mel-frequency-cepstral-coefficients-mfccs/#computing-the-mel-filterbank

                  https://haythamfayek.com/2016/04/21/speech-processing-for-machine-learning.html

                  https://blog.csdn.net/TH_NUM/article/details/80597495

                  https://blog.csdn.net/shichaog/article/details/72809261

                  https://my.oschina.net/zzw922cn/blog/533175

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章