基于深度学习的中文语音识别系统框架(pluse)

目录

  • 声学模型
    • GRU-CTC
    • DFCNN
    • DFSMN
  • 语言模型
    • n-gram
    • CBHG
  • 数据集

本文搭建一个完整的中文语音识别系统,包括声学模型和语言模型,能够将输入的音频信号识别为汉字。

声学模型使用了应用较为广泛的递归循环网络中的GRU-CTC的组合,除此之外还引入了科大讯飞提出的DFCNN深度全序列卷积神经网络,也将引入阿里的架构DFSMN。

语言模型有传统n-gram模型和基于深度神经网络的CBHG网络结构,该结构是谷歌用于TTS任务中的tacotron系统,本文中将该系统部分结构移植过来用于搭建拼音序列生成汉字序列系统。

数据集采用了目前能找到的所有中文免费数据,包括:thchs-30、aishell、primewords、st-cmd四个数据集,训练集总计大约450个小时。

该项目地址在:https://github.com/audier/my_ch_speech_recognition写的时候可能有些乱,后续会整理。

声学模型

声学模型目前开源了部分示例模型,更大模型将在确认识别结果后更新。

GRU-CTC

我们使用 GRU-CTC的方法搭建了第一个声学模型,在gru_ctc_am.py中,利用循环神经网络可以利用语音上下文相关的信息,得到更加准确地信息,而GUR又能选择性的保留需要的信息。该模型使用python/keras进行搭建,本文系统都基于python搭建。
网络结构如下:
该结构没有真正使用,只是一个基本框架,类似于helloworld,用于作为示例。

def creatModel():input_data = Input(name='the_input', shape=(500, 26))layer_h1 = Dense(512, activation="relu", use_bias=True, kernel_initializer='he_normal')(input_data)layer_h1 = Dropout(0.2)(layer_h1)layer_h2 = Dense(512, activation="relu", use_bias=True, kernel_initializer='he_normal')(layer_h1)layer_h2 = Dropout(0.2)(layer_h2)layer_h3 = Dense(512, activation="relu", use_bias=True, kernel_initializer='he_normal')(layer_h2)layer_h4_1 = GRU(512, return_sequences=True, kernel_initializer='he_normal', dropout=0.3)(layer_h3)layer_h4_2 = GRU(512, return_sequences=True, go_backwards=True, kernel_initializer='he_normal', dropout=0.3)(layer_h3)layer_h4 = add([layer_h4_1, layer_h4_2])layer_h5 = Dense(512, activation="relu", use_bias=True, kernel_initializer='he_normal')(layer_h4)layer_h5 = Dropout(0.2)(layer_h5)layer_h6 = Dense(512, activation="relu", use_bias=True, kernel_initializer='he_normal')(layer_h5)layer_h6 = Dropout(0.2)(layer_h6)layer_h7 = Dense(512, activation="relu", use_bias=True, kernel_initializer='he_normal')(layer_h6)layer_h7 = Dropout(0.2)(layer_h7)layer_h8 = Dense(1177, activation="relu", use_bias=True, kernel_initializer='he_normal')(layer_h7)output = Activation('softmax', name='Activation0')(layer_h8)model_data = Model(inputs=input_data, outputs=output)#ctc层labels = Input(name='the_labels', shape=[50], dtype='float32')input_length = Input(name='input_length', shape=[1], dtype='int64')label_length = Input(name='label_length', shape=[1], dtype='int64')loss_out = Lambda(ctc_lambda, output_shape=(1,), name='ctc')([labels, output, input_length, label_length])model = Model(inputs=[input_data, labels, input_length, label_length], outputs=loss_out)model.summary()ada_d = Adadelta(lr=0.01, rho=0.95, epsilon=1e-06)model=multi_gpu_model(model,gpus=2)model.compile(loss={'ctc': lambda y_true, output: output}, optimizer=ada_d)#test_func = K.function([input_data], [output])print("model compiled successful!")return model, model_data

DFCNN

