西工大 ASLP 实验室在 WeNet 中开源基于 CPPN 的神经网络热词增强语音识别方案

语境偏置(Contextual biasing)旨在将语境知识集成到语音识别(ASR)系统中,以提高在相关领域词汇(俗称“热词”)上的识别准确率。在许多ASR场景中,待识别语音中可能会包含训练数据中数量很少或完全没出现的短语,例如一些领域专有名词、用户通讯录中的人名等,这些短语的识别准确程度对用户体验或下游任务的影响很大,但对于在通用数据上训练ASR系统来说又难以完全正确识别。因此语境偏置方法具有重要价值,旨在提升在这些“热词”上的识别准确率。

西工大音频与语音处理研究组(ASLP@NPU)近期在语音研究顶级会议 INTERSPEECH2023发表了论文题目为“Contextualized End-to-End Speech Recognition with Contextual Phrase Prediction Network”。该论文提出了一种基于热词短语预测网络的深度热词增强方法,该网络利用热词编码来预测语音中的热词,并通过计算偏置损失来辅助深度偏置模型的训练。所提出的方法能够应用在多种主流端到端ASR模型上,显著改进模型在热词数据上的识别准确率。

该方案的代码主要由该论文的一作黄凯勋同学完成,目前已开源在WeNet社区,详见:https://github.com/wenet-e2e/wenet/pull/1982

基于规则的热词增强

WeNet 之前实现的热词方案为基于规则的热词增强,即在解码过程中匹配到热词列表中的词时,给予该解码路径一定的奖励,这样含热词的搜索路径概率更大,更容易被识别出来。详见:

WeNet 热词增强 2.0 强势来袭

WeNet 更新:支持热词增强

虽然该方案在一般情况下也能有不错的处理能力,但对于训练中少见或没有见过的词即 rare word 的识别效果却非常很差。本质上因为该方法为浅融合(shadow fusion,或者后融合)的热词方案,在训练中没有见过,很难预测出来,在解码候选路径中根本没有出现,所以再怎么奖励也无济于事。而下文介绍的神经网络的热词则为深融合(deep fusion,或者前融合)则可以非常有效的解决 rare word 的问题,同时在常见热词识别也有更好的效果。

神经网络热词增强

基于神经网络的热词增强在端到端ASR模型中引入了一组独立的偏置模块来建模、集成热词信息,将热词增强的过程放到了神经网络模型推理的过程中。相比于传统的基于解码图的热词增强方案,神经网络热词增强使用上十分灵活,对于较小的热词列表可以取得优于解码图增强方案的效果,并且对于训练集中从未出现的罕见词也有着良好的增强效果。

近年来,神经网络热词增强方法得到了快速的发展。在2018年,谷歌首先提出了 CLAS 模型 [2],在 LAS 模型上通过全神经网络的方式集成热词信息。CLAS 的模型结构如下图所示,其中包含的两个偏置模块为:

  • 热词编码器(Bias Encoder):通过 RNN 对热词信息进行编码,将不等长的热词编码为相同维度的热词嵌入。

  • 热词偏置层(Attention):包含一个多头注意力层,使用音频编码作为 Query,热词编码作为 Key 和 Value,查询与当前音频相关的热词,提取热词感知编码。

图片

后续的神经网络热词增强研究基本沿袭自 CLAS,分为“编码热词、查询音频相关热词并集成信息”两步。在其他 ASR 模型上,提出了适用于 RNNT [3] 以及 CIF [4] 模型的神经网络热词增强模型,在神经网络增强方法上也产生了许多变体,如 TCPGen [5] 和 NAM [6] 等。

CPPN 论文介绍

之前的神经网络热词增强研究大多探索在如 RNNT 等 ASR 模型上实现或提升热词增强的效果,缺少在 AED 模型上有效的纯神经网络热词增强方法。因此,我们最初的动机就是寻找 AED 模型上有效的神经网络热词增强方案,并且由于我们使用 WeNet 框架进行实验,基于 attention rescore 解码依靠 CTC 后验的特点,我们希望能够在 Encoder 部分就能进行神经网络热词增强。

