语音识别之Kaldi学习GMM-HMM

news2025/1/11 20:50:37

语音识别之Kaldi

kaldi语音识别理论与实践课程学习。

前面的博客介绍了语音识别的基础知识及原理。现在开始学习实战。以Kaldi框架为基础。

Kaldi是一个有全套的语音识别代码的工具,由Dan Povey博士和捷克的BUT大学联合开发,最早发布于2011年,底层代码使用C++编写,接口采用shell和python,覆盖了统计模型和深度学习方法,操作灵活,易于扩展,开发者更为活跃。

语音识别流程:

在这里插入图片描述

目前开源的语料库有:
在这里插入图片描述

Kaldi实战

Kaldi官网:KALDI

里面有详细的文档。
在这里插入图片描述

  • 下载Kaldi:https://github.com/du-ud/kaldi-cslt.git
    注: 安装kaldi前, 已编译好cuda
    在这里插入图片描述

  • 下载数据集:(开源数据集thchs30)
    OpenSLR: https://openslr.org/18/

整个流程包括以下几个部分:
在这里插入图片描述

数据准备

数据预处理
1.划分为训练集train和测试集test

在这里插入图片描述
输入: 数据存储地址
输出: 在当前目录下新生成的 /data 文件夹,里面如下图。train和test里的文件夹名字一样,但内容不一样,不然就是作弊了。
在这里插入图片描述

  • wav.scp:音频索引地址
    在这里插入图片描述
  • text:音频文件对应的文本内容
    这个文本内容中间有一些空格,因为是经过了分词处理
    在这里插入图片描述
  • utt2spk:每个句子是有哪个说话人说的
    在这里插入图片描述
  • spk2utt:每个说话人都说了哪些句子
    在这里插入图片描述
    为什么有后两个文件夹呢?
    因为之前的数据比较稀少,说话人对语音识别性能的影响比较大,可能同一套ASR对这个人识别效果好,对另一个人就不行。现在可以通过某种算法,先提取说话人信息,将该信息从说话人模型中去除,就可以较小不同说话人的影响。但后面随着数据的增多,就不用去除了。

2.生成dict文件夹

在这里插入图片描述
dict 文件夹里如下:
在这里插入图片描述

去除了lexion里面的一些特殊符号。首先打开看一下:

cd data/dict/
vim lexicon.txt

lexion是一个发音词典,表示每个字的读音,但它的注音和我们的拼音不太一样但也差不多
在这里插入图片描述

再看看lang里面的

cd data/dict/
vim extra_questions.txt

将具有相同还声调的音归为一行,为了有助于GMM训练时决策树的聚类。如果后面训练别的语种,不知道这些信息的话就把这和文件设为空。
在这里插入图片描述

cd data/dict/
vim nonsilence_phones.txt

去除静音音素之外,所有音素的集合。
在这里插入图片描述
3.生成lang文件夹
是在dict基础上生成的。
首先在data文件夹下建一个lang文件夹,调用prepare_lang.sh这个脚本,输入是dict文件,输出在lang文件夹下。
在这里插入图片描述
里面的两个参数:
第一个考虑到英文的某个单词是另一个单词的前缀或后缀(位置相关),在数据有限的情况下,考虑位置信息提高性能。数据量大的话不用考虑。
第二个就是系统将不认识的词映射到oov里面。

在这里插入图片描述

lang文件夹里如下:
在这里插入图片描述

  • L.fst:音素到词的映射关系。输入的是音素,输出是词。
cd data/lang
fstprint L.fst | head -n 20

例:第一行
前两个数,表示从0状态跳转到1状态
三四数:输入输出表达的什么东西
第五个数:跳转的概率
在这里插入图片描述
加上输入phones和输出words重新打印

cd data/lang
fstprint --osymbols=words.txt --isymbols=phones.txt L.fst | head -n 20

第三列:phone的id
第四列:word的id
第五列:预先赋予的跳转概率(给eps, spokenNoise等这些特殊符号的),下面那些词的概率需要经过声学&语言模型的训练得到的。
在这里插入图片描述

  • oov:将不认识的集外词映射到里面去。
  • phones.txt:音素映射表,对每个音素进行编号
  • phones文件夹:用于决策树聚类
    我们看一下里面