由于两个原因在使用GRU作为语音识别的时候我们会遇到问题。一方面是我们常常使用双向循环神经网络才能取得更好的识别效果,这样会影响解码实时性。另一方面随着网络结构复杂性增加,双向GRU的参数是相同节点数全连接层的6倍,这样会导致训练速度非常缓慢。
科大讯飞提出了一种使用深度卷积神经网络来对时频图进行识别的方法,就是DFCNN,利用CNN参数共享机制,可以将参数数量下降一个级别,且深层次的卷积和池化层能够充分考虑语音信号的上下文信息,且可以在较短的时间内就可以得到识别结果,具有较好的实时性。
该模型在cnn_witch_fbank.pycnn_ctc_am.py中,实验中是所有网络结果最好的模型,目前能够取得较好的泛化能力,声学模型识别率能够达到90%以上,其网络结构如下:
DFCNN

def creatModel():input_data = Input(name='the_input', shape=(800, 200, 1))# 800,200,32layer_h1 = Conv2D(32, (3,3), use_bias=True, activation='relu', padding='same', kernel_initializer='he_normal')(input_data)layer_h1 = BatchNormalization(mode=0,axis=-1)(layer_h1)layer_h2 = Conv2D(32, (3,3), use_bias=True, activation='relu', padding='same', kernel_initializer='he_normal')(layer_h1)layer_h2 = BatchNormalization(axis=-1)(layer_h2)layer_h3 = MaxPooling2D(pool_size=(2,2), strides=None, padding="valid")(layer_h2)# 400,100,64layer_h4 = Conv2D(64, (3,3), use_bias=True, activation='relu', padding='same', kernel_initializer='he_normal')(layer_h3)layer_h4 = BatchNormalization(axis=-1)(layer_h4)layer_h5 = Conv2D(64, (3,3), use_bias=True, activation='relu', padding='same', kernel_initializer='he_normal')(layer_h4)layer_h5 = BatchNormalization(axis=-1)(layer_h5)layer_h5 = MaxPooling2D(pool_size=(2,2), strides=None, padding="valid")(layer_h5)# 200,50,128layer_h6 = Conv2D(128, (3,3), use_bias=True, activation='relu', padding='same', kernel_initializer='he_normal')(layer_h5)layer_h6 = BatchNormalization(axis=-1)(layer_h6)layer_h7 = Conv2D(128, (3,3), use_bias=True, activation='relu', padding='same', kernel_initializer='he_normal')(layer_h6)layer_h7 = BatchNormalization(axis=-1)(layer_h7)layer_h7 = MaxPooling2D(pool_size=(2,2), strides=None, padding="valid")(layer_h7)# 100,25,128layer_h8 = Conv2D(128, (1,1), use_bias=True, activation='relu', padding='same', kernel_initializer='he_normal')(layer_h7)layer_h8 = BatchNormalization(axis=-1)(layer_h8)layer_h9 = Conv2D(128, (3,3), use_bias=True, activation='relu', padding='same', kernel_initializer='he_normal')(layer_h8)layer_h9 = BatchNormalization(axis=-1)(layer_h9)# 100,25,128layer_h10 = Conv2D(128, (1,1), use_bias=True, activation='relu', padding='same', kernel_initializer='he_normal')(layer_h9)layer_h10 = BatchNormalization(axis=-1)(layer_h10)layer_h11 = Conv2D(128, (3,3), use_bias=True, activation='relu', padding='same', kernel_initializer='he_normal')(layer_h10)layer_h11 = BatchNormalization(axis=-1)(layer_h11)# Reshape层layer_h12 = Reshape((100, 3200))(layer_h11) # 全连接层layer_h13 = Dense(256, activation="relu", use_bias=True, kernel_initializer='he_normal')(layer_h12)layer_h13 = BatchNormalization(axis=1)(layer_h13)layer_h14 = Dense(1177, use_bias=True, kernel_initializer='he_normal')(layer_h13)output = Activation('softmax', name='Activation0')(layer_h14)model_data = Model(inputs=input_data, outputs=output)# ctc层labels = Input(name='the_labels', shape=[50], dtype='float32')input_length = Input(name='input_length', shape=[1], dtype='int64')label_length = Input(name='label_length', shape=[1], dtype='int64')loss_out = Lambda(ctc_lambda, output_shape=(1,), name='ctc')([labels, output, input_length, label_length])model = Model(inputs=[input_data, labels, input_length, label_length], outputs=loss_out)model.summary()ada_d = Adadelta(lr=0.01, rho=0.95, epsilon=1e-06)#model=multi_gpu_model(model,gpus=2)model.compile(loss={'ctc': lambda y_true, output: output}, optimizer=ada_d)#test_func = K.function([input_data], [output])print("model compiled successful!")return model, model_data