在实验最初阶段,我们尝试将一个基础的包含热词编码器以及热词偏置层的热词增强模块加入 AED 模型的 Encoder 中进行训练,但是模型却完全没有学习到热词增强的能力,推理过程中加入热词信息几乎不会对结果产生任何影响。我们分析认为这很可能是由于对 AED 模型而言,热词增强模块更难学习到热词编码与音频编码之间的联系。如果仅依靠 ASR 的损失函数进行训练,在没有对热词增强任务给出明确的监督的情况下,模型就会倾向于直接放弃热词增强模块的输出。因此我们研究的重心便转移到了寻找一个对于热词增强任务有效的监督损失上。

最直观的想法就是让热词增强模块直接预测出语句中包含的热词,但热词模块的输入输出长度与音频编码长度相同,这就存在编码长度与语句中包含的热词短语长度之间的不匹配。我们实验发现 CTC 损失可以很好的解决这个问题,并且由于 WeNet AED 模型的实现中 Encoder 本身也依靠 CTC 损失进行辅助训练,在预测热词任务上同样使用 CTC 损失可以让热词增强模块更好的契合 Encoder 的输出。在此基础上,我们提出了基于热词短语预测网络(Contextual Phrase Prediction Network, CPPN)的热词语音识别方案。热词增强模型结构如下图所示。

图片

图(c)是我们在 AED 模型基础上实现的热词增强模型结构,由于仅对模型 Encoder 部分进行了修改,因此没有画出 Decoder 部分的结构,这样的热词增强方案同样适用于仅包含一个 Encoder 的 CTC 模型。在 AED 热词增强模型中,热词增强相关的模块有:

  • 热词编码器(Context Encoder):我们使用 BLSTM 作为热词编码器对热词短语进行编码。

  • 热词偏置层(Biasing Layer):如图(b)所示,查询与当前音频相关的热词,提取热词感知编码。

  • 组合器(Combiner):拼接音频编码与热词感知编码,并通过一个线性层集成信息。

  • 热词短语预测网络(CPP Network):如图(a)所示,包含两个线性层,其中第二个线性层与 Encoder 的 CTC 线性层共享参数。热词短语预测网络使用热词感知编码作为输入,对语句中包含的热词短语进行预测,并使用 CTC 损失监督训练。例如对于语句标签为“我想去西工大学习语音识别”,如果“西工大”和“语音识别”是热词,则热词短语预测网络的标签为“西工大语音识别”。

图(d)是在 RNNT 模型基础上实现的热词增强模型结构,我们在 CATT [7] 热词增强方案的基础上添加了热词短语预测网络,相比于 AED 模型,在标签编码器(Label Encoder)后也添加了热词偏置层。

基于神经网络的热词增强方案还存在对于热词短语列表的大小较为敏感的问题,由于模型依靠注意力机制查找与音频关联的热词短语,当给出的热词列表过大时,注意力就会较为分散,影响热词增强的效果。因此,我们引入了一种两阶段的热词短语筛选算法[8],首先在不计算热词增强模块的情况下计算模型encoder部分的输出,使用 CTC 后验分别计算后验和置信度(PSC)和序列顺序置信度(SOC)以筛选出最可能出现在音频中的热词,然后构建成更小的热词列表再进行神经网络热词增强。

更多方案细节可参考推文:

Interspeech2023 | 基于热词短语预测网络的热词语音识别

模型实现

  1. 大部分热词增强模块的实现都位于 transformer/context_module.py 中,我们在 ContextModule 类中分别声明了热词编码器、热词偏置层、组合器、热词短语预测网络,以及增强任务的 CTC 损失。相比于论文中的实现,在此处我们将组合器替换为了更加简单的通过一个线性层后直接与音频编码相加的形式,这样能使 ASR 模型与热词模块更加解耦,并且经测试效果基本没有区别。并且我们还额外设置了一个热词增强权重用于控制热词增强的程度,热词感知编码先会与该权重相乘后再与音频编码相加。