cd data/lang
head -n 20 phones.txt

出现下图中间的一个。

数据准备-phone、word与lexicon的关系
在这里插入图片描述

  • words.txt:词映射表,对每个词进行编号
    里面的词和发音词典的词基本一一对应(发音词典大概有五万多个词,对应的词表只有四万九千多个,近几年的新词还没包含进去)
cd data/lang
head -n 20 words.txt

在这里插入图片描述

  • topo:拓扑图,隐马尔可夫网络HMM
cd data/lang
vim topo

里面有两个HMM网络,一个是普通音素的,一个是静音音素的。
下图从2到218就是phone的id, 然后是HMM的三个跳转状态和一个输出状态。
在这里插入图片描述

跳转状态图:
在这里插入图片描述

特征提取

目前常见的两种特征。一般MFCC特征用于GMM训练,FBANK特征用于DNN训练。
在这里插入图片描述

先删除残留文件夹,新建两个目录,将训练集和测试集复制进去。
提取MFCC及FBank特征,并计算其均值和方差。
在这里插入图片描述

MFCC和FBank特征提取原理:
在这里插入图片描述
在这里插入图片描述

计算MFCC命令

. ./path.sh
compute-mfcc-feats

比如:参数1和2就是降采样和升采样。这些选项可以放到.conf配置文件里面。
在这里插入图片描述

生成如下目录:

cd data/mfcc/train
ls

在这里插入图片描述

查看MFCC:

. ./path.sh
cd data/mfcc/train/data
copy-feats ark:raw_mfcc_train.1.ark ark,t:train.1.ark.txt
vim train.1.ark.txt

行:帧数,一帧为一行
列:维度,MFCC特征默认13维

以A02_000音频为例:
在这里插入图片描述
然后看下均值方差,是按每个说话人提取的

. ./path.sh
cd data/mfcc/train/data
copy-feats ark:cmvn_train.ark ark,t:cmvn_train.ark.txt
copy-feats --binary=false ark:cmvn_train.ark ark:cmvn_train.ark.txtvim train.1.ark.txt

行:均值总和、方差总和
在这里插入图片描述

查看log:
kaldi的log非常全,索引对不上,采样不一致等问题都有。

cd data/mfcc/train/log/
vim make_mfcc_train.1.log

在这里插入图片描述

GMM训练

整体过程:
共有5大模块,可分为10小步。每两步一个模块。
1.先训练一个单音素模型;2.对齐
3.再训练一个三音素模型;4.对齐
5.用lda等算法重估GMM模型; 6.对齐

在这里插入图片描述

mono单音素模型训练

命令如下,

steps/train_mono.sh --boost-silence 1.25 --nj 10 --cmd
"run.pl" data/mfcc/train data/lang exp/mono

参数:
–boost-silence:静音音素权重设置,1.25 一般不用改
–nj 10:就是用10个线程(小于等于训练集中说话人数量)
run.pl:在本机跑

输入1: MFCC数据 ( data/mfcc/train)
输入2: lang (data/lang)
输出: 单音素模型(exp/mono)

具体流程:
在这里插入图片描述

  • 模型初始化:有GMM模型的均值、方差,和隐马尔可夫的转移矩阵。随机生成,其实也不是真正随机,用了训练集的部分特征。

  • 制作graph:需要输入上一步初始化的模型,lang文件中的L.fst,词表,以及训练集中的标注文本。生成结果是一个从句子到音素的fst压缩包,是训练集中每一个音频对应的文本标签生成的,一个文本标签生成一个fst。(句子-词-字-拼音-音素-HMM中的状态)

  • 等对齐:均匀对齐。现在要将MFCC特征和fst对应起来。
    黄色是MFCC特征,每条是一帧,一帧是13维。
    要与下面的fst对齐。(只画到音素级别)
    在这里插入图片描述
    什么是均匀对齐?就是假如现在是4个音素,对应100帧,那就平分,每个音素对100/4=25帧。统计这25帧的均值和方差,就是一个高斯模型了。
    后面还有三音素模型(考虑了协调发音):
    在这里插入图片描述
    但存在一个问题:本来有两百多个音素,但考虑了前后协同发音,就成了200* 200* 200个了,这个数量太大了。
    解决办法:决策树聚类(将具有相近发音的音素归为一类,集中训练)

  • 模型重估:现在已经统计了全部数据的特征,也通过对齐知道了每帧对应的状态,以及每个状态的跳转概率。基于这些信息对模型进行重估。

  • 对齐信息:用重估后的统计量和前面的fst生成新的对齐信息。注意,此时不是均匀对齐了,此时过程可理解为一个模型对训练集的解码过程,把每帧特征放到每个状态对应的GMM里算概率,得到每个状态的后验概率,概率最大的音素作为这一帧对应的音素。
    此时可能第一个音素20帧,第二个音素28帧等等。

  • 统计计算:计算每个音素跳转的次数占全部跳转次数的比例。得到每个状态的跳转概率,又进行模型重估,重复该过程(重复次数可以自己设置,默认40次)。

