當前位置:
首頁 > 最新 > Python語音識別終極指南

Python語音識別終極指南

譯者 | 廉潔

編輯 | 明明

【AI科技大本營導讀】亞馬遜的 Alexa 的巨大成功已經證明:在不遠的將來,實現一定程度上的語音支持將成為日常科技的基本要求。整合了語音識別的 Python 程序提供了其他技術無法比擬的交互性和可訪問性。最重要的是,在 Python 程序中實現語音識別非常簡單。通過本指南,你將學到:

語音識別的工作原理;

PyPI 支持哪些軟體包;

如何安裝和使用 SpeechRecognition 軟體包——一個功能全面且易於使用的 Python 語音識別庫。


語音識別源於 20 世紀 50 年代早期在貝爾實驗室所做的研究。早期語音識別系統僅能識別單個講話者以及只有約十幾個單詞的辭彙量。現代語音識別系統已經取得了很大進步,可以識別多個講話者,並且擁有識別多種語言的龐大辭彙表。

語音識別的首要部分當然是語音。通過麥克風,語音便從物理聲音被轉換為電信號,然後通過模數轉換器轉換為數據。一旦被數字化,就可適用若干種模型,將音頻轉錄為文本。

大多數現代語音識別系統都依賴於隱馬爾可夫模型(HMM)。其工作原理為:語音信號在非常短的時間尺度上(比如 10 毫秒)可被近似為靜止過程,即一個其統計特性不隨時間變化的過程。

許多現代語音識別系統會在 HMM 識別之前使用神經網路,通過特徵變換和降維的技術來簡化語音信號。也可以使用語音活動檢測器(VAD)將音頻信號減少到可能僅包含語音的部分。

幸運的是,對於 Python 使用者而言,一些語音識別服務可通過 API 在線使用,且其中大部分也提供了 Python SDK。


PyPI中有一些現成的語音識別軟體包。其中包括:

?apiai

?google-cloud-speech

?pocketsphinx

?SpeechRcognition

?watson-developer-cloud

?wit

一些軟體包(如 wit 和 apiai )提供了一些超出基本語音識別的內置功能,如識別講話者意圖的自然語言處理功能。其他軟體包,如谷歌雲語音,則專註於語音向文本的轉換。

其中,SpeechRecognition 就因便於使用脫穎而出。

識別語音需要輸入音頻,而在 SpeechRecognition 中檢索音頻輸入是非常簡單的,它無需構建訪問麥克風和從頭開始處理音頻文件的腳本,只需幾分鐘即可自動完成檢索並運行。

SpeechRecognition 庫可滿足幾種主流語音 API ,因此靈活性極高。其中 Google Web Speech API 支持硬編碼到 SpeechRecognition 庫中的默認 API 密鑰,無需註冊就可使用。SpeechRecognition 以其靈活性和易用性成為編寫 Python 程序的最佳選擇。


SpeechRecognition 兼容 Python2.6 , 2.7 和 3.3+,但若在 Python 2 中使用還需要一些額外的安裝步驟。本教程中所有開發版本默認 Python 3.3+。

讀者可使用 pip 命令從終端安裝 SpeechRecognition:

安裝完成後請打開解釋器窗口並輸入以下內容來驗證安裝:

註:不要關閉此會話,在後幾個步驟中你將要使用它。

若處理現有的音頻文件,只需直接調用 SpeechRecognition ,注意具體的用例的一些依賴關係。同時注意,安裝 PyAudio 包來獲取麥克風輸入。


SpeechRecognition 的核心就是識別器類。

Recognizer API 主要目是識別語音,每個 API 都有多種設置和功能來識別音頻源的語音,分別是:

recognize_bing(): Microsoft Bing Speech

recognize_google(): Google Web Speech API

recognize_google_cloud(): Google Cloud Speech - requires installation of the google-cloud-speech package

recognize_houndify(): Houndify by SoundHound

recognize_ibm(): IBM Speech to Text

recognize_sphinx(): CMU Sphinx - requires installing PocketSphinx

recognize_wit(): Wit.ai

以上七個中只有 recognition_sphinx()可與CMU Sphinx 引擎離線工作, 其他六個都需要連接互聯網。

SpeechRecognition 附帶 Google Web Speech API 的默認 API 密鑰,可直接使用它。其他六個 API 都需要使用 API 密鑰或用戶名/密碼組合進行身份驗證,因此本文使用了 Web Speech API。

現在開始著手實踐,在解釋器會話中調用 recognise_google()函數。

屏幕會出現:

相信你已經猜到了結果,怎麼可能從空文件中識別出數據呢?

這 7 個recognize_*()識別器類都需要輸入audio_data參數,且每種識別器的audio_data都必須是 SpeechRecognition 的 AudioData 類的實例。