class ContextModule(torch.nn.Module):"""Context module, Using context information for deep contextual biasDuring the training process, the original parameters of the ASR modelare frozen, and only the parameters of context module are trained.Args:vocab_size (int): vocabulary sizeembedding_size (int): number of ASR encoder projection unitsencoder_layers (int): number of context encoder layersattention_heads (int): number of heads in the biasing layer"""def __init__(self,vocab_size: int,embedding_size: int,encoder_layers: int = 2,attention_heads: int = 4,dropout_rate: float = 0.0,):super().__init__()self.embedding_size = embedding_sizeself.encoder_layers = encoder_layersself.vocab_size = vocab_sizeself.attention_heads = attention_headsself.dropout_rate = dropout_rate# 热词编码器self.context_extractor = BLSTM(self.vocab_size, self.embedding_size,self.encoder_layers)self.context_encoder = nn.Sequential(nn.Linear(self.embedding_size * 4, self.embedding_size),nn.LayerNorm(self.embedding_size))# 热词偏置层self.biasing_layer = MultiHeadedAttention(n_head=self.attention_heads,n_feat=self.embedding_size,sdropout_rate=self.dropout_rate)# 组合器self.combiner = nn.Linear(self.embedding_size, self.embedding_size)self.norm_aft_combiner = nn.LayerNorm(self.embedding_size)# 热词短语预测网络self.context_decoder = nn.Sequential(nn.Linear(self.embedding_size, self.embedding_size),nn.LayerNorm(self.embedding_size),nn.ReLU(inplace=True),)self.context_decoder_ctc_linear = nn.Linear(self.embedding_size,self.vocab_size)# 热词 CTC 损失self.bias_loss = torch.nn.CTCLoss(reduction="sum", zero_infinity=True)
  1. 我们将热词短语筛选部分的代码放到了 /utils/context_graph.py 中实现,该文件原本负责实现基于解码图的热词增强,包含有解码时所用的热词列表的信息,因此适合在此处进行热词短语筛选并将 tensor 形式的热词列表传递给热词增强模块。

class ContextGraph:def get_context_list_tensor(self, context_list: List[List[int]]):"""Add 0 as no-bias in the context list and obtain the tensorform of the context list"""def two_stage_filtering(self,context_list: List[List[int]],ctc_posterior: torch.Tensor,filter_window_size: int = 64):"""Calculate PSC and SOC for context phrase filtering,refer to: https://arxiv.org/abs/2301.06735"""
  1. 训练时热词采样的代码位于 /dataset/processor.py 的 context_sampling 与 context_label_generate 方法中。在训练时,我们从每条话语中随机抽取数个长度随机的短语作为该条话语的热词,每个 batch 抽取出的热词短语再加上一些干扰短语(来自之前 batch 的热词)共同构成该 batch 的热词列表。

def context_sampling(data,symbol_table,len_min,len_max,utt_num_context,batch_num_context,):"""Perform context sampling by randomly selecting context phrases from theutterance to obtain a context list for the entire batchArgs:data: Iterable[List[{key, feat, label}]]Returns:Iterable[List[{key, feat, label, context_list}]]"""def context_label_generate(label, context_list):""" Generate context labels corresponding to the utterances based onthe context list"""

实验结果

我们在 Librispeech test other 测试集上进行测试,使用 [9] 中给出的热词列表,热词列表可以从该链接获取:https://github.com/facebookresearch/fbai-speech/tree/main/is21_deep_bias

我们使用 WeNet 开源的 Librispeech 预训练 AED 模型进行实验,冻结原本 ASR 模型的参数,仅对热词增强模块训练 30 epoch 后取 3 个 epoch 平均得到的模型作为结果。在训练时,需要关闭 use_dynamic_chunk 流式训练选项,开启该选项会使得热词增强效果变差。经过测试非流式训练得到的模型对非流式和流式解码具有基本一致的热词增强性能。训练好的热词增强模型可以从该链接下载:https://huggingface.co/kxhuang/Wenet_Librispeech_deep_biasing/tree/main

除了词错误率 (WER) 之外,我们分别使用 U-WER 和 B-WER 来评估非热词部分与热词部分的字错误率,实验的结果如下。

非流式推理:

MethodList sizeGraph scoreBiasing scoreWERU-WERB-WER
baseline///8.775.5836.84
context graph38383.0/7.755.8324.62
CPPN3838/1.57.935.9225.64
context graph + CPPN38382.01.07.666.0821.48
context graph1003.0/7.325.4523.70
CPPN100/2.07.085.3322.41
context graph + CPPN1002.51.56.555.3317.27

表中 context graph 表示 WeNet 中基于解码图的热词增强方法。在使用较大热词列表(3838)的情况下,基于解码图的方法效果较好,而使用较小热词列表(100)的情况下,CPPN 的增强效果则更好。而无论热词列表大小,以合理的增强权重和分数同时使用两种方法时都能够取得比单一方法更好的效果。

热词列表(3838)的情况下,基于解码图的方法效果较好,而使用较小热词列表(100)的情况下,CPPN 的增强效果则更好。而无论热词列表大小,以合理的增强权重和分数同时使用两种方法时都能够取得比单一方法更好的效果。

小热词列表实验同时还表现出了非热词部分 WER 下降的情况,这是由于经过热词增强,模型在波束搜索时能够选择到包含正确热词并且非热词部分更加准确的路径。

流式推理 (chunk 16):

MethodList sizeGraph scoreBiasing scoreWERU-WERB-WER
baseline///10.477.0740.30
context graph1003.0/9.066.9927.21
CPPN100/2.08.866.8726.28
context graph + CPPN1002.51.58.176.8519.72

在流式推理的结果中,使用CPPN也有显著的 B-WER 改进,与非流式推理热词增强效果基本一致。

参考文献

[1] Kaixun Huang, Ao Zhang, Zhanheng Yang, Pengcheng Guo, Bingshen Mu, Tianyi Xu, Lei Xie: Contextualized End-to-End Speech Recognition with Contextual Phrase Prediction Network. INTERSPEECH 2023

[2] Golan Pundak, Tara N. Sainath, Rohit Prabhavalkar, Anjuli Kannan, Ding Zhao: Deep Context: End-to-end Contextual Speech Recognition. SLT 2018

[3] Mahaveer Jain, Gil Keren, Jay Mahadeokar, Geoffrey Zweig, Florian Metze, Yatharth Saraf: Contextual RNN-T for Open Domain ASR. INTERSPEECH 2020

[4] Minglun Han, Linhao Dong, Shiyu Zhou, Bo Xu: Cif-Based Collaborative Decoding for End-to-End Contextual Speech Recognition. ICASSP 2021

[5] Guangzhi Sun, Chao Zhang, Philip C. Woodland: Tree-Constrained Pointer Generator for End-to-End Contextual Speech Recognition. ASRU 2021

[6] Tsendsuren Munkhdalai, Khe Chai Sim, Angad Chandorkar, Fan Gao, Mason Chua, Trevor Strohman, Françoise Beaufays: Fast Contextual Adaptation with Neural Associative Memory for On-Device Personalized Speech Recognition. ICASSP 2022

[7] Feng-Ju Chang, Jing Liu, Martin Radfar, Athanasios Mouchtaris, Maurizio Omologo, Ariya Rastrow, Siegfried Kunzmann:

Context-Aware Transformer Transducer for Speech Recognition. ASRU 2021 [8] Zhanheng Yang, Sining Sun, Xiong Wang, Yike Zhang, Long Ma, Lei Xie: Two Stage Contextual Word Filtering for Context bias in Unified Streaming and Non-streaming Transducer. INTERSPEECH 2023

[9] Duc Le, Mahaveer Jain, Gil Keren, Suyoun Kim, Yangyang Shi, Jay Mahadeokar, Julian Chan, Yuan Shangguan, Christian Fuegen, Ozlem Kalinli, Yatharth Saraf, Michael L. Seltzer: Contextualized Streaming End-to-End Speech Recognition with Trie-Based Deep Biasing and Shallow Fusion. INTERSPEECH 2021

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/107465.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows10系统下Python3.11中安装Numpy库教程

Python3.11中安装Numpy库目录 项目场景:问题描述解决方案:①下载Numpy文件②把NumPy文件放到Python安装的Scripts文件夹里。③安装numpy④安装验证 项目场景: numpy是开源的数值计算扩展,用于数据分析、机器学习、科学计算的重要…

