Speech recognition using neural network

Winston Chen
Taiwan AI Academy
Published in
9 min readOct 8, 2019

Overview

自從 deep learning 蓬勃發展後,在語音辨識的領域上也取得了巨大的成功,現今生活中,許多語音助理就在我們身邊!各個科技大老例如:Google、Amazon 與 Apple 紛紛推出自家的語音助理,而我們僅需要簡單的言語指令,語音助理就可以完成如:訂購披薩、說笑話或是搜尋各種資料,當然要完成這些指令並不是想像的這麼簡單,中間需要透過一系列的”黑盒子”處理,首先就是要取得聲音,接著利用語音辨識將聲音轉換為文字,最後則是讓機器”理解”自然語言,而本文主要講述如何透過 neural network 實作簡單語音辨識。

本文使用 Tensorflow Speech Recognition Challenge 提供的 dataset,下載連結在此

1. 什麼是聲音訊號?

聲音是介質振動產生的聲波,而聲波會引起介質 — 空氣分子有節奏的振動,使空氣產生疏密變化,形成疏密相間的縱波,而透過麥克風與音效介面,我們可以將縱波轉換為數位訊號,而這一過程稱之為”取樣”,我們可以將空氣中的縱波想像為 S(t) ,每隔 T 時間,就取樣得到 Si,而 1/T 則 稱之為取樣頻率 (Hz),代表著一秒能夠取得的 samples 數量,而 Nyquist theorem 要求取樣頻率必須夠高才不會導致訊號失真,在這裡我並不著重於訊號處理的細節,主要是想告訴大家,使用程式碼將音檔讀進來後,得到的會是一維的矩陣,值域範圍為 -1 ~ 1,如果是二維的矩陣則是雙聲道的音檔。

https://en.wikipedia.org/wiki/Sampling_(signal_processing)

2. Preprocessing

Librosa 是 python 中一個強大的語音訊號處理的 package,接著我會使用 librosa 來做訊號的前處理。

import librosasignal, fs = librosa.load('up/0a7c2a8d_nohash_0.wav', sr = 16000)window_length = int(0.04 * fs)
hopping_length = int(0.01 * fs)
stft = librosa.core.stft(signal, n_fft = window_length, win_length = window_length, hop_length = hopping_length)
spectrogram = librosa.amplitude_to_db(stft)

在使用 librosa.load 時,可以自己定義取樣頻率,如果定義的取樣頻率大於原始的取樣頻率,函式會自動做 upsampling,反之,則會做 downsampling,而這份 dataset 原始的取樣頻率就是為 16 kHz,一般來說在語音處理的應用中,由於人的語音頻率範圍大部分都低於 1 kHz,所以通常取樣頻率為 8 kHz 或是 16 kHz,這樣可以大大的降低資料量,加快訓練的速度。

下圖左是讀進來 “up” 的聲波圖,又稱之為時域圖,在語音處理中,一般不會直接使用時域圖,因為很難從這樣一張圖得到我們想要知道的資訊,例如:頻率,所以我們會將訊號做 Short-time Fourier Transform (STFT)得到時頻譜 (spectrogram),而時頻圖能提供許多資訊,幫助我們理解時間與頻率的關係,簡單來說就像是一張較複雜的五線譜。

本文中不會特別講解什麼是傅立葉轉換 (Fourier Transform),只需要知道她的概念就是將原始的時域訊號轉換為頻域訊號,可以讓人一目了然的知道說聲音的頻率是多少,而短時距傅立葉變換 (STFT)則是將時間與頻率結合在一起,可以從時頻譜中清楚的知道哪個時間點出現了哪個頻率的聲音,如下圖,在時域圖中可以很清楚的看到,聲音大約在 0.4 秒出現,而透過時頻圖可以更近一步的知道,在 0.4 秒出現的聲音的頻率是多少,時頻圖就像是五線譜,縱軸是頻率的高低,橫軸是時間的推移,而亮度則表示了能量的大小。

此外,一般而言在處理聲音訊號時,會將訊號的值域轉為 dB scale,這是因為人的耳朵對於聲音大小的感知程度不是線性而是比較類似 dB scale。

如果對於時頻圖有興趣,其實還有其他方法可以得到時頻圖,例如:Contstant-Q transfomr、Mel-frequency spectrogram 或是 Mel-frequency Cepstrum Coefficients,這些方法是短時距傅立葉變換 (STFT) 的進階,可以將原本的時頻圖降到更低的維度,訓練時間會更快,準確程度則是要視模型的設計。