AudioData 實例的創建有兩種路徑:音頻文件或由麥克風錄製的音頻,先從比較容易上手的音頻文件開始。


首先需要下載音頻文件(https://github.com/realpython/python-speech-recognition/tree/master/audio_files),保存到 Python 解釋器會話所在的目錄中。

AudioFile 類可以通過音頻文件的路徑進行初始化,並提供用於讀取和處理文件內容的上下文管理器界面。

支持文件類型

SpeechRecognition 目前支持的文件類型有:

WAV: 必須是 PCM/LPCM 格式

AIFF

AIFF-C

FLAC: 必須是初始 FLAC 格式;OGG-FLAC 格式不可用

若是使用 Linux 系統下的 x-86 ,macOS 或者是 Windows 系統,需要支持 FLAC文件。若在其它系統下運行,需要安裝 FLAC 編碼器並確保可以訪問 flac 命令。

使用record()從文件中獲取數據

在解釋器會話框鍵入以下命令來處理 「harvard.wav」 文件的內容:

通過上下文管理器打開文件並讀取文件內容,並將數據存儲在 AudioFile 實例中,然後通過 record()將整個文件中的數據記錄到 AudioData 實例中,可通過檢查音頻類型來確認:

現在可以調用recognition_google()來嘗試識別音頻中的語音。

以上就完成了第一個音頻文件的錄製。

利用偏移量和持續時間獲取音頻片段

若只想捕捉文件中部分演講內容該怎麼辦?record()命令中有一個 duration 關鍵字參數,可使得該命令在指定的秒數後停止記錄。

例如,以下內容僅獲取文件前四秒內的語音:

在with塊中調用record()命令時,文件流會向前移動。這意味著若先錄製四秒鐘,再錄製四秒鐘,則第一個四秒後將返回第二個四秒鐘的音頻。

除了指定記錄持續時間之外,還可以使用 offset 參數為 record() 命令指定起點,其值表示在開始記錄的時間。如:僅獲取文件中的第二個短語,可設置 4 秒的偏移量並記錄 3 秒的持續時間。

在事先知道文件中語音結構的情況下,offset和duration關鍵字參數對於分割音頻文件非常有用。但使用不準確會導致轉錄不佳。

本程序從第 4.7 秒開始記錄,從而使得片語 「it takes heat to bring out the odor」 ,中的 「it t」 沒有被記錄下來,此時 API 只得到 「akes heat」 這個輸入,而與之匹配的是 「Mesquite」 這個結果。

同樣的,在獲取錄音結尾片語 「a cold dip restores health and zest」 時 API 僅僅捕獲了 「a co」 ,從而被錯誤匹配為 「Aiko」 。

噪音也是影響翻譯準確度的一大元兇。上面的例子中由於音頻文件乾淨從而運行良好,但在現實中,除非事先對音頻文件進行處理,否則不可能得到無雜訊音頻。

雜訊對語音識別的影響

雜訊在現實世界中確實存在,所有錄音都有一定程度的雜訊,而未經處理的噪音可能會破壞語音識別應用程序的準確性。

要了解雜訊如何影響語音識別,請下載 「jackhammer.wav」 (https://github.com/realpython/python-speech-recognition/tree/master/audio_files)文件,並確保將其保存到解釋器會話的工作目錄中。文件中短語 「the stale smell of old beer lingers」 在是很大鑽牆聲的背景音中被念出來。

嘗試轉錄此文件時會發生什麼?

那麼該如何處理這個問題呢?可以嘗試調用 Recognizer 類的adjust_for_ambient_noise()命令。

這樣就與準確結果接近多了,但精確度依然存在問題,而且片語開頭的 「the」 被丟失了,這是什麼原因呢?

因為使用adjust_for_ambient_noise()命令時,默認將文件流的第一秒識別為音頻的雜訊級別,因此在使用record()獲取數據前,文件的第一秒已經被消耗了。

可使用duration關鍵字參數來調整adjust_for_ambient_noise()命令的時間分析範圍,該參數單位為秒,默認為 1,現將此值降低到 0.5。

現在我們就得到了這句話的 「the」,但現在出現了一些新的問題——有時因為信號太吵,無法消除噪音的影響。

若經常遇到這些問題,則需要對音頻進行一些預處理。可以通過音頻編輯軟體,或將濾鏡應用於文件的 Python 包(例如SciPy)中來進行該預處理。處理嘈雜的文件時,可以通過查看實際的 API 響應來提高準確性。大多數 API 返回一個包含多個可能轉錄的 JSON 字元串,但若不強制要求給出完整響應時,recognition_google()方法始終僅返回最可能的轉錄字元。

通過把recognition_google()中True參數改成show_all來給出完整響應。

可以看到,recognition_google()返回了一個關鍵字為 "alternative" 的列表,指的是所有可能的響應列表。此響應列表結構會因 API 而異且主要用於對結果進行調試。


若要使用 SpeechRecognizer 訪問麥克風則必須安裝 PyAudio 軟體包,請關閉當前的解釋器窗口,進行以下操作:

安裝 PyAudio

安裝 PyAudio 的過程會因操作系統而異。

Debian Linux

如果使用的是基於 Debian的Linux(如 Ubuntu ),則可使用 apt 安裝PyAudio:

安裝完成後可能仍需要啟用pip install pyaudio,尤其是在虛擬情況下運行。

macOS:macOS 用戶則首先需要使用 Homebrew 來安裝 PortAudio,然後調用pip命令來安裝 PyAudio。

Windows:Windows 用戶可直接調用pip來安裝 PyAudio。

安裝測試:安裝了 PyAudio 後可從控制台進行安裝測試。

請確保默認麥克風打開並取消靜音,若安裝正常則應該看到如下所示的內容:

請對著麥克風講話並觀察 SpeechRecognition 如何轉錄你的講話。

Microphone 類

請打開另一個解釋器會話,並創建識一個別器類的例子。

此時將使用默認系統麥克風,而不是使用音頻文件作為信號源。讀者可通過創建一個Microphone類的實例來訪問它。

若系統沒有默認麥克風(如在 RaspberryPi 上)或想要使用非默認麥克風,則需要通過提供設備索引來指定要使用的麥克風。讀者可通過調用Microphone類的list_microphone_names()函數來獲取麥克風名稱列表。

注意:你的輸出可能與上例不同。

list_microphone_names()返回列表中麥克風設備名稱的索引。在上面的輸出中,如果要使用名為 「front」 的麥克風,該麥克風在列表中索引為 3,則可以創建如下所示的麥克風實例:

但大多數情況下需要使用系統默認麥克風。

使用listen()獲取麥克風輸入數據

準備好麥克風實例後,讀者可以捕獲一些輸入。

就像AudioFile類一樣,Microphone是一個上下文管理器。可以使用 with 塊中Recognizer 類的listen()方法捕獲麥克風的輸入。該方法將音頻源作為第一個參數,並自動記錄來自源的輸入,直到檢測到靜音時自動停止。

執行 with 塊後請嘗試在麥克風中說出 「hello」 。請等待解釋器再次顯示提示,一旦出現 「>>>」 提示返回就可以識別語音。

如果沒有提示再次返回,可能是因為麥克風收到太多的環境噪音,請使用 Ctrl + C 中斷這個過程,從而讓解釋器再次顯示提示。

要處理環境雜訊,可調用 Recognizer 類的adjust_for_ambient_noise()函數,其操作與處理噪音音頻文件時一樣。由於麥克風輸入聲音的可預測性不如音頻文件,因此任何時間聽麥克風輸入時都可以使用此過程進行處理。

運行上面的代碼後稍等片刻,嘗試在麥克風中說 「hello」 。同樣,必須等待解釋器提示返回後再嘗試識別語音。

請記住,adjust_for_ambient_noise()默認分析音頻源中1秒鐘長的音頻。若讀者認為此時間太長,可用duration參數來調整。

SpeechRecognition 資料建議 duration 參數不少於0.5秒。某些情況下,你可能會發現,持續時間超過默認的一秒會產生更好的結果。您所需要的最小值取決於麥克風所處的周圍環境,不過,這些信息在開發過程中通常是未知的。根據我的經驗,一秒鐘的默認持續時間對於大多數應用程序已經足夠。

處理難以識別的語音

嘗試將前面的代碼示例輸入到解釋器中,並在麥克風中輸入一些無法理解的噪音。你應該得到這樣的結果:

無法被 API 匹配成文字的音頻會引發UnknownValueError異常,因此要頻繁使用try和except塊來解決此類問題。API 會盡全力去把任何聲音轉成文字,如短咕嚕聲可能會被識別為 「How」,咳嗽聲、鼓掌聲以及舌頭咔噠聲都可能會被轉成文字從而引起異常。


本教程中,我們一直在識別英語語音,英語是 SpeechRecognition 軟體包中每個recognition _ *()方法的默認語言。但是,識別其他語音也是絕對有可能且很容易完成的。要識別不同語言的語音,請將 recognition _ *()方法的語言關鍵字參數設置為與所需語言對應的字元串。

作者:David Amos

https://realpython.com/python-speech-recognition/


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python 的精彩文章:

Python 2.7支持將於2020年1月1日終止
Python錯誤、調試和測試

TAG:Python |