pgzrun 拼图游戏制作过程详解(3)

3. 绘制完整的拼图 建立Gird列表存储小拼图的基本信息 Gird[] for i in range(6):for j in range(4):SquareActor("girl_06")Square.leftSquare_size*jSquare.topSquare_size*iGird.append(Square) 修改draw()绘制函数 建立循环绘制Gird列表中的所有小拼图 def d…

开源大模型ChatGLM2-6B 1. 租一台GPU服务器测试下

0. 环境 租用了1台GPU服务器,系统 ubuntu20,GeForce RTX 3090 24G。过程略。本人测试了ai-galaxy的,今天发现网友也有推荐autodl的。 (GPU服务器已经关闭,因此这些信息已经失效) SSH地址:* 端…

虚拟机作为master远程控制台式机中的机器人在仿真环境中进行slam地图构建与自主导航

文章目录 前言一、思路流程二、具体步骤1.虚拟机网络配置2.台式机网络配置3.网络测试 三、远程操控SLAM建立地图三、远程操控SLAM导航 前言 虚拟机作为master远程控制台式机中的机器人在仿真环境中进行slam地图构建与自主导航 最近有时间一直在搞Ubuntu虚拟机与台式机的通讯&…

Java复习-多线程编程

多线程编程 解决并发访问的问题。 一. 继承 Thread 类实现多线程 1. 继承实现 继承thread类 class MyThread extends Thread{}覆写run主方法 多线程要执行的功能都应该在 run() 方法中定义。 class MyThread extends Thread { // 线程的主体类private String title;public…

澄海区图书馆《乡村振兴战略下传统村落文化旅游设计》许少辉八一新著

澄海区图书馆《乡村振兴战略下传统村落文化旅游设计》许少辉八一新著

2022年全国研究生数学建模竞赛华为杯D题PISA架构芯片资源排布问题求解全过程文档及程序

2022年全国研究生数学建模竞赛华为杯 D题 PISA架构芯片资源排布问题 原题再现: 一、背景介绍 芯片是电子行业的基础,在当前日益复杂的国际形势下,芯片成了各个大国必争的高科技技术。本课题关注网络通信领域的交换芯片,传统的交…

华为云云耀云服务器L实例评测|使用Linux系统与Docker部署.net/c#项目

目录 前言 如何在CentOS运行项目 登录CentOS 使用Rider打包 使用Visual Studio打包 项目运行 后台运行 开放端口 如何在Docker中运行项目 项目运行 前言 本章详细介绍,.net Core项目从打包到部署上华为云云耀云服务器L实例的过程与一些细节问题。在这里…

解决stable diffusion webui1.6 wd1.4 tagger加载失败的问题

由于webui源码的变化,需要修改两个地方的import 1.tagger/ui.py # 第十行 # from webui import wrap_gradio_gpu_call # 原代码 from modules.call_queue import wrap_gradio_gpu_call1.preload.py # 第4行开始 # from modules.shared import models_path # 原…

每日一博 - 闲聊经典微服务架构

文章目录 概述Arch小结 概述 典型的微服务架构是一种软件架构模式,其中一个应用程序被拆分成多个小型、相对独立的服务单元,每个服务单元都专注于执行特定的业务功能。这些服务单元可以独立开发、部署和扩展,通常通过网络通信协议进行互相通…

docker 部署 node.js(express) 服务

1、在 express 项目根目录下新增 Dockerfile 文件,内容如下: 创建服务容器的方法,可以根据自己的情况选择: 1、以下示例为宿主机没有安装 node 环境的写法; 2、先在本地构建包含 node 和 express 的基础镜像&#xff0…

第6章_freeRTOS入门与工程实践之创建FreeRTOS工程

本教程基于韦东山百问网出的 DShanMCU-F103开发板 进行编写,需要的同学可以在这里获取: https://item.taobao.com/item.htm?id724601559592 配套资料获取:https://rtos.100ask.net/zh/freeRTOS/DShanMCU-F103 freeRTOS系列教程之freeRTOS入…