CMUS狮身人面像(四)-构建语言模型

embedded/2024/12/30 22:41:15/

构建语言模型

语言模型是配置的重要组成部分,它告诉解码器可以识别哪些单词序列。

模型有多种类型:关键词列表、语法和统计语言模型以及语音语言模型。它们具有不同的功能和性能特性。您可以根据需要选择任何解码模式,甚至可以在运行时在模式之间切换。有关更多详细信息,请参阅Pocketsphinx 教程。

关键词列表

Pocketsphinx 支持关键字发现模式,您可以在其中指定要查找的关键字列表。这种模式的优点是可以为每个关键词指定一个阈值,这样就可以在连续语音中检测到关键词。所有其他模式都会尝试从语法中检测单词,即使您使用的单词不在语法中。典型的关键字列表如下所示:

oh mighty computer /1e-40/
hello world /1e-30/
other phrase /1e-20/

必须为每个关键短语指定阈值。对于较短的关键短语,您可以使用较小的阈值,例如1e-1,对于较长的关键短语,阈值必须更大,最大为1e-50。如果您的关键短语非常长(超过 10 个音节),建议将其拆分并分别查找各个部分。必须调整阈值以在误报和漏检之间取得平衡。最好的方法是使用预先录制的音频文件。常见的调优流程如下:

  1. 录制一段较长的录音,其中很少出现您的关键字和其他一些声音。您可以拍摄电影声音或其他东西。音频长度应约为 1 小时。
  2. 使用以下命令对该文件运行关键字识别,每个关键字具有不同的阈值:
     pocketsphinx_continuous -infile <your_file.wav> -keyphrase <your keyphrase> \-kws_threshold <your_threshold> -time yes

    该命令将打印许多行,其中一些是带有检测时间和置信度的关键字。您还可以使用-logfn your_file.log选项禁用额外日志以避免混乱。

  3. 根据您的关键字识别结果,计算您遇到的误报和漏检次数。
  4. 选择误报和漏检最少的阈值。

为了获得最佳准确性,最好使用 3-4 个音节的关键词。太短的短语很容易混淆。

仅pocketsphinx 支持关键字列表,sphinx4 无法处理它们。

将关键字列表与 PocketSphinx 结合使用

要在命令行中使用关键字列表,请使用-kws选项指定它。您还可以使用-keyphrase选项来指定单个关键短语。

在 Python 中,您可以在配置对象中指定选项,也可以添加关键字的命名搜索:

decoder.set_kws('keyphrase', kws_file)
decoder.set_search('keyphrase')

在 Android 中,它看起来类似:

recognizer.setKws('keyphrase', kwsFile);
recognizer.startListening('keyphrase')

请注意-kws-lm-jsgf选项冲突。您不能同时指定两者。

语法

语法描述了一种非常简单的命令和控制语言类型。它们通常是手工编写的或在代码中自动生成的。语法通常没有单词序列的概率,但某些元素可能会被加权。它们可以使用 Java 语音语法格式 ( JSGF ) 创建,并且通常具有.gram.jsgf等文件扩展名。

语法允许您非常精确地指定可能的输入,例如,某个单词可能只重复两到三次。但是,如果您的用户不小心跳过了语法所需的单词,这种严格性可能会有害。那样的话整个识别就会失败。因此,最好使语法更加灵活。只需列出允许任意顺序的词袋,而不是短语。避免具有许多规则和情况的非常复杂的语法。它只会减慢识别器的速度,您可以使用简单的规则来代替。过去,语法需要花费大量的精力来调整它们,正确地分配变体等等。大型 VXML 咨询行业就是这样的。

建立语法

语法通常以 Java 语音语法格式 (JSGF) 手动编写:

#JSGF V1.0;grammar hello;
public <greet> = (good morning | hello) ( bhiksha | evandro | rita | will );

有关 JSGF 的更多信息,请参阅 W3C 上的完整文档。

在 PocketSphinx 中使用语法

要在命令行中使用您的语法,请使用选项指定它-jsgf

在 Python 中,您可以在配置对象中指定选项,也可以添加语法的命名搜索:

decoder.set_jsgf('grammar', jsgf_file)
decoder.set_search('grammar')

在 Android 中,这看起来很相似:

recognizer.setJsgf('grammar', jsgfFile);
recognizer.startListening('grammar')

请注意-jsgf-kws-jsgf选项冲突。您不能同时指定两者。

语言模型

统计语言模型描述更复杂的语言。它们包含单词和单词组合的概率。这些概率是根据样本数据估计的,并且自动具有一定的灵活性。词汇表中的每种组合都是可能的,尽管每种组合的概率会有所不同。例如,如果您从单词列表创建统计语言模型,它仍然允许解码单词组合,即使这可能不是您的意图。

总体而言,建议将统计语言模型用于自由格式输入,用户可以用自然语言说出任何内容。它们需要比语法更少的工程工作。您只需列出可能的句子即可。例如,您可能会列出“二十一”和“三十三”之类的数字,统计语言模型也会以一定的概率允许“三十一”。

一般来说,现代语音识别界面往往更加自然,并避免了上一代的命令和控制风格。因此,大多数界面设计人员更喜欢使用统计语言模型进行自然语言识别,而不是使用老式的 VXML 语法。

关于设计 VUI 界面的主题,您可能会对以下书籍感兴趣: Bruce Balentine 所著的《It is Better to Be a Good Machine Than a Bad Person: Speech Recognition and Other Exotic User Interfaces at the Twilight of the Jetsonian Age》 。

构建统计语言模型的方法有很多。当您的数据集很大时,使用 CMU 语言建模工具包是有意义的。当模型较小时,您可以使用快速在线 Web 服务。当您需要特定选项或者您只想使用您最喜欢的工具包来构建 ARPA 模型时,您也可以使用它。

语言模型可以以三种不同的格式存储和加载:文本 ARPA格式、二进制BIN格式和二进制DMP格式。ARPA 格式占用更多空间,但可以对其进行编辑。ARPA 文件有一个.lm扩展名。二进制格式占用的空间显着减少,加载速度更快。二进制文件有一个.lm.bin扩展名。也可以在这些格式之间进行转换。DMP 格式已过时,不推荐。

构建统计语言模型

文本准备

首先,您需要准备大量干净的文本。扩展缩写、将数字转换为单词、清理非单词项目。例如,要清理 Wikipedia XML 转储,您可以使用特殊的 Python 脚本,例如Wikiextractor。要清理 HTML 页面,您可以尝试 BoilerPipe。这是一个专门为从 HTML 中提取文本而创建的很好的包。

有关如何从维基百科文本创建语言模型的示例,请参阅此博客文章。电影字幕也是口语的良好来源。

完成语言建模过程后,请将您的语言模型提交到 CMUSphinx 项目。我们很乐意分享!

普通话和其他类似语言的语言建模与英语基本相同,但还有一项额外的考虑。不同之处在于输入文本必须进行分词。提供了分段工具和关联的单词列表来实现此目的。

使用 SRILM 训练 ARPA 模型

使用 SRI 语言建模工具包 ( SRILM )训练模型非常简单。这就是我们推荐它的原因。此外,SRILM 是迄今为止最先进的工具包。要训​​练模型,您可以使用以下命令:

ngram-count -kndiscount -interpolate -text train-text.txt -lm your.lm

您可以事后修剪模型以减小模型的大小:

ngram -lm your.lm -prune 1e-8 -write-lm your-pruned.lm

训练完成后,值得在测试数据上测试模型的困惑度:

ngram -lm your.lm -ppl test-text.txt

使用 CMUCLMTK 训练 ARPA 模型

您需要下载并安装 CMUSphinx 的语言模型工具包(CMUCLMTK)。详情请参阅下载页面。

创建语言模型的过程如下:

1) 准备用于生成语言模型的参考文本。语言模型工具包期望其输入采用规范化文本文件的形式,话语由<s></s> 标签分隔。许多输入过滤器可用于特定语料库,例如 Switchboard、ISL 和 NIST 会议以及 HUB5 转录本。结果应该是由句子的开始和结束标记界定的句子集:<s></s>。这是一个例子:

<s> generally cloudy today with scattered outbreaks of rain and drizzle
persistent and heavy at times </s>
<s> some dry intervals also with hazy sunshine especially in eastern parts in
the morning </s>
<s> highest temperatures nine to thirteen Celsius in a light or moderate mainly
east south east breeze </s>
<s> cloudy damp and misty today with spells of rain and drizzle in most places
much of this rain will be light and patchy but heavier rain may develop in the
west later </s>

更多的数据将产生更好的语言模型。weather.txtsphinx4(用于生成天气语言模型)的文件包含近 100,000 个句子。

2)生成词汇文件。这是文件中所有单词的列表:

 text2wfreq < weather.txt | wfreq2vocab > weather.tmp.vocab

3) 您可能需要编辑词汇文件以删除单词(数字、拼写错误、名称)。如果您发现拼写错误,最好在输入记录中修复它们。

4) 如果您想要一个封闭词汇语言模型(一种没有针对未知单词的规定的语言模型),那么您应该从输入记录中删除包含词汇文件中不存在的单词的句子。

5) 使用以下命令生成 ARPA 格式语言模型:

 text2idngram -vocab weather.vocab -idngram weather.idngram < weather.closed.txtidngram2lm -vocab_type 0 -idngram weather.idngram -vocab weather.vocab -arpa weather.lm

6)生成CMU二进制形式(BIN):

sphinx_lm_convert -i weather.lm -o weather.lm.bin

使用 Web 服务构建简单的语言模型

如果您的语言是英语并且文本很小,有时使用 Web 服务来构建它会更方便。以这种方式构建的语言模型对于简单的命令和控制任务来说非常实用。首先,您需要创建一个语料库。

“语料库”只是一个用于训练语言模型的句子列表。作为一个例子,我们将使用一个假设的移动互联网设备语音控制任务。我们想告诉它“打开浏览器”、“新电子邮件”、“前进”、“后退”、“下一个窗口”、“最后一个窗口”、“打开音乐播放器”等信息。因此,我们首先创建一个名为的文件corpus.txt

open browser
new e-mail
forward
backward
next window
last window
open music player

然后进入LMTool页面。只需单击“浏览...”按钮,选择corpus.txt您创建的文件,然后单击“编译知识库”

您应该看到一个包含一些状态消息的页面,后面是一个标题为“Sphinx 知识库”的页面。该页面将包含标题为“词典”“语言模型”的链接。下载这些文件并记下它们的名称(它们应包含 4 位数字,后跟扩展名 .dic.lm)。您现在可以使用 PocketSphinx 测试新创建的语言模型。

使用其他语言模型工具包

有许多工具包可以从文本文件创建 ARPA n-gram 语言模型。

您可以尝试一些工具包:

  • 肯·LM
  • IRSTLM
  • 麻省理工学院

如果您正在训练大词汇量语音识别系统,则语言模型训练将在有关大规模语言模型的单独页面中概述。

创建 ARPA 文件后,您可以将模型转换为二进制格式以加快加载速度。

将模型转换为二进制格式

要快速加载大型模型,您可能希望将它们转换为二进制格式,以节省解码器初始化时间。对于小模型来说这是没有必要的。Pocketsphinx 和 sphinx3 都可以使用该选项来处理它们-lm。Sphinx4 通过 lm 文件的扩展名自动检测格式。

ARPA 格式和 BINARY 格式可以相互转换。sphinx_lm_convert您可以使用sphinxbase 中的命令生成另一个文件:

sphinx_lm_convert -i model.lm -o model.lm.bin
sphinx_lm_convert -i model.lm.bin -ifmt bin -o model.lm -ofmt arpa

您还可以通过这种方式将旧的 DMP 模型转换为二进制格式。

在下一节中,我们将讨论如何使用、测试和改进您创建的语言模型。

将您的语言模型与 PocketSphinx 结合使用

如果您已经安装了 PocketSphinx,您将有一个名为 的程序 pocketsphinx_continuous,可以从命令行运行该程序来识别语音。假设它安装在 下 /usr/local,并且您的语言模型和字典被调用8521.dic8521.lm放置在当前文件夹中,请尝试运行以下命令:

pocketsphinx_continuous -inmic yes -lm 8521.lm -dict 8521.dic

这将使用您的新语言模型、词典和默认声学模型。在 Windows 上,您还必须使用以下选项指定声学模型文件夹-hmm

bin/Release/pocketsphinx_continuous.exe -inmic yes -lm 8521.lm -dict 8521.dic -hmm model/en-us/en-us

您将看到很多诊断消息,然后暂停,然后输出 “READY…”。现在您可以尝试说出一些命令。它应该能够完全准确地识别它们。如果没有,您的麦克风或声卡可能有问题。

将您的语言模型与 Sphinx4 结合使用

在 Sphinx4 高级 API 中,您需要在配置中指定语言模型的位置:

configuration.setLanguageModelPath("file:8754.lm");

如果模型在资源中,您可以通过以下方式引用它"resource:URL"

configuration.setLanguageModelPath("resource:/com/example/8754.lm");

另请参阅Sphinx4 教程以了解更多详细信息。


http://www.ppmy.cn/embedded/29475.html

相关文章

Go实现 - 树莓派自己烧录自己 之 多读卡器同时烧录

简介 Go实现 监控读卡器设备存储空间变化&#xff0c; 自动烧写SD Card&#xff0c; 烧写完成之后自动弹出&#xff0c; 显示执行状态&#xff0c; 还支持热插拔。 步骤 代码 lsblkParser.go imageWriter.go package actionimport ("fmt""os/exec" )ty…

【RabbitMQ 二】RabbitMQ基本组成、交换器类型、RabbitMQ生产消费消息流程、信道Channel、AMQP协议

RabbitMQ入门 1.RabbitMQ基本组成 RabbitMQ有一些基本的组成单元&#xff1a; Producer&#xff1a;消息的生产者Consumer&#xff1a;消息的消费者Broker&#xff1a;RabbitMQ的服务节点。形象一点说就是一个Broker等同于一台RabbitMQ服务器&#xff0c;可以接收Producer的…

开源博客项目Blog .NET Core源码学习(20:App.Hosting项目结构分析-8)

本文学习并分析App.Hosting项目中后台管理页面的个人资料页面、修改密码页面。 个人资料页面 个人资料页面用于显示和编辑个人信息&#xff0c;支持从本地上传个人头像。整个页面使用了layui中的表单、日期与时间选择、上传等样式或模块&#xff0c;通过layui.css文件设置样式…

Flutter笔记:Widgets Easier组件库(8)使用图片

Flutter笔记 Widgets Easier组件库&#xff08;8&#xff09;&#xff1a;使用图片 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress o…

【翻译】Elasticsearch Java API Client 8.13.2 (第四章-使用 Java API 客户端)

以下部分提供了有关 Elasticsearch 最常用和一些不太明显的功能的教程。 有关完整参考&#xff0c;请参阅 Elasticsearch 文档&#xff0c;特别是 REST API 部分。 Java API 客户端使用 Java API 约定&#xff0c;严格遵循此处描述的 JSON 结构。 索引单个文档 如果您是 Ela…

Java中的Map接口有哪些方法可以用来遍历它的键值对?

Java中的Map接口提供了多种方法来遍历它的键值对。以下是其中一些常用的方法&#xff1a; 1. keySet()&#xff1a;返回一个包含Map中所有键的Set视图。可以使用这个方法来遍历键。 java Map<String, Integer> map new HashMap<>(); // 添加键值对 map.put("…

网络安全知识点

网络安全 1&#xff0e; 网络安全的定义&#xff0c;网络安全的属性。 定义&#xff1a;针对各种网络安全威胁研究其安全策略和机制&#xff0c;通过防护、检测和响应&#xff0c;确保网络系统及数据的安全性。 属性&#xff1a;机密性 认证&#xff08;可鉴别性&#xff09…

rust可变全局静态数组用法

extern crate alloc; use alloc::vec::Vec; use core::mem::ManuallyDrop; use log::info; use uefi::println; pub static mut gbuf:&static mut [i32] &mut [0; 0x1000]; pub fn testdumphex() -> i32 { info!(“testdumphex!”); let mut hexvec Vec::new();…