Python 语音识别

2024年12月3日 | 阅读 17 分钟

你有没有想过 Google AssistantAmazon Alexa 是如何识别你所说的话的?你一定认为是一些复杂的智能技术在幕后运作。除了识别系统在巨大的技术发展市场中大受欢迎之外,大多数蜂窝设备都通过一些内置应用程序或第三方应用程序具有语音识别功能。不一定;大多数此类语音识别系统都是借助 Python 包和库构建和部署的。在一定程度上,Python 已证明它是可预见未来必不可少的一部分。原因很明显。要在 Python 中集成语音识别,你需要一定程度的交互性和可访问性来匹配技术。

可访问性这个概念值得考虑,因为识别功能使 老年人、残疾人视障人士 能够与机器互动,并通过最先进的服务和产品快速解决他们的问题,而无需选择随机的 GUI 应用程序。

在本文中,你将学习如何在 Python 中创建语音识别系统。为了简化理解其构建过程,本文旨在教你如何以更少的精力、更多的热情构建系统。但在进入项目之前,让我们先谈谈作为开发人员需要了解的一些更重要的方面。

语音识别的历史

早期起步

语音识别的概念可以追溯到 1950 年代,当时开发了可以识别数字和少量单词的基本系统。早期的努力集中于识别口语数字和孤立单词,但这些系统高度受限。

1980 年代和 1990 年代的进步

在 1980 年代,隐马尔可夫模型 (HMM) 成为语音识别的流行技术,从而产生了更准确、更高效的系统。在 1990 年代,更大的词汇量和连续语音识别变得可行,但这些系统仍然局限于特定领域,并且需要大量的计算能力。

Python 的参与

Python 在 2000 年代初期开始作为一种多功能编程语言而受到关注,随着语音识别技术的成熟,Python 因其简洁性和不断增长的库生态系统而自然而然地成为开发语音识别应用程序的理想选择。由 Anthony Zhang 开发的 SpeechRecognition 库成为最流行的 Python 语音识别库之一。它提供了一个简单的接口来处理各种语音识别引擎,如 Google Web Speech API、Sphinx 等。

现代时代

近年来,随着 TensorFlow 和 PyTorch 等深度学习框架的兴起,Python 在语音识别中的作用进一步扩大。这些框架使得开发复杂的语音识别模型成为可能,这些模型可以处理复杂的任务,例如识别不同的口音和语言、执行实时转录以及与虚拟助手集成。

如今,Python 仍然是语音识别研究和应用程序开发的领先语言,其工具和库的范围不断扩大,使得实现和试验这项技术比以往任何时候都更容易。

概述 - 它是如何工作的

在深入研究你将要构建的项目的细节和复杂性之前,请花点时间了解语音识别工作原理的细致概述。虽然你不需要任何先决条件即可开始,但了解 Python 编程语言的基础知识是件好事。

语音识别已经从 1950 年代贝尔实验室进行的、仅限于单个说话者和有限词汇数据库的研究发展而来。自古老的对应物出现以来,现代语音识别应用程序已经取得了长足的进步。

谈到语音的组成部分,第一个组成部分是语音。它必须从声音转换为信号,该信号可以通过麦克风传输并转录为数字数据。这是通过模数转换器完成的。一旦数据形式数字化,几个经过训练的模型就可以轻松地将音频转录为文本。

Speech Recognition python

现代语音识别器依赖于鲜为人知的隐马尔可夫模型 (HMM) 概念。该方法基于语音信号在短时间内(例如五毫秒)持续存在时所形成的假设,并且可以被认为是平稳过程,即基于不随时间变化的统计数据的过程。

在典型的 HMM 中,语音的默认信号划分约为十毫秒,分为不同的片段。每个片段的功率谱有助于信号绘制一个函数并生成一个频率,该频率稍后映射到称为倒谱系数的实数向量。映射向量的维度相当小,低至十,而一些准确的系统可能具有触及 32 或更多维度的维度。HMM 生成的最终输出以向量序列的形式出现。

向量组在借助音素(语音的基本单位)将语音解码为文本方面起着重要作用。音素的计算取决于训练,因为存在说话者差异,即使对于同一个说话者,发音有时也不同。因此,为了解决这个问题,考虑了一种特殊算法,该算法确定产生音素序列的最相关单词。

你刚刚学到的整个过程在计算方面相当昂贵。神经网络用于在现代语音识别系统中转换特征和维度,从而减少了对 HMM 的需求。此外,还使用语音活动检测器 (VAD) 来减少可能包含某些语音的音频信号的一部分。它主要用于识别不必要的语音部分并阻止它们被考虑。