DFSMN

而前馈记忆神经网络也也解决了双向GRU的参数过多和实时性较差的缺点,它利用一个记忆模块,包含了上下几帧信息,能够得到不输于双向GRU-CTC的识别结果,阿里最新的开源系统就是基于DFSMN的声学模型,只不过在kaldi的框架上实现的。我们将考虑使用DFSMN+CTC的结构在python上实现。该网络后续将实现。
结构如下:
DFSMN

语言模型

n-gram

n元语法是一个非常经典的语言模型,这里不过多介绍啦。

CBHG

该想法来自于一个大神搞输入法的项目,下面部分也引用此处:搜喵出入法
他是利用该模型建立一个按键到汉字的作用,本文对其结构和数据处理部分稍作改动,作为语言模型。

拼音输入的本质上就是一个序列到序列的模型:输入拼音序列,输出汉字序列。所以天然适合用在诸如机器翻译的seq2seq模型上。

模型初始输入是一个随机采样的拼音字母的character embedding,经过一个CBHG的模型,输出是五千个汉字对应的label。
这里使用的CBHG模块是state-of-art的seq2seq模型,用在Google的机器翻译和语音合成中,该模型放在language_model/CBHG.py中,结构如下:
图片来自 Tacotron: Towards End-to-End Speech Synthesis
CBHG

关于该模型值得注意的几点:

1.模型先使用一系列的一维卷积网络,有一系列的filter,filter_size从1到K,形成一个Conv1D Bank。这样的作用相当于使用了一系列的unigrams, bigrams直到K-grams,尽可能多的拿到输入序列从local到context的完整信息。其实这样的模型,与之前我们提到过的IDCNN(Iterated Dilated Convolutionary Nerual Network)有异曲同工之妙。而IDCNN相比较起来有更少的参数,不知道如果把CBHG的Conv1D Bank换成IDCNN是怎样的效果。

2.模型在最终的BiGRU之前加入了多层的Highway Layers,用来提取更高层次的特征。Highway Layers可以理解为加入了本来不相邻层之间的“高速公路”,可以让梯度更好地向前流动;同时又加入一个类似LSTM中门的机制,自动学习这些高速公路的开关和流量。Highway Networks和Residual Networks、Dense Networks都是想拉近深度网络中本来相隔很远的层与层之间的距离,使很深的网络也可以比较容易地学习。

3.模型中还使用了Batch Normalization(继ReLU之后大家公认的DL训练技巧),Residual Connection(减少梯度的传播距离),Stride=1的Max-pooling(保证Conv的局部不变性和时间维度的粒度)以及一个时髦的BiGRU。Tacotron: Towards End-to-End Speech Synthesis这篇文章发表在2017年4月,最潮的DL技术用到了很多。

项目基于深度学习的中文语音识别系统中language_model/文件夹中已经默认放置了例子语料,可以通过直接运行CBHG.py进行数据预处理、模型训练、和模型测试,下面是我用项目中的默认数据在12G GPU上训练了大概小半天的模型识别结果,如果利用网络爬虫增加数据集,将会有更好的泛化结果。

请输入测试拼音:ta1 mei2 you3 duo1 shao3 hao2 yan2 zhuang4 yu3 dan4 ta1 que4 ba3 ai4 qin1 ren2 ai4 jia1 ting2 ai4 zu3 guo2 ai4 jun1 dui4 wan2 mei3 de tong3 yi1 le qi3 lai2
她没有多少豪言壮语但她却把爱亲人爱家庭爱祖国爱军队完美地统一了起来请输入测试拼音:chu2 cai2 zheng4 bo1 gei3 liang3 qian1 san1 bai3 wan4 yuan2 jiao4 yu4 zi1 jin1 wai4 hai2 bo1 chu1 zhuan1 kuan3 si4 qian1 wu3 bai3 qi1 shi2 wan4 yuan2 xin1 jian4 zhong1 xiao3 xue2
除财政拨给两千三百万元教太资金外还拨出专款四千五百七十万元新建中小学请输入测试拼音:ke3 shi4 chang2 chang2 you3 ren2 gao4 su4 yao2 xian1 sheng1 shuo1 kan4 jian4 er4 xiao3 jie3 zai4 ka1 fei1 guan3 li3 he2 wang2 jun4 ye4 wo4 zhe shou3 yi1 zuo4 zuo4 shang4 ji3 ge4 zhong1 tou2
可是常常有人告诉姚先生说看见二小姐在咖啡馆里和王俊业握着族一坐坐上几个钟头

