1. 程式人生 > >論文筆記:語音情感識別(四)語音特徵之聲譜圖,log梅爾譜,MFCC,deltas

論文筆記:語音情感識別(四)語音特徵之聲譜圖,log梅爾譜,MFCC,deltas

一:原始訊號
從音訊檔案中讀取出來的原始語音訊號通常稱為raw waveform,是一個一維陣列,長度是由音訊長度和取樣率決定,比如取樣率Fs為16KHz,表示一秒鐘內取樣16000個點,這個時候如果音訊長度是10秒,那麼raw waveform中就有160000個值,值的大小通常表示的是振幅。

二:(線性)聲譜圖
(1)對原始訊號進行分幀加窗後,可以得到很多幀,對每一幀做FFT(快速傅立葉變換),傅立葉變換的作用是把時域訊號轉為頻域訊號,把每一幀FFT後的頻域訊號(頻譜圖)在時間上堆疊起來就可以得到聲譜圖,其直觀理解可以形象地表示為以下幾個圖,圖源見參考資料[1]。
(2)有些論文提到的DCT(離散傅立葉變換)和STFT(短時傅立葉變換)其實是差不多的東西。STFT就是對一系列加窗資料做FFT。而DCT跟FFT的關係就是:FFT是實現DCT的一種快速演算法。
(3)FFT有個引數N,表示對多少個點做FFT,如果一幀裡面的點的個數小於N就會zero-padding到N的長度。對一幀訊號做FFT後會得到N點的複數,這個點的模值就是該頻率值下的幅度特性。每個點對應一個頻率點,某一點n(n從1開始)表示的頻率為\(F_n = (n-1)*Fs/N\)

,第一個點(n=1,Fn等於0)表示直流訊號,最後一個點N的下一個點(n=N+1,Fn=Fs時,實際上這個點是不存在的)表示取樣頻率Fs。
(4)FFT後我們可以得到N個頻點,頻率間隔(也叫頻率解析度或)為 Fs / N,比如,取樣頻率為16000,N為1600,那麼FFT後就會得到1600個點,頻率間隔為10Hz,FFT得到的1600個值的模可以表示1600個頻點對應的振幅。因為FFT具有對稱性,當N為偶數時取N/2+1個點,當N為奇數時,取(N+1)/2個點,比如N為512時最後會得到257個值。
(5)用python_speech_feature庫時可以看到有三種聲譜圖,包括振幅譜,功率譜,log功率譜。振幅譜就是fft後取絕對值。功率譜就是在振幅譜的基礎上平方然後除以N。log功率譜就是在功率譜的基礎上取10倍lg,然後減去最大值。得到聲譜圖矩陣後可以通過matplotlib來畫圖。
(6)常用的聲譜圖都是STFT得到的,另外也有用CQT(constant-Q transform)得到的,為了區分,將它們分別稱為STFT聲譜圖和CQT聲譜圖。



三:梅爾聲譜圖
(1)人耳聽到的聲音高低和實際(Hz)頻率不呈線性關係,用Mel頻率更符合人耳的聽覺特性(這正是用Mel聲譜圖的一個動機,由人耳聽力系統啟發),即在1000Hz以下呈線性分佈,1000Hz以上呈對數增長,Mel頻率與Hz頻率的關係為\(f_{mel} = 2595 \cdot lg(1+\frac{f}{700Hz})\),如下圖所示,圖源見參考資料[2]。有另一種計算方式為\(f_{mel} = 1125 \cdot ln(1+\frac{f}{700Hz})\)。下面給出一個計算Mel聲譜圖的例子。另,python中可以用librosa調包得到梅爾聲譜圖。

