吳恩達教授曾經預言過,當語音識別的準確度從95%提高到99%的時候,它將成爲與電腦交互的首要方式。web
下面就讓咱們來學習與深度學習進行語音室識別吧!數據庫
機器學習並不老是一個黑盒網絡
若是你想知道神經機器翻譯是如何工做的,你應該猜到了咱們能夠簡單地將一些聲音送入神經網絡,而後訓練它使之生成文本:app
這是使用深度學習進行語音識別的最高追求,可是很遺憾咱們如今尚未徹底作到這一點(至少在筆者寫下這一篇文章的時候尚未–我敢打賭,再過幾年咱們能夠作到)機器學習
一個大問題是語速不一樣。一我的可能會很快的說出」Hello!」,而另外一我的可能很是緩慢的說」heeeelllllllllllllooooo’!’,產生了一個擁有更多數據也更長的聲音文件。這兩個文件都應該被識別爲同一個文本–「Hello!」。而事實證實,把各類長度的音頻文件自動對齊到一個固定長度的文本是很難的一件事情。學習
爲了解決這個問題,咱們必須使用一些特殊的技巧,並進行一些深度神經網絡之外的特殊處理。讓咱們看看它是如何工做的吧!大數據
顯然,語音識別的第一步是–咱們須要將聲波輸入到電腦中。ui
咱們應該怎麼將聲波轉換爲數字呢?讓咱們使用我說的「hello」這個聲音片斷舉個例子:翻譯
聲波是一維的,它在每一個時刻都有一個基於其高度的值。讓咱們把聲波的一小部分放大看看:3d
爲了將這個聲波轉換成數字,咱們只記錄聲波在等距點的高度:
這被稱爲採樣(sampling)。咱們每秒讀取數千次,並把聲波在該時間點的高度用一個數字記錄下來。這基本上就是一個未壓縮的 .wav 音頻文件。
「CD 音質」的音頻是以 44.1khz(每秒 44100 個讀數)進行採樣的。但對於語音識別,16khz(每秒 16000 個採樣)的採樣率就足以覆蓋人類語音的頻率範圍了。
讓咱們把「Hello」的聲波每秒採樣 16000 次。這是前 100 個採樣:
每一個數字表明聲波在一秒鐘的16000分之一處的振幅。
由於聲波採樣只是間歇性的讀取,你可能認爲它只是對原始聲波進行粗略的近似估計。咱們的讀數之間有間距,因此咱們必然會丟失數據,對吧?
可是,因爲採樣定理(Nyquist theorem),咱們知道咱們能夠利用數學,從間隔的採樣中完美重建原始聲波——只要咱們的採樣頻率比指望獲得的最高頻率快至少兩倍就行。
我提這一點,是由於幾乎每一個人都會犯這個錯誤,並誤認爲使用更高的採樣率老是會得到更好的音頻質量。其實並非。
咱們如今有一個數列,其中每一個數字表明 1/16000 秒的聲波振幅。
咱們能夠把這些數字輸入到神經網絡中,可是試圖直接分析這些採樣來進行語音識別仍然很困難。相反,咱們能夠經過對音頻數據進行一些預處理來使問題變得更容易。
讓咱們開始吧,首先將咱們的採樣音頻分紅每份 20 毫秒長的音頻塊。這是咱們第一個 20 毫秒的音頻(即咱們的前 320 個採樣):
將這些數字繪製爲簡單的折線圖,咱們就獲得了這 20 毫秒內原始聲波的大體形狀:
雖然這段錄音只有 1/50 秒的長度,但即便是這樣短暫的錄音,也是由不一樣頻率的聲音複雜地組合在一塊兒的。其中有一些低音,一些中音,甚至有幾處高音。但總的來講,就是這些不一樣頻率的聲音混合在一塊兒,才組成了人類的語音。
爲了使這個數據更容易被神經網絡處理,咱們將把這個複雜的聲波分解成一個個組成部分。咱們將分離低音部分,再分離下一個最低音的部分,以此類推。而後將(從低到高)每一個頻段(frequency band)中的能量相加,咱們就爲各個類別的音頻片斷建立了一個指紋(fingerprint)。
想象你有一段某人在鋼琴上演奏 C 大調和絃的錄音。這個聲音是由三個音符組合而成的:C、E 和 G。它們混合在一塊兒組成了一個複雜的聲音。咱們想把這個複雜的聲音分解成單獨的音符,以此來分辨 C、E 和 G。這和語音識別是同樣的道理。
咱們須要傅里葉變換(Fourier Transform)來作到這一點。它將複雜的聲波分解爲簡單的聲波。一旦咱們有了這些單獨的聲波,咱們就將每一份頻段所包含的能量加在一塊兒。
最終獲得的結果即是從低音(即低音音符)到高音,每一個頻率範圍的重要程度。以每 50hz 爲一個頻段的話,咱們這 20 毫秒的音頻所含有的能量從低頻到高頻就能夠表示爲下面的列表:
可是把它們畫成圖表時會更容易理解:
你能夠看到,在咱們的 20 毫秒聲音片斷中有不少低頻能量,然而在更高的頻率中並無太多的能量。這是典型「男性」的聲音。
若是咱們對每一個20毫秒的音頻塊都重複這個過程,咱們最後會獲得一個頻譜圖(從左到右每一列都是一個29毫秒的音頻塊)
頻譜圖很酷,由於你能夠在音頻數據中實實在在地看到音符和其餘音高模式。對於神經網絡來講,相比於原始聲波,從這種數據中尋找規律要容易得多。所以,這就是咱們將要實際輸入到神經網絡中去的數據表示方式。
從短音頻中識別字符
如今咱們已經讓音頻轉變爲一個易於處理的格式了,如今咱們將要把它輸入深度神經網絡。神經網絡的輸入將會是 20 毫秒的音頻塊。對於每一個小的音頻切片(audio slice),神經網絡都將嘗試找出當前正在說的聲音所對應的字母。
咱們將使用一個循環神經網絡——即一個擁有記憶,能影響將來預測的神經網絡。這是由於它預測的每一個字母都應該可以影響它對下一個字母的預測。例如,若是咱們到目前爲止已經說了「HEL」,那麼頗有可能咱們接下來會說「LO」來完成「Hello」。咱們不太可能會說「XYZ」之類根本讀不出來的東西。所以,具備先前預測的記憶有助於神經網絡對將來進行更準確的預測。
當經過神經網絡跑完咱們的整個音頻剪輯(一次一塊)以後,咱們將最終獲得一份映射(mapping),其中標明瞭每一個音頻塊和其最有可能對應的字母。這是我說那句「Hello」所對應的映射的大體圖案:
咱們的神經網絡正在預測我說的那個詞頗有多是「HHHEE_LL_LLLOOO」。但它同時認爲我說的也多是「HHHUU_LL_LLLOOO」,或者甚至是「AAAUU_LL_LLLOOO」。
咱們能夠遵循一些步驟來整理這個輸出。首先,咱們將用單個字符替換任何重複的字符:
· HHHEE_LL_LLLOOO 變爲 HE_L_LO
· HHHUU_LL_LLLOOO 變爲 HU_L_LO
· AAAUU_LL_LLLOOO 變爲 AU_L_LO
而後,咱們將刪除全部空白:
· HE_L_LO 變爲 HELLO
· HU_L_LO 變爲 HULLO
· AU_L_LO 變爲 AULLO
這讓咱們獲得三種可能的轉寫——「Hello」、「Hullo」和「Aullo」。若是你大聲說出這些詞,全部這些聲音都相似於「Hello」。由於神經網絡每次只預測一個字符,因此它會得出一些純粹表示發音的轉寫。例如,若是你說「He would not go」,它可能會給出一個「He wud net go」的轉寫。
解決問題的訣竅是將這些基於發音的預測與基於書面文本(書籍、新聞文章等)大數據庫的可能性得分相結合。扔掉最不可能的結果,留下最實際的結果。
在咱們可能的轉寫「Hello」、「Hullo」和「Aullo」中,顯然「Hello」將更頻繁地出如今文本數據庫中(更不用說在咱們原始的基於音頻的訓練數據中了),所以它可能就是正解。因此咱們會選擇「Hello」做爲咱們的最終結果,而不是其餘的轉寫。搞定!
稍等一下!
你可能會想「可是若是有人說Hullo」怎麼辦?這個詞的確存在。也許「Hello」是錯誤的轉寫!
固然可能有人實際上說的是「Hullo」而不是「Hello」。可是這樣的語音識別系統(基於美國英語訓練)基本上不會產生「Hullo」這樣的轉寫結果。用戶說「Hullo」,它老是會認爲你在說「Hello」,不管你發「U」的聲音有多重。
試試看!若是你的手機被設置爲美式英語,嘗試讓你的手機助手識別單詞「Hullo」。這不行!它掀桌子不幹了,它老是會理解爲「Hello」。
不識別「Hullo」是一個合理的行爲,但有時你會碰到使人討厭的狀況:你的手機就是不能理解你說的有效的語句。這就是爲何這些語音識別模型老是處於再訓練狀態的緣由,它們須要更多的數據來修復這些少數狀況。