数据集

数据集采用了目前我能找到的所有中文免费数据,包括:thchs-30、aishell、primewords、st-cmd四个数据集,训练集总计大约450个小时,在实验过程中,使用thchs-30+aishell+st-cmd数据集对DFCNN声学模型进行训练,以64batch_size训练。

  • 数据集
    • 共计约430小时,相关链接:http://www.openslr.org/resources.php
    • st-cmd、primewords、Aishell、thchs30四个数据集,整理为相同格式,放于some_expriment\data_process\datalist中。包含了解压后数据的路径,以及训练所需的数据标注格式,其中prime数据没有区分训练集等,为我手工区分。各个数据集的数量(句)如下:

      Nametraindevtest
      aishell120098143267176
      primewords4078350465073
      thchs-30100008932495
      st-cmd100006002000

这是目前能找到的所有开源中文语料,如果还有希望大神能够留言提示。

转载请注明出处:https://www.cnblogs.com/sunhongwen/p/9613674.html

转载于:https://www.cnblogs.com/sunhongwen/p/9613674.html

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

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

相关文章

jSignature签名的用法,一文教会你(一)前端代码

jSignature签名的用法1、先看看效果以后最后它是什么格式的2、先去下载该js3、下载以后就把它引入我们的HTML中4、看一下我的例子吧!下期我们在讲,怎么把base64在后台处理,然后在存进我们指定的位置,以及怎么存数据库;…

jSignature签名的用法,一文教会你(二)后台代码

1、先在我们的项目里加几个工具类,代码如下 AbstractUploadAction (名字可以自取,这个不影响) import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.OutputStream;import javax.s…

HTML5 多图片上传(前端+后台详解)

HTML5 多图片上传(前端后台详解)1、参考jquery插件库2、修改代码3、添加的后台代码4、删除的后台代码1、参考jquery插件库 手机端实现多图片上传 2、修改代码 我发现他这里的代码仅仅只是显示出来了,对后台一点作用都没有,于是…

vue2.0移动端自定义性别选择提示框

这篇文章主要是简单的实现了vue2.0移动端自定义性别选择的功能&#xff0c;很简单但是经常用到&#xff0c;于是写了一个小小的demo&#xff0c;记录下来。 效果图&#xff1a; 图片.png实现代码&#xff1a; <template><div class"app"><div class&q…

微信小程序入门的一些建议,替大家踩坑

小程序入门教程1&#xff0c; 建议先去看官方文档2&#xff0c;说说app.json这个文件3、app.js4、点击事件5、跳转页面最后要说一下我踩的一个大坑&#xff0c;样式问题1&#xff0c; 建议先去看官方文档 微信小程序官方文档 官方文档里有下载微信开发者工具的地址&#xff0c…

云服务器Linux安装,配置,使用nginx

云服务器Linux安装&#xff0c;配置&#xff0c;使用nginxlinux安装nginxnginx的使用linux安装nginx 检查是否安装了GCC&#xff08;可在任何目录下输入&#xff09; yum list installed | grep "gcc"如果像下图一样&#xff0c;就说明安装了&#xff0c;反之没安装…

原来文化设计可以这样玩!

设计是什么&#xff1f;设计是一种以科学的方法去高效解决问题的办法&#xff0c;为之设计。例如一个灯&#xff0c;是为了照明&#xff0c;如果改良的灯&#xff0c;肯定是为了高效或者节能地解决照明这个需求&#xff0c;没毛病吧&#xff1f; 那么中秋的花灯是什么&#xff…

Windows安装python,以及python的集成开发环境Pycharm

安装python&#xff0c;以及python的集成开发环境Pycharm1&#xff0c;安装python&#xff08;Windows&#xff09;2&#xff0c;安装python的集成开发环境1&#xff0c;安装python&#xff08;Windows&#xff09; 进入python官网 点击图中标识出来的这个&#xff0c;是个ex…

Python 最难的问题

Python 最难的问题 超过十年以上&#xff0c;没有比解释器全局锁&#xff08;GIL&#xff09;让Python新手和专家更有挫折感或者更有好奇心。 未解决的问题 随处都是问题。难度大、耗时多肯定是其中一个问题。仅仅是尝试解决这个问题就会让人惊讶。之前是整个社区的尝试&#x…