语音识别包

PyPI 链上存在少数语音识别包。其中一些是:

  1. 汇编
  2. Apiai
  3. SpeechRecognition
  4. Wit
  5. Watson-developer-cloud

上述包,例如 apiaiwit,提供了自然语言处理等功能。它们的内置功能有助于识别说话者的意图,并超越通用语音识别。其他包主要关注语音到文本的转换。

在上述包中,只有一个包脱颖而出,那就是 SpeechRecognition

识别语音需要音频形式的输入,而 SpeechRecognition 包可以轻松检索这些类型的输入。它不需要复杂的脚本来访问麦克风,然后从头开始处理音频。该包的另一个优点是它可以节省你的时间,并且可以在几分钟内执行指令。

SpeechRecognition 库就像各种专门为语音构建的 API 的封面或包装器。它具有极大的灵活性和敏捷性。其中一个 API 是 Google Web Speech API,它支持硬编码的默认语音识别。

SpeechRecognition 库非常易于使用,并且该包易于作为 Python 项目导入。同样重要的是要注意,此包可能无法包装当今所有可用的 API。因此,你需要准确识别你需要哪种包来构建你的语音识别器。

你可能已经理论上了解了一些语音识别器的优缺点以及语音识别器的工作原理概述,接下来让我们按照下面给出的安装过程将 SpeechRecognition 包安装到本地环境中。

SpeechRecognition 安装

SpeechRecognition 包与各种版本的 Python 语言兼容,例如 2.6、2.73.3+。如果你的 Python 版本较旧,可能还需要其他安装。假设你的本地系统上安装了 Python 3.3+ 版本,你可以使用 pip 从终端执行安装方法。

安装后,你必须使用下面给出的代码验证安装是否正确解释。

如果你在包中使用音频文件,SpeechRecognition 可能会运行得非常好。但是,它可能还需要一些依赖项。因此,为了简化此过程,PyAudio 包可以方便地从麦克风捕获输入。

识别器类

SpeechRecognition 的魔力只有在 Recognizer 类存在时才能发挥作用。Recognizer 的主要目的是识别语音,同时读取不同语音的变体,然后驱动功能并验证来自音频源的语音。

要创建识别器,你需要创建其实例。因此,在 Python 解释器中输入以下代码。

有各种方法可以创建识别器实例,这些实例可以在 API 支持下从音频源识别语音。其中一些列举如下。

在这些包中,recognize_sphinx() 包设计用于在与 CMU Sphinx 引擎一起使用时离线工作。其余包需要互联网连接才能工作。

注意:务必小心 SpeechRecognition 中提供的默认密钥。它主要用于测试,出于安全目的,它可能会被 Google 撤销。因此,SpeechRecognition 有一个 API 接口,可以翻译这些默认密钥,以便谨慎使用。

每个 recognize_*() 方法可能会抛出名为 speech_recognition.RequestError 的异常。这可能是因为 API 由于安装损坏而无法访问。对于上面所示的其他方法,如果达到配额限制,或者服务器或互联网连接可能存在问题,则可能会生成 RequestError。可能会出现类似这样的问题。

使用音频文件

在使用 Python 中的 SpeechRecognition 包之前,你需要先下载一个音频文件。SpeechRecognition 通过将音频文件保存到你当前运行的 Python 解释器所在的目录中,使得处理音频文件变得容易。它通过使用 AudioFile 类来实现这一点。此需要进行初始化并设置音频文件路径,以便上下文管理器提供一个良好的接口来读取文件及其内容。

支持的文件类型

SpeechRecognition 支持的文件格式类型如下:

  1. WAV:格式必须是 PCM/LPCM
  2. AIFF
  3. AIFF-C
  4. FLAC:格式必须是原生 FLAC

如果你使用的是基于 x-86 的 Windows、Linux 或 macOS,则使用 FLAC 文件会更容易。除了这些操作系统,你可能需要安装一个 FLAC 编码器,该编码器可以让你访问命令行工具。

使用 record() 捕获数据

record() 函数用于在你的文件中使用 python 解释器从文件捕获数据。例如,如果文件名是“harvard.wav”,则编码此方法的 python 解释器代码将如下所示。

此代码将打开上下文管理器以读取文件的内容,并将数据存储在称为 sourceAudioFile 实例中。然后 record() 方法从文件中记录真实数据。要确认数据是否已记录,你可以使用以下代码进行检查。