跑完代码生成的东西:
在mono文件夹里
在这里插入图片描述
final.occs:简单理解为全局统计量,每个音素对应几个状态的信息
aligz:每迭代一次,对齐信息跟新一次
fst.
.gz:训练集中每条语音对应的文本信息(句子-词-字-拼音-音素-HMM中的状态)都在这里面

final模型查看

声学模型不能直接代开看,用kaldi自带的命令打开:

gmm-copy --binary=false final.mdl final.mdl.txt

在这里插入图片描述
1-23行是HMM的拓扑图。7-10行是音素编号为2-218的HMM,其状态有3个。16-21行是音素编号为1的HMM,其状态有5个,也就是静音音素。24行是决策树聚类数,656类。

为什么是656类呢?
在这里插入图片描述
左图:25-29行是中间一列0-4(静音),剩下的都是0,1,2。
右图:第一列共218个音素,第二列状态,第三列决策树聚类数。

静音是5个状态,剩下都是3状态:217* 3+5=656

后面还有如下信息:
在这里插入图片描述
MFCC维度39:因为作了一阶二阶差分(13+13+13)
Weigh两个:说明是两个单高斯组成的GMM
均值39列,方差39列

GCONSTS的超参是什么呢?

W权重,后面是标准的高斯。取出了与x无关的项,提前计算好,这样后面就可以减少计算量。
在这里插入图片描述

final.occs查看

show-transitions phones.txt final.mdl final.occs > final.occs.txt

对每个HMM的描述
在这里插入图片描述
以前5行为例,描述状态1到1(自环),2,3,4的过程。
在这里插入图片描述
提特征按帧级别提的,
训练也是按帧级别训练的,
训练的结果是什么?

对齐信息查看

. ./path.sh
ali-to-phones

里面是每个phone的对齐信息
在这里插入图片描述
每个phone-id对应的音素是什么?

cd exp/mono
gunzip -c ali.1.gz | ali-to-phones --per-frame=true final.mdl ark:- ark,t:- | ../../utils/int2sym.pl -f 2- phones.txt

每帧特征对应的音素,
在这里插入图片描述
每个音素持续的时间是多久?

gunzip -c ali.1.gz | ali-to-phones --ctm-output=true final.mdl ark:- -| ../../utils/int2sym.pl -f 5 phones.txt

以A02_000为例:

文本内容:
绿 是 阳春 烟 景 大块 文章 的 底色 四月 的 林 峦 更是 绿 得 鲜活 秀媚 诗意 盎然
在这里插入图片描述
比如:前0.87s都是静音段,绿这个字lv4,从0.87s到0.1s,持续了0.1+0.2s=0.3s。可以用音频播放软件看看对的准不准。

网格信息查看

cd exp/mono
gunzip fsts.1.gz
fstcopy ark:fsts.1 ark,t:fsts.1.txt

存的词、字、音素、状态之间的映射关系,跳转关系
在这里插入图片描述

决策树

cd exp/mono
tree-info tree

里面有三行信息:
在这里插入图片描述
context-width:单音素模型就是1,三音素就是3
central-position:单音素就是0,三音素就是1(0,1,2,看到1就是中间位置)