解决echart中:Cannot read property ‘queryComponents‘ of undefined

在使用案例的echart的日历图表的时候&#xff0c;遇到了&#xff1a; Uncaught TypeError: Cannot read property ‘queryComponents’ of undefined 思考了很久&#xff0c;还百度了&#xff0c;结果还是不好使&#xff0c;最后终于被我在一个问答了找到了答案。 刚开始我是…

ListT.Find用法学习

泛型集合List<T>中的Find函数用于查找集合中符合指定条件的元素..相比foreach遍历元素&#xff0c;用Find函数查找&#xff0c;代码更简洁. 函数原型如下&#xff1a; public T Find(Predicate<T> match); 其中Predicate为C#定义好的委托&#xff0c;原型如下&…

从零开始的全栈工程师——html篇1.6

浮动与伪类选择器 一、浮动(float) 1.标准文档流 标准文档流是一种默认的状态 浏览器的排版是根据元素的特征&#xff08;块和行级&#xff09; 从上往下 从左往右排版 这就是标准文档流 2.浮动(float)float:left/right; 因为标准文档流会使页面的状态固定 元素会自动从左往…

idea+springboot+mongodb的简单测试使用分享

1&#xff0c;先去官网下载&#xff0c;选择版本&#xff0c;选择Windows&#xff0c;就可以点击下载了。 2&#xff0c;安装mongodb。 下一步安装 “install mongoDB compass” 不勾选&#xff08;当然你也可以选择安装它&#xff0c;可能需要更久的安装时间&#xff09;&a…

project01

the question 最早时间出发为第一架航班&#xff0c;接下来第二架要求&#xff1a;到达日期与第一架航班的出发日期的时间间隔不小于45分钟&#xff0c;且序号最小依次类推将所有航班排完the data the transmission of the data import numpy as np import pandas as pd from p…

idea+springboot+mongodb的实战使用分享

昨天的时候我们先在网上找了测试类&#xff0c;测试了一下mongdb的简单使用&#xff0c;今天就来实地在项目中用一用 没安装mongodb的参考我上一篇文章&#xff1a;ideaspringbootmongodb的简单测试使用分享 其实我们初学者最好是安装一个可视化的工具&#xff0c;这样方便我…

Nginx整合tomcat,实现反向代理和负载均衡

1.Nginx与Tomcat整合,通过Nginx反向代理Tomcat。 Nginx安装路径为&#xff1a;/usr/local//nginx 首先切换路径到&#xff1a;/usr/local//nginx/conf通过命令 vim/usr/local//nginx/conf/nginx.conf打开配置文件 修改Nginx配置文件&#xff1a;/usr/local//nginx/conf/nginx.…

ElasticSearch Java SpringBoot根据时间范围分组求和

需求是这样的&#xff1a; 近7天的用户登陆统计&#xff0c;根据日期来返回的要是data:[{date&#xff1a;“2021-04-01”,count:“1”}] Autowired private ElasticsearchTemplate elasticsearchTemplate;SimpleDateFormat formater new SimpleDateFormat("yyyy-MM-dd&…

开发springboot项目,遇到的一些问题总结

首先看一下我的项目目录吧 1&#xff0c;添加拦截器 我们做项目肯定要用到拦截器这个功能哈&#xff0c;没登录的话一些页面我们是不能访问的哈&#xff0c;这里是用到了HandlerInterceptor。 分别在图中的位置创建2个目录和2个文件&#xff1a; WebConfig: import org.sp…

centOS下lnamp安装

首先安装apache,mysql ,最后安装php 1>apache安装 安装&#xff1a;yum install -y httpd 运行&#xff1a;/bin/systemctl start httpd.service 执行完运行命令之后是看不到效果的&#xff0c;这时候再输入查看apache服务状态命令来查看服务是否已经启动&#xff1a; 查看状…

java使用itext填充pdf模板,超简单教学,有手就行

java使用itext填充pdf模板1、先去建一个Word文件&#xff0c;设置好想要填充的地方&#xff0c;留好位置&#xff0c;设置好下划线2、将Word另存为pdf3、打开电脑中的Adobe Acrobat pro DC&#xff08;这个应该win10 都有&#xff0c;搜索一下就出来了&#xff09;&#xff0c;…