語音識別


在本章中,我們將學習使用AI和Python進行語音識別。
言語是成人人際溝通的最基本手段。 語音處理的基本目標是提供人與機器之間的互動。
語音處理系統主要有三項任務 -

  • 首先,語音識別允許機器捕捉我們所說的單詞,短語和句子
  • 其次,自然語言處理使機器能夠理解我們所說的話
  • 第三,語音合成允許機器說話。

本章重點講述語音識別,理解人類說話的過程。 請記住,在麥克風的幫助下捕捉語音信號,然後系統才能理解它。

構建語音識別器

語音識別或自動語音識別(ASR)是AI機器人等AI專案的關注焦點。 沒有ASR,就不可能想象一個認知機器人與人進行互動。 但是,構建語音識別器並不容易。

開發語音識別系統的困難
開發高品質的語音識別系統確實是一個難題。 語音識別技術的困難可以廣泛地表徵為如下所討論的許多維度 -

  • 詞彙大小 - 詞彙大小影響開發ASR的難易程度。考慮以下詞彙量以便更好地理解。
    • 例如,在一個語音選單系統中,一個小詞彙由2到100個單詞組成
    • 例如,在資料庫檢索任務中,中等大小的詞彙包含幾個100到1000個單詞
    • 一個大的詞彙由幾萬個單詞組成,如在一般的聽寫任務中。
  • 通道特性 - 通道品質也是一個重要的維度。 例如,人類語音包含全頻率範圍的高頻寬,而電話語音包含頻率範圍有限的低頻寬。 請注意,後者更難。
  • 說話模式 - 輕鬆開發ASR還取決於說話模式,即語音是處於孤立詞模式還是連線詞模式,還是處於連續語音模式。 請注意,連續說話很難辨認。

  • 口語風格 - 閱讀說話可以採用正式風格,也可以採用自發風格和對話風格。 後者更難以識別。

  • 揚聲器依賴性 - 語音可以依賴揚聲器,揚聲器自適應或揚聲器獨立。 獨立發言人是最難建立的。
  • 噪音型別 - 噪音是開發ASR時需要考慮的另一個因素。 訊雜比可以在各種範圍內,這取決於觀察較少的聲學環境與較多的背景噪聲 -
    • 如果訊雜比大於30dB,則認為是高範圍
    • 如果訊雜比在30dB到10db之間,則認為是中等訊雜比
    • 如果訊雜比小於10dB,則認為是低範圍
  • 麥克風特性 - 麥克風的品質可能很好,平均水平或低於平均水平。 此外,嘴和微型電話之間的距離可能會有所不同。 識別系統也應考慮這些因素。

儘管存在這些困難,研究人員在語音的各個方面做了很多工作,例如理解語音信號,說話人以及識別口音。

所以,需要按照以下步驟構建語音識別器 -

視覺化音訊信號 - 從檔案讀取並進行處理

這是構建語音識別系統的第一步,因為它可以幫助您理解音訊信號的結構。 處理音訊信號可遵循的一些常見步驟如下所示 -

記錄
當必須從檔案中讀取音訊信號時,首先使用麥克風錄製。

取樣
用麥克風錄音時,信號以數位形式儲存。 但為了解決這個問題,機器需要使用離散數位形式。 因此,我們應該以某個頻率進行取樣,並將信號轉換為離散數位形式。 選擇高頻取樣意味著當人類聽到信號時,他們會感覺它是一個連續的音訊信號。

範例

以下範例顯示了使用Python儲存在檔案中的逐步分析音訊信號的方法。 這個音訊信號的頻率是44,100HZ。

下面匯入必要的軟體包 -

import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile

現在,讀取儲存的音訊檔案。 它會返回兩個值:取樣頻率和音訊信號。 提供儲存音訊檔案的路徑,如下所示 -

frequency_sampling, audio_signal = wavfile.read("/Users/admin/audio_file.wav")

使用顯示的命令顯示音訊信號的取樣頻率,信號的資料型別及其持續時間等引數 -

print('\nSignal shape:', audio_signal.shape)
print('Signal Datatype:', audio_signal.dtype)
print('Signal duration:', round(audio_signal.shape[0] / 
float(frequency_sampling), 2), 'seconds')

這一步涉及如下所示對信號進行標準化 -

audio_signal = audio_signal / np.power(2, 15)

在這一步中,從這個信號中提取出前100個值進行視覺化。 為此目的使用以下命令 -

audio_signal = audio_signal [:100]
time_axis = 1000 * np.arange(0, len(signal), 1) / float(frequency_sampling)

現在,使用下面給出的命令視覺化信號 -

plt.plot(time_axis, signal, color='blue')
plt.xlabel('Time (milliseconds)')
plt.ylabel('Amplitude')
plt.title('Input audio signal')
plt.show()

下面輸出圖形是上述音訊信號提取的資料,如圖所示 -

Signal shape: (132300,)
Signal Datatype: int16
Signal duration: 3.0 seconds

表徵音訊信號:轉換到頻域

表徵音訊信號涉及將時域信號轉換為頻域,並通過以下方式理解其頻率分量。 這是一個重要的步驟,因為它提供了關於信號的大量資訊。 可以使用像傅立葉變換這樣的數學工具來執行此轉換。

範例

以下範例將逐步說明如何使用儲存在檔案中的Python來表徵信號。 請注意,這裡使用傅里葉變換數學工具將其轉換為頻域。

匯入必要的軟體包,如下所示 -

import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile

現在,讀取儲存的音訊檔案。 它會返回兩個值:取樣頻率和音訊信號。 提供儲存音訊檔案的路徑,如命令所示 -

frequency_sampling, audio_signal = wavfile.read("/Users/admin/sample.wav")

在這一步中,將使用下面給出的命令顯示音訊信號的取樣頻率,信號的資料型別和持續時間等引數 -

print('\nSignal shape:', audio_signal.shape)
print('Signal Datatype:', audio_signal.dtype)
print('Signal duration:', round(audio_signal.shape[0] / 
float(frequency_sampling), 2), 'seconds')

在這一步中,我們需要對信號進行標準化,如下面的命令所示 -

audio_signal = audio_signal / np.power(2, 15)

這一步涉及提取信號的長度和半長。使用以下命令 -

length_signal = len(audio_signal)
half_length = np.ceil((length_signal + 1) / 2.0).astype(np.int)

現在,需要應用數學工具來轉換到頻域。 這裡使用傅里葉變換。

signal_frequency = np.fft.fft(audio_signal)

現在,進行頻域信號的歸一化並將其平方 -

signal_frequency = abs(signal_frequency[0:half_length]) / length_signal
signal_frequency **= 2

接下來,提取頻率變換信號的長度和一半長度 -

len_fts = len(signal_frequency)

請注意,傅里葉變換信號必須針對奇偶情況進行調整。

if length_signal % 2:
   signal_frequency[1:len_fts] *= 2
else:
   signal_frequency[1:len_fts-1] *= 2

現在,以分貝(dB)為單位提取功率 -

signal_power = 10 * np.log10(signal_frequency)

調整X軸的以kHz為單位的頻率 -

x_axis = np.arange(0, len_half, 1) * (frequency_sampling / length_signal) / 1000.0

現在,將信號的特徵視覺化如下 -

plt.figure()
plt.plot(x_axis, signal_power, color='black')
plt.xlabel('Frequency (kHz)')
plt.ylabel('Signal power (dB)')
plt.show()

可以觀察上面程式碼的輸出圖形,如下圖所示 -

生成單調音訊信號

到目前為止你所看到的兩個步驟對於了解信號很重要。 現在,如果要使用某些預定義引數生成音訊信號,此步驟將很有用。 請注意,此步驟會將音訊信號儲存在輸出檔案中。

範例

在下面的例子中,我們將使用Python生成一個單調信號,它將被儲存在一個檔案中。需要採取以下步驟 -

匯入必要的軟體包 -

import numpy as np
import matplotlib.pyplot as plt
from scipy.io.wavfile import write

指定輸出儲存的檔案 -

output_file = 'audio_signal_generated.wav'

現在,指定選擇的引數,如圖所示 -

duration = 4 # in seconds
frequency_sampling = 44100 # in Hz
frequency_tone = 784
min_val = -4 * np.pi
max_val = 4 * np.pi

在這一步中,我們可以生成音訊信號,如下程式碼所示 -

t = np.linspace(min_val, max_val, duration * frequency_sampling)
audio_signal = np.sin(2 * np.pi * tone_freq * t)

現在,將音訊檔案儲存在輸出檔案中 -

write(output_file, frequency_sampling, signal_scaled)

如圖所示,提取圖形的前100個值 -

audio_signal = audio_signal[:100]
time_axis = 1000 * np.arange(0, len(signal), 1) / float(sampling_freq)

現在,將生成的音訊信號視覺化如下 -

plt.plot(time_axis, signal, color='blue')
plt.xlabel('Time in milliseconds')
plt.ylabel('Amplitude')
plt.title('Generated audio signal')
plt.show()

可以觀察這裡給出的圖形 -

語音特徵提取

這是構建語音識別器的最重要步驟,因為在將語音信號轉換為頻域後,我們必須將其轉換為可用的特徵向量形式。 可以為此使用不同的特徵提取技術,如MFCC,PLP,PLP-RASTA等。

範例

在以下範例中,我們將使用MFCC技術逐步使用Python從信號中提取特徵。

匯入必要的軟體包,如下所示 -

import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
from python_speech_features import mfcc, logfbank

現在,讀取儲存的音訊檔案。 它會返回兩個值 - 取樣頻率和音訊信號。 提供儲存音訊檔案的路徑。

frequency_sampling, audio_signal = wavfile.read("/Users/admin/audio_file.wav")

請注意,在此首先抽取15000個樣本進行分析。

audio_signal = audio_signal[:15000]

使用MFCC技術並執行以下命令來提取MFCC特徵 -

features_mfcc = mfcc(audio_signal, frequency_sampling)

現在,列印MFCC引數,如下所示 -

print('\nMFCC:\nNumber of windows =', features_mfcc.shape[0])
print('Length of each feature =', features_mfcc.shape[1])

使用下面給出的命令繪製並視覺化MFCC特徵 -

features_mfcc = features_mfcc.T
plt.matshow(features_mfcc)
plt.title('MFCC')

在這一步中,我們使用如下濾器組特徵,提取過濾器組特徵 -

filterbank_features = logfbank(audio_signal, frequency_sampling)

現在,列印過濾器組引數。

print('\nFilter bank:\nNumber of windows =', filterbank_features.shape[0])
print('Length of each feature =', filterbank_features.shape[1])

繪製並視覺化過濾器組特徵。

filterbank_features = filterbank_features.T
plt.matshow(filterbank_features)
plt.title('Filter bank')
plt.show()

根據上述步驟,您可以觀察到以下輸出:圖1為MFCC,圖2為過濾器組。

口語詞的識別

語音識別意味著當人們說話時,機器就會理解它。 這裡使用Python中的Google Speech API來實現它。 需要為此安裝以下軟體包 -

  • Pyaudio - 它可以通過使用pip安裝Pyaudio命令進行安裝。
  • SpeechRecognition - 這個軟體包可以通過使用pip install SpeechRecognition進行安裝。
  • Google-Speech-API - 可以使用命令pip install google-api-python-client進行安裝。

範例

觀察下面的例子來理解口語的識別。如下所示匯入必要的軟體包 -

import speech_recognition as sr

建立一個物件,如下所示 -

recording = sr.Recognizer()

現在,Microphone()模組將把語音作為輸入 -

with sr.Microphone() as source: recording.adjust_for_ambient_noise(source)
   print("Please Say something:")
   audio = recording.listen(source)

現在谷歌API會識別語音並提供輸出。

try:
   print("You said: \n" + recording.recognize_google(audio))
except Exception as e:
   print(e)

可以看到下面的輸出 -

Please Say Something:
You said:

例如,如果您說tw511.com,那麼系統會如下正確識別它 -

tw511.com