(2)假設現在用10個Mel filterbank(一些論文會用40個,如果求MFCC一般是用26個然後在最後取前13個),為了獲得filterbanks需要選擇一個lower頻率和upper頻率,用300作為lower,8000作為upper是不錯的選擇。如果取樣率是8000Hz那麼upper頻率應該限制為4000。然後用公式把lower和upper轉為Mel頻率,我們使用上述第二個公式(ln那條),可以得到401.25Mel 和 2834.99Mel。
(3)因為用10個濾波器,所以需要12個點來劃分出10個區間,在401.25Mel和2834.99Mel之間劃分出12個點,m(i) = (401.25, 622.50, 843.75, 1065.00, 1286.25, 1507.50, 1728.74, 1949.99, 2171.24, 2392.49, 2613.74, 2834.99)。
(4)然後把這些點轉回Hz頻率,h(i) = (300, 517.33, 781.90, 1103.97, 1496.04, 1973.32, 2554.33, 3261.62, 4122.63, 5170.76, 6446.70, 8000)。
(5)把這些頻率轉為fft bin,f(i) = floor( (N+1)*h(i)/Fs),N為FFT長度,預設為512,Fs為取樣頻率,預設為16000Hz,則f(i) = (9, 16, 25, 35, 47, 63, 81, 104, 132, 165, 206, 256)。這裡256剛好對應512點FFT的8000Hz。
(6)然後建立濾波器,第一個濾波器從第一個點開始,在第二個點到達最高峰,第三個點跌回零。第二個濾波器從第二個點開始,在第三個點到達最大值,在第四個點跌回零。以此類推。濾波器的示意圖如下圖所示,圖源見參考資料[3]。可以看到隨著頻率的增加,濾波器的寬度也增加。

(7)接下來給出濾波器輸出的計算公式,如下所示,其中m從1到M,M表示濾波器數量,這裡是10。k表示點的編號,一個fft內256個點,k從1到256,表示了fft中的256個頻點(k=0表示直流訊號,算進來就是257個頻點,為了簡單起見這裡省略k=0的情況)。
\[H_m(k) = \left\{\begin{matrix} \frac{k-f(m-1)}{f(m)-f(m-1)} & f(m-1) \leq k \leq f(m)\\ \frac{f(m+1)-k}{f(m+1)-f(m)} & f(m) \leq k \leq f(m+1) \\ 0 & others \\ \end{matrix}\right.\]
(8)最後還要乘上fft計算出來的能量譜,關於能量譜在前一節(線性)聲譜圖中已經講過了。將濾波器的輸出應用到能量譜後得到的就是梅爾譜,具體應用公式如下,其中\(|X(k)|^2\)表示能量譜中第k個點的能量。以每個濾波器的頻率範圍內的輸出作為權重,乘以能量譜中對應頻率的對應能量,然後把這個濾波器範圍內的能量加起來。舉個例子,比如第一個濾波器負責的是9和16之間的那些點(在其它範圍的點濾波器的輸出為0),那麼只對這些點對應的頻率對應的能量做加權和。
\[MelSpec(m) = \sum_{k=f(m-1)}^{f(m+1)} H_m(k) * |X(k)|^2\]
(9)這樣計算後,對於一幀會得到M個輸出。經常會在論文中看到說40個梅爾濾波器輸出,指的就是這個(實際上前面說的梅爾濾波器輸出是權重H,但是這裡的意思應該是將濾波器輸出應用到聲譜後得到的結果,根據上下文可以加以區分)。然後在時間上堆疊多個“40個梅爾濾波器輸出”就得到了梅爾尺度的聲譜(梅爾譜),如果再取個log,就是log梅爾譜,log-Mels。
(10)把濾波器範圍內的能量加起來,可以解決一個問題,這個問題就是人耳是很難理解兩個靠的很近的線性頻率(就是和梅爾頻率相對應的赫茲頻率)之間不同。如果把一個頻率區域的能量加起來,只關心在每個頻率區域有多少能量,這樣人耳就比較能區分,我們希望這種方式得到的(Mel)聲譜圖可以更加具有辨識度。最後取log的motivation也是源於人耳的聽力系統,人對聲音強度的感知也不是線性的,一般來說,要使聲音的音量翻倍,我們需要投入8倍的能量,為了把能量進行壓縮,所以取了log,這樣,當x的log要翻倍的話,就需要增加很多的x。另外一個取log的原因是為了做倒譜分析得到MFCC,具體細節見下面MFCC的介紹。

四:MFCC
(1)MFCC,梅爾頻率的倒譜系數,是廣泛應用於語音領域的特徵,在這之前常用的是線性預測係數Linear Prediction Coefficients(LPCs)和線性預測倒譜系數(LPCCs),特別是用在HMM上。
(2)先說一下獲得MFCC的步驟,首先分幀加窗,然後對每一幀做FFT後得到(單幀)能量譜(具體步驟見上面線性聲譜圖的介紹),對線性聲譜圖應用梅爾濾波器後然後取log得到log梅爾聲譜圖(具體步驟見上面梅爾聲譜圖的介紹),然後對log濾波能量(log梅爾聲譜)做DCT,離散餘弦變換(傅立葉變換的一種),然後保留第二個到第13個係數,得到的這12個係數就是MFCC。
(3)然後再大致說說MFCC的含義,下圖第一個圖(圖源見參考資料[1])是語音的頻譜圖,峰值是語音的主要頻率成分,這些峰值稱為共振峰,共振峰攜帶了聲音的辨識(相當於人的身份證)。把這些峰值平滑地連起來得到的曲線稱為頻譜包絡,包絡描述了攜帶聲音辨識資訊的共振峰,所以我們希望能夠得到這個包絡來作為語音特徵。頻譜由頻譜包絡和頻譜細節組成,如下第二個圖(圖源見參考資料[1])所示,其中log X[k]代表頻譜(注意圖中給出的例子是赫茲譜,這裡只是舉例子,實際我們做的時候通常都是用梅爾譜),log H[k]代表頻譜包絡,log E[k]代表頻譜細節。我們要做的就是從頻譜中分離得到包絡,這個過程也稱為倒譜分析,下面就說說倒譜分析是怎麼做的。

(4)要做的其實就是對頻譜做FFT,在頻譜上做FFT這個操作稱為逆FFT,需要注意的是我們是在頻譜的log上做的,因為這樣做FFT後的結果x[k]可以分解成h[k]和e[k]的和。我們先看下圖(圖源見參考資料[1]),對包絡log H[k]做IFFT的結果,可以看成“每秒4個週期的正弦波”,於是我們在偽頻率軸上的4Hz上給一個峰值,記作h[k]。對細節log E[k]做IFFT的結果,可以看成“每秒100個週期的正弦波”,於是我們在偽頻率軸上的100Hz上給一個峰值,記作e[k]。對頻譜log X[k]做IFFT後的結果記作x[k],這就是我們說的倒譜,它會等於h[k]和e[k]的疊加,如下第二個圖所示。我們想要得到的就是包絡對應的h[k],而h[k]是x[k]的低頻部分,只需要對x[k]取低頻部分就可以得到了。

(5)最後再總結一下得到MFCC的步驟,求線性聲譜圖,做梅爾濾波得到梅爾聲譜圖,求個log得到log梅爾譜,做倒譜分析也就是對log X[k]做DCT得到x[k],取低頻部分就可以得到倒譜向量,通常會保留第2個到第13個係數,得到12個係數,這12個係數就是常用的MFCC。圖源見參考資料[1]。

五:deltas,deltas-deltas
(1)deltas和deltas-deltas,看到很多人翻譯成一階差分和二階差分,也被稱為微分系數和加速度係數。使用它們的原因是,MFCC只是描述了一幀語音上的能量譜包絡,但是語音訊號似乎有一些動態上的資訊,也就是MFCC隨著時間的改變而改變的軌跡。有證明說計算MFCC軌跡並把它們加到原始特徵中可以提高語音識別的表現。
(2)以下是deltas的一個計算公式,其中t表示第幾幀,N通常取2,c指的就是MFCC中的某個係數。deltas-deltas就是在deltas上再計算以此deltas。
\[d_t = \frac{\sum_{n=1}^{N} n(c_{t+n}-c_{t-n})}{2 \sum_{n=1}^{N} n^2}\]
(3)對MFCC中每個係數都做這樣的計算,最後會得到12個一階差分和12個二階差分,我們通常在論文中看到的“MFCC以及它們的一階差分和二階差分”指的就是這個。
(4)值得一提的是deltas和deltas-deltas也可以用在別的引數上來表述動態特性,有論文中是直接在log Mels上做一階差分和二階差分的,論文筆記:語音情感識別(二)聲譜圖+CRNN中3-D Convolutional Recurrent Neural Networks with Attention Model for Speech Emotion Recognition這篇論文就是這麼做的。

六:參考資料
[1] CMU語音課程slides

[2] 一個MFCC的介紹教程

[3] csdn-MFCC計算過程

[4] 部落格園-MFCC學習筆記