画出决策树:

cd exp/mono
draw-tree phones.txt tree | dot -Gsize=8,10.5 -Tps | ps2pdf - tree.pdf

在这里插入图片描述
静音的HMM有5个状态,其他都是3个。

log分析:

用于检查错误
在这里插入图片描述
init.log:模型初始化时产生的
compile.log:fst时产生的
align.log:对齐时产生的

这样,就完成了下图流程中的第1,2,3步。
在这里插入图片描述
同样的方法,进行第4步:

训练aligh_si.sh

steps/align_si.sh --boost-silence 1.25 --nj 10 --cmd "run.pl"
data/mfcc/train data/lang exp/mono exp/mono_ali

此时:
在这里插入图片描述
查看mono_ali.sh生成内容:

cd mono_ali
gunzip -c ali.1.gz | ali-to-phones --ctm-output=true final.mdl
ark:- -| ../../utils/int2sym.pl -f 5 phones.txt

在这里插入图片描述
对齐信息和之前一样,说明单音素模型迭代没有效果,就这样了,需要新的算法来提升模型对齐能力。

GMM训练-对比mono_ali、 tri4b_ali对齐信息
A02_000文本:
绿 是 阳春 烟 景 大块 文章 的 底色 四月 的 林 峦 更
mono tri4b 是 绿 得 鲜活 秀媚 诗意 盎然

mono_ali: sox A2_0.wav part.wav trim 0.87 0.3

tri4b_ali : sox A2_0.wav part.wav trim 0.86 0.29

在这里插入图片描述
此时对齐的时间不一样了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文献检索工具 | 计算机类英文文献检索数据库DBLP