或者,你也可以调用 recognize_google() 以便识别音频。这可能取决于你的互联网速度、音频的捕获方式以及结果显示的时间。

此代码将转录文件中存在的所有数据,并将识别的音频以文本格式写入。

持续时间和分段偏移量捕获

假设你只想捕获文件中语音的特定片段。record() 方法可以通过识别持续时间关键字及其参数来做到这一点,该参数会在几秒钟后停止语音。例如,你可能需要从“harvard.wav”文件中捕获语音的前 5 秒;你可以使用下面给出的方法来完成此操作。

当在块内使用时,record() 方法总是旨在在文件流中向前移动。这通常意味着如果你在前四秒进行录音,则会再次录音四秒并返回前四秒的音频。这种现象可以用下面给出的代码片段来说明。

你可以注意到 audio2 包含音频第三阶段的一部分。也有一些情况下,你指定了持续时间,但录制中途停止,这通常会损害音频的透明度。此外,在指定 record() 方法时,你甚至可以使用 offset 关键字通过参数设置一个特定的起点。起点表示从文件开始录制之前的秒数。因此,要从音频文件中捕获第二个短语,你可以根据需要选择 5 秒或 3 秒,使用以下方法。

duration 和 offset 关键字的重要性在于音频文件分割。如果你已经知道音频帧,你可能会仓促地得出较差的转录结果。为了可视化此效果,请尝试使用 Python 解释器运行以下代码。

上面的代码片段说明录音从 4.7 秒开始,开头的短语将被错过。同样,当录音结束时,捕获的短语将与开头阶段不匹配。

导致不准确转录的另一个原因是噪声。上述方法可能效果很好,因为它是一个干净的音频,但在现实世界中没有没有噪声的地方。

噪声对语音识别的影响

没有地方没有噪音。所有语音识别技术都已开发出来,以解决和去除语音中存在的会削弱捕获音频帧能力的不必要噪音。

噪音会显著影响语音识别系统的准确性和性能。以下是噪音如何影响语音识别的概述:

1. 准确性降低

  • 词语误解: 噪音会扭曲音频信号,导致语音识别系统对口语词语的解释不正确或不完整。
  • 错误率增加: 背景噪音通常会导致系统错误识别单词或短语,从而增加词错误率 (WER)。

2. 难以检测语音

  • 信号遮蔽: 噪音会遮蔽语音信号,使系统更难区分口语和背景声音。
  • 语音活动检测 (VAD) 的挑战: 噪音会干扰系统检测语音何时开始和结束的能力,从而导致音频流分割不佳。

噪音会严重影响应用程序的精度。要了解噪音如何影响语音识别,你需要下载一个名为“jackhammer.wav”的文件,并确保将其保存在解释器的工作目录中。假设此文件包含大声说出的短语“JavaTpoint 是最好的 Java 培训网站”,你需要将其在后台转录。为此,请考虑以下方法。

为了处理噪音,在上述步骤之后可以尝试的另一种方法是使用识别器类的 adjust_for_ambient_noise() 方法。

上面的代码片段会错过初始输出,并且输出没有第一个单词。因此,当 record() 方法捕获音频时,音频文件的第一部分被消耗,然后捕获后续数据。adjust_for_ambient_noise() 方法读取音频文件的第一秒,识别器校准音频的噪声水平。

如果你想使用 adjust_for_ambient_noise() 调整时间范围,你可以在代码片段中使用 duration 关键字,并为其分配以秒为单位的数值。如果你不分配任何值,则默认取 1,但建议将值降低到 0.5。以下代码片段显示了相同的技术。

上面的代码片段将返回你之前在开头错过的整个音频文件。尽管在某些情况下,处理或消除噪音的影响非常困难,因为信号可能太嘈杂而无法处理。

因此,你可能需要借助其他技术来预处理音频以解决此类问题。为此,你可以使用音频编辑软件或像 SciPy 这样的 Python 包。该包可以预处理音频文件并过滤噪音。

此外,在处理嘈杂文件时,使用实际的 API 响应会很有帮助,因为大多数 API 返回包含许多转录的 JSON 字符串。同样,除非强制提供完整响应,否则 recognize_google() 方法也会提供类似的转录文件。此方法可以通过使用某些参数和关键字(例如返回 recognize_google() 方法的 show_all)来实际实现。

在上面的代码片段中,recognize_google() 方法返回一个字典,其中包含一个指向上面显示的各种转录的替代键。尽管响应结构可能因 API 而异而具有不同的形式,但这主要用于调试。

到目前为止,你可能已经学习了 Python 中语音识别及其包的基础知识。学习的下一阶段涉及通过从麦克风获取输入使项目更具交互性来转录音频文件。

处理麦克风输入

你可以通过安装名为 PyAudio 的包来使用 SpeechRecognizer 包访问麦克风。为此,请保存更改并关闭解释器。继续安装 PyAudio,过程与安装 SpeechRecognizer 类似。

安装后,要测试它是否与你正在使用的语音识别器版本兼容,请键入以下命令。

在此步骤之后,你需要确保你的默认麦克风已打开且未静音。如果安装和测试过程中没有遇到任何问题,你应该在终端上看到类似这样的内容。

尝试对着麦克风说话,测试 SpeechRecognizer 包如何转录你的语音。

麦克风类

麦克风类用于为系统创建实例,以从源识别音频文件。要使用此类,你需要通过打开另一个解释器会话并创建识别器类来导入它,如下所示。

你需要使用系统上的默认麦克风,而不是使用来自源的音频文件。你可以使用所示方法来做到这一点。

如果你的系统无法识别默认麦克风,你可能需要指定其中一个设备索引。你可以使用麦克风类中的 list_microphone_names() 方法获取所有可用麦克风名称的列表。

上面代码中定义的设备索引被称为 index,它包含系统上可用麦克风名称的列表。例如,在上面给出的输出中,名为“front”的麦克风位于列表中索引 3 的位置。这可以使用下面给出的方法来完成。

上面的代码只是一个示例,因此建议不要在解释器中运行。对于大多数项目,你应该使用默认系统麦克风。

使用 listen() 捕获麦克风输入

你将在此处学习的另一个方法是 listen() 方法,用于从麦克风捕获输入。由于你已经创建了麦克风实例,现在是时候捕获一些输入了。与大多数 AudioFile 类一样,麦克风也被视为上下文管理器。它通过 Recognizer 类中的一个块来捕获输入,将它作为第一个参数,然后从源录制输入,直到麦克风检测到静音。为了说明这一点,让我们看看它是如何使用给定代码应用的。

一旦上述代码在块中执行,你应该尝试对着麦克风说一些话并等待一段时间。解释器可能会在一段时间后提示显示。一旦你看到“>>>”作为返回的提示,就可以确保识别器可以识别你所说的一切。

如果识别器未能返回提示,可能是因为存在一些环境噪音。你可以通过按 Ctrl+C 来停止它并返回提示。

为了调整语音中的噪音,你可能需要使用识别器类的 adjust_for_ambient_noise() 方法。由于麦克风输入与音频文件相比是不可预测的,因此在监听麦克风输入时始终这样做是一个好主意。为了获得精确且无噪音的输出,你可以尝试使用 listen() 方法,如下所示。

运行上述代码时,请等待几秒钟,以便 adjust_for_ambient_noise() 方法完成其任务。代码编译运行后,尝试对着麦克风说一些话,等待解释器识别语音。如果它识别并返回提示,则表示运行正常。

你也可以使用 duration 关键字,并尝试再次使用它来获取你想要识别的特定语音帧。同时,SpeechRecognizer 文档建议在 duration 关键字的持续时间为 0.5 或更短时使用它。你可能还会发现,在某些情况下,duration 关键字没有使用,因此默认使用 1 来生成更好的结果。此外,值得注意的是,最小值取决于麦克风环境的输入。因此,一秒的持续时间被认为是此类任务的最佳选择。

无法识别的语音

使用代码库,你已经在解释器中创建了一些具体的代码,使用麦克风发出了一些无法理解的噪音。你很可能会收到这样的错误。

此错误是由于通过麦克风捕获的输入语音无法识别的性质造成的,因此 API 代码库不够先进,无法转录这些短促的咕哝声或人声。还可能出现这样的情况:解释器可能会通过识别当前输入来提示,并显示与麦克风捕获的内容完全不符的东西。因此,拍手、点击或其他动作可能会分别引发异常或没有正确的输出。

总结

在本篇关于 Python 语音识别的冗长教程中,你从头开始学习了调度是如何工作的。你涵盖了从概念知识到实际操作经验,创建了一个实时且简单的 Python 语音识别器,它可以听到你的语音并以文本格式显示在控制台上。你还学习了一些关键方法来处理在使用 SpeechRecognizer 包时经常出现的问题,并学会了如何纠正这些问题。Python 作为一种广泛使用的编程和脚本语言,因其丰富的库和框架而涵盖了大多数语音识别应用程序,这些库和框架展示了它只需几行易于阅读的代码即可处理关键问题的能力。