使用 Python 的 AI – 语音识别

在本章中,我们将学习使用 Python 的 AI 进行语音识别。

语音是成人交流的最基本方式。语音处理的基本目标是提供人与机器之间的交互。

语音处理系统主要有三个任务 −

  • 第一,语音识别使机器能够捕捉我们所说的单词、短语和句子

  • 第二,自然语言处理使机器能够理解我们所说的内容,并且

  • 第三,语音合成使机器能够说话。

本章重点介绍语音识别,即理解人类所说的单词的过程。请记住,语音信号是在麦克风的帮助下捕获的,然后系统必须理解它。

构建语音识别器

语音识别或自动语音识别 (ASR) 是机器人等人工智能项目的关注中心。没有 ASR,就无法想象认知机器人与人类互动。然而,构建语音识别器并不容易。

开发语音识别系统的困难

开发高质量的语音识别系统确实是一个难题。语音识别技术的难度可以从以下几个方面大致描述 −

  • 词汇量 − 词汇量会影响开发 ASR 的难易程度。为了更好地理解,请考虑以下词汇量。

    • 小规模词汇表由 2-100 个单词组成,例如,在语音菜单系统中

    • 中等规模词汇表由几百到几千个单词组成,例如,在数据库检索任务中

    • 大规模词汇表由几万个单词组成,例如,在一般听写任务中。

    请注意,词汇量越大,识别难度就越大。

  • 信道特性 − 信道质量也是一个重要维度。例如,人类语音包含具有全频率范围的高带宽,而电话语音则包含具有有限频率范围的低带宽。请注意,后者更难。

  • 说话模式 − 开发 ASR 的难易程度还取决于说话模式,即语音是孤立词模式、连接词模式还是连续语音模式。请注意,连续语音更难识别。

  • 说话风格 − 朗读语音可能是正式风格,也可能是自发的、随意的对话风格。后者更难识别。

  • 说话人依赖性 − 语音可以是说话人依赖性、说话人自适应性或说话人独立性。独立于扬声器的 ASR 是最难构建的。

  • 噪音类型 − 噪音是开发 ASR 时要考虑的另一个因素。信噪比可能处于不同的范围,具体取决于观察到较少背景噪音还是较多背景噪音的声学环境 −

    • 如果信噪比大于 30dB,则被视为高范围

    • 如果信噪比介于 30dB 到 10db 之间,则被视为中等 SNR

    • 如果信噪比小于 10dB,则被视为低范围

    例如,背景噪音的类型(如静止、非人为噪音、背景语音和其他说话者的串扰)也增加了问题的难度。

  • 麦克风特性 − 麦克风的质量可能很好、一般或低于平均水平。此外,嘴巴和麦克风之间的距离也可能不同。识别系统也应考虑这些因素。

尽管存在这些困难,研究人员仍在语音的各个方面进行了大量研究,例如理解语音信号、说话者和识别口音。

您必须按照以下步骤构建语音识别器 −

可视化音频信号 - 从文件中读取并对其进行处理

这是构建语音识别系统的第一步,因为它可以了解音频信号的结构。处理音频信号时可以遵循的一些常见步骤如下 −

录音

当您必须从文件中读取音频信号时,首先使用麦克风进行录音。

采样

使用麦克风录音时,信号以数字化形式存储。但要对其进行处理,机器需要以离散数字形式存储它们。因此,我们应该以一定的频率进行采样,并将信号转换为离散数字形式。选择高频采样意味着当人类听到信号时,他们会将其视为连续的音频信号。

示例

以下示例展示了使用 Python 分析存储在文件中的音频信号的分步方法。此音频信号的频率为 44,100 HZ。

按此处所示导入必要的包 −

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('
Signal 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()

您将能够看到输出图和针对上述音频信号提取的数据,如图像所示

Visualizing Audio Signals
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('
Signal 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 等。

示例

在下面的示例中,我们将使用 Python 逐步提取信号中的特征,使用 MFCC 技术。

导入必要的包,如下所示 −

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('
MFCC:
Number 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('
Filter bank:
Number 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 install 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)

现在 google API 可以识别语音并给出输出。

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

您可以看到以下输出 −

请说点什么:
您说:

例如,如果您说的是 tutorialspoint.com,那么系统会正确识别它,如下所示 −

tutorialspoint.com