文章目录1.什么是DBLP?2.DBLP文献检索的3种方式2.1.检索指定会议/期刊的论文2.2.检索指定作者的论文2.3.检索指定题目的论文3.Tips:DBLP中各个颜色模块含义1.什么是DBLP? 定义: DBLP(DataBase systems and Logic Programming&…

JS 数组去重的多种方法

1. 前言 2. 普通方法数组去重 3. filter indexOf 4. ES6 的 new Set() 5. 需要注意的问题 1. 前言 本文提供两个数组变量供测试使用 const array [html, css, js, css]const resArr [html, css, css, [1], [1]]2. 普通方法数组去重 下面列举几种数组去重的方法思路都一…

JavaScript大作业 制作简单的程序员个人博客网站(web前端网页制作课作业)

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

花钱去IT培训班学习几个月软件测试真的值得吗?

为什么网上一问去IT培训机构报班学软件测试,一大堆人就会跳出来说不建议、劝退、建议自学? 为什么IT培训机构那么多坑,还有那么多学生愿意花几万块钱去学软件测试? 有人说:网上那么多的视频资料,很多都是…

五、输入输出管理(二)I/O管理概述

目录 2.1 I/O 软件层次结构 2.1.1用户层 I/O 软件 2.1.2设备独立软件 2.1.3设备驱动程序 2.2应用程序与I/O接口 2.2.1字符设备接口 2.2.2块设备接口 2.2.3网络设备接口 2.2.4阻塞/非阻塞 I/O I/O系统概述、I/O接口、I/O控制的四种方式(程序直接控制方式、程…

Trimble Tekla Structures支持14种不同的语言

Trimble Tekla Structures支持14种不同的语言 Tekla Structures被称为前Xsteel,是Trimble Software的产品,Trimble软件是一种强大的BIM机器。该软件为用户提供的环境,用户可以绘制接下来的三个模型并从中提取接下来的两个模型。该软件制作的模…

linux下pycharm运行错误解决办法

错误1: Inspection info:this inspection detects names that should resolve but dont.due to dynamic dispatch 重新设置虚拟环境即可,前面几篇文章有如何配置虚拟环境的教程 错误2: 有时候即使我们配好环境后在代码中也会出…

【玩转c++】c++内存管理 new/delete

本期主题:c/c内存管理。 博客主页:小峰同学分享小编的在Linux中学习到的知识和遇到的问题小编的能力有限,出现错误希望大家不吝赐身为程序员 ,不会有人没有女朋友吧。 目录 🍁1. 了解c/c内存区域划分 🍁2.…

hbuilderx升级3.6.5版本后运行到手机端同步资源失败,未得到同步资源的授权,请停止运行后重新运行,并注意手机上的授权提示

问题1: hbuilderx升级3.6.5版本后运行到手机端同步资源失败,未得到同步资源的授权,请停止运行后重新运行,并注意手机上的授权提示。 解决问题指路。 https://uniapp.dcloud.net.cn/tutorial/run/run-app-faq.html#node https://un…

在线考试系统毕业设计,线上考试系统设计与实现,毕业设计论文源码开题报告需求分析

项目背景和意义 目的:本课题主要目标是设计并能够实现一个在线考试的java系统,整体使用了基于浏览器的B/S架构,技术上使用了基于java的springboot框架;使用浏览器,通过后台添加考试题目,学生通过浏览器登录…

一文解决网络系统调用接口到内核的请求

网络套接字入口函数 //所有的网络套接字系统调用函数(socket bind listen connect )都使用一个共同的入口函数:sys_socketcall /* 第一个参数call表示被调用的应用层接口函数,第二个参数是一个指针,指向具体被调用函数…

【综合案例】原生JS实现购物商城

目录一、案例说明1、目录结构2、conf文件夹3、用户名密码的正则和ajax的封装二、登录页的实现1、案例效果2、登录页逻辑3、接口文档4、代码实现5、返回信息显示三、首页的实现1、案例效果2、首页的逻辑3、接口文档4、代码实现5、返回信息显示四、个人中心1、案例效果2、个人页的…

springboot车辆管理系统的设计与实现毕业设计源码031034

车辆管理系统的设计与实现 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化,电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流,人类发展的历史正进入一个新时代。在现实运用中&…

Runtime源码解析-alloc

Runtime源码解析-alloc 前言alloc 通过汇编查看调用流程1. objc_alloc方法2. callAlloc方法 首次进入非首次进入LLVM优化 3. _objc_rootAllocWithZone方法4. _class_createInstanceFromZone方法 instanceSize:计算内存大小 fastInstanceSizealignedInstanceSize mal…

TS201的DMA通信基本原理以及IIR的加深理解(含源代码)

实验目的: 了解DMA通信基本原理,掌握内存与SDRAM间一维DMA通信方式、二维DMA通信方式以及相关控制方法。学习数字滤波器设计方法,掌握其调试步骤,使学生加深对IIR的理解,进一步提高对数字信号处理理论的认识。 实验任…

Java+SSM美妆商城全套电商购物(含源码+论文+答辩PPT等)

项目功能简介: 本项目含代码详细讲解视频,手把手带同学们敲代码从0到1完成项目 该项目采用技术Springmvc、Spring、MyBatis、Tomcat服务器、MySQL数据库 项目含有源码、配套开发软件、软件安装教程、项目发布教程以及代码讲解教程 项目功能介绍: 系统管理…

[附源码]计算机毕业设计酒店物联网平台系统Springboot程序

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

国标码的发展历史以及编码方式

文章目录引言GB2312GBKunicode 和 ISO10646ISO10646的编码结构结论参考文献引言 由于物理实现比较容易等原因计算机等数字系统内部使用二进制字符的记录、存贮、传递和交换通过编码来实现。字符的机内编码其实就是该字符在字符图库中的序号。拼音文字一般仅有几十个字母组成。而…

【传输层】TCP、三次握手、四次挥手、可靠传输、TCP拥塞控制、慢开始、拥塞避免、快重传、快恢复

文章目录TCP------打电话----可靠有序、不丢不重复--------提供全双工-------------发送接收缓存----------面向字节流--------搬砖一样加个头运走TCP首部格式-----源端口目的端口一共4B-------序号字段(报文第一个字节的序号)--------确认号&#xff08…

手机软件系统测试用例设计大全

一、 等价类分析法 二、 边界值分析 三、 错误猜测法 四、 判定表法 五、 流程分析方法 六、 正交试验设计法 七、 状态迁移法 等价类分析法等价类划分方法针对手机状态大致可以归几个大类: 按键类(等价法):有效输入和无效…