語音識別

在本章中,我們將學習使用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:

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

yiibai.com