在接下來的模型訓練中,我們只使用了 0 ~ 9 數字實作語音辨識,在這份資料中,每一個單字都有同一個人念了好幾次的音檔,而常見的 80–20 訓練資料與驗證資料的切分對於語音辨識來說並不是一個好的方法,因為同一個人講話的方式通常是一樣的,如果同時出現在訓練資料與驗證資料中,很容易造成模型 overfitting,所以通常在切分訓練資料與驗證資料時,會以人為單位做切分的動作,才能確保語音辨識真的能夠應用到不同人、性別、種族或是口音,而不是只能應用在特定的訓練資料上。

3. Speech recognition using Long Short-Term Memory

人類的語音與時間有著非常重要的關係,所以非常適合使用 Recurrent neural network 這類能夠捕捉時序上的模型訓練,而這裡我們單純建構兩層 hidden layer 的 LSTM,就能夠達到不錯的效果。

首先,LSTM 的模型必須先設定每一層 hidden layer 的 neural 數量,在 tensorflow 中有許多不同 RNN 的 cell 可以選擇,常見的如:RNN、GRU 與 LSTM,在本文中選擇的是 LSTM cell,接著給定同一層 hidden layer 的 dropout 比例,最後使用 MultiRNNCell 將設定完成的每一層 hidden layer 間構成完整的 LSTM 網路,與此同時,要將所有 state 的初始值設定為 0。

接下來就可以開始訓練 LSTM 的網路囉!tensorflow 中提供了常使用的兩種訓練方式,分別是 static_rnn 與 dynamic_rnn,static_rnn 在計算網路前,會先將網路 unroll,如下圖等式右邊,而 dynamic_rnn 則相反,兩者的差別在於,由於 static_rnn 先將整個網路 unroll,所以計算速度會較 dynamic_rnn 快,但是缺點是,由於已經將整個 graph 設定好,所以全部資料的時間序列必須要相同,而 dynamic_rnn 只需要確保在每一筆 batch 中的資料時間序列相同就好。

dhttp://colah.github.io/posts/2015-08-Understanding-LSTMs/

本文所使用的是 tensorflow 中的 dynamic_rnn 的函式,而通過 dynamic_rnn 的計算過後會得到兩個輸出,一個是模型的輸出,另一個則是模型的 state,在 LSTM 中,每一個時間序列上的資料點都會計算出一個輸出,通常只會取最後一個時間序列計算得到的輸出繼續做後續的處理,這是因為最後一個時間序列的輸出是使用前面所有資料訓練後得到的結果,這才是我們想要的輸出,將之取出後便可以接上傳統的 neural network 預測結果。

在訓練 LSTM 過程中,與其他網路較不一樣的地方為:為了避免 LSTM 太容易梯度爆炸 (gradient explosion),所以通常會將計算得到的 gradient 縮減到特定範圍內,這時候就無法像在訓練 DNN 或是 CNN 時,直接計算 loss 然後使用 optimizer 更新gradient,而是先使用 optimizer 針對 loss 計算出 gradient,然後將 gradient 縮減到指定範圍內,再將 gradient 丟進 optimizer。

4. Speech recognition using Convolution Neural Network

透過 STFT 轉換後得到的時頻圖也可以視為另類的圖片,所以本文也嘗試用 CNN 訓練語音辨識。

由於時頻圖的結構簡單,相較於一般動物或是物品的圖片較不複雜,所以不太需要用到太深層的網路,這裡僅僅使用三層的 CNN 就得到不錯的結果。

5. Result

下圖左右分別為 CNN 與 LSTM 的結果,從結果上來看 CNN 的準確率略高於 LSTM,不過皆已經達到不錯的效果,不過在訓練時間上,兩者的差異非常大,CNN 的訓練速度大約為 LSTM 的十倍左右。

Accuracy of CNN and LSTM

6. Conclusion

要完成一個很好的語音辨識,除了設計好的模型以外,聲音訊號的前處理也是一大重點,除了本文中提到的時頻轉換外,噪音往往會影響語音辨識的準確率,而這次使用的 dataset 語音品質很高,所以不需要特別對訊號進行降噪。

這只是一個非常簡單的語音辨識網路,由於本文只著重於十個單字,所以能夠得到不錯的結果,但是在實際應用上,語音辨識必須要處理世界上數以萬計的語音,所以並沒有想像中的那麼容易,不過如果想實作 real-time 的喚醒功能如:”Hey, Siri” 或是 “OK, google” 則是可以透過簡單的語音辨識網路就可以達成,快動手打造一個專屬自己的語音助理吧!

Reference

--

--