冯 君
(滨州学院,山东 滨州 256603)
如今手机已成为人们日常生活中不可或缺的一部分,智能手机提供给用户与之进行交互的多种方式,但最自然的交互方式仍然是语音。智能手机市场提供了许多关于语音识别的应用。本文基于科大讯飞语音识别引擎实现了一款语音识别应用VoiceMessage。应用的主要目标是允许用户输入语音信息并将信息转换为期望的文本信息,从而使得用户可以不用打字就可以快速地得到文本信息,大大节省了时间。
现代语音识别技术主要采用模式识别的基本流程,如图1所示:
图1 语音识别流程
首先准备要训练的训练数据集,然后提取数据的特征并且利用数据的这些特征进行模型的训练,最后根据训练好的模型进行测试应用。
在模型训练好了之后,对待测的语音信号进行信号处理,从中提取出有利于识别的信息,也就是特征提取。随后,以音频信号为输入形式,进行语音增强处理,消除噪音,反映语音的本质,完成语音信号从时域到频域的转化,并将特征提取给声学模型,生成声学模型得分,用语言模型决定序列的可能性,也即语言模型得分。解码器计算这两个得分,识别结果就是输出分数最高的词序列,如图2所示。
图2 识别结果计算流程
用公式表示如下:
其中W表示识别的文本序列,X表示语音数据,基于给定的X,语音识别求得最大后验概率的文本序列,利用贝叶斯公式将此文本序列的后验概率展开为两部分,一是先验概率,另一个是似然概率,然后对这两部分进行建模,得出语言模型和声学模型,再在搜索空间Ω中,通过其得分,求取概率最大的文本序列。
从物理意义来理解语言模型就是体现字或词出现的先验概率,从各种候选词顺序、词的语义信息状态序列中,判断哪一个比较合理。
传统语言模型采用N-gram方式:
语言模型实际是对文本序列的先验概率进行建模,一个词出现的概率与第一个词后,第二个词出现的概率相乘,依此类推。
基于N-阶马尔科夫假设的全概率空间:就是每个词出现的概率只关联到最近的N个历史词。那么公式2中的每一项就可以做如下近似:
则有:
声学模型的建模也即对似然概率部分的建模,即给定文本序列之后生成对应语音的概率,是整个语音识别中最核心的部分,也是最复杂的部分。某些训练数据由于具有共性,可共享给不同的建模单元,为了避免这个问题,需要转换文本序列成为对应的发音序列,由于发音的不定长特性,就需要引入HMM模型,将每一个语音帧都对应于HMM模型的每一个状态,如此无论多长的语音帧都能表达为HMM模型中的一个状态序列,最后只要将每一个状态与语音序列中的每一帧进行一一对应,再将对应关系以一定的概率来表达。由于语音是非常复杂多变的,不同说话人在说同样句子时会表现出非常大的差异性,而在不同的环境噪声的情况下,这样的语音也是表现出非常多的复杂性,因此最后特征状态序列到语音的建模通常会采用比较复杂的概率模型来实现。在1980年左右采用GMM-HMM即高斯混合模型的方式来表达概率分布,由于当时的计算条件,数据量都不是很大,所以GMM是较好的方案,它能够有效的在数据量较少的情况下进行声学模型的训练。在2010左右,出现了新的替代方案DNN-HMM,DNN也是经历了几个阶段的发展,首先是前馈神经网络,后来发现其对时序的表达并不是很好,所以后来又提出了递归神经网络,它将前后时刻的神经网络的状态进行了连接,从而使得在每一时刻都能看到非常长的上下文的知识,从而提高了概率模型的表达能力,为了更高的稳定性,后来又提出了卷积神经网络做声学模型,卷积神经网络能够看到长时以来的同时,又通过空间结构逐层递进的关系使得声学模型会更加的稳定,也是逐渐成为现代最杰出的声学模型结构。
语音识别通常是采用动态规划算法来进行识别的,在语音识别具体的应用中,采用的是Viterbi搜索的方法,语音识别问题就是变相求解最优路径。对于求出全部中间路径节点的Viterbi的值,其计算公式为:
有了该值之后,就可以从路径的最后一个节点开始往前不断的回溯找到最优路径。
首先,使用Androidstudio创建一个新项目,切换到project视图。将下载的Android_iat1140_5ea3dfe2(后面的编号和APPID是一致的)中libs目录中的Msc.jar包复制到新建项目的libs目录下,并且右键jar选择 Add As Library。
然后,右键点击main,依次选择new->Directory,建立一个名为jniLibs的目录,将下载好的SDK中的libs目录下剩下的文件全部复制到jniLibs目录中。
接着,集成资源文件,右键点击main,依次选择new->Directory,建立 assets 目录,然后将 Android_iat1140_5ea3dfe2下assets下的所有文件复制到刚刚创建的assets目录中。
注意要在AndroidManifest.xml文件中添加如下访问权限,如图3所示。
图3 需要添加的网络访问权限
初始化即创建语音配置对象,只有初始化后才可以使用MSC的各项服务。建议将初始化放在程序入口处 (如 Application、Activity的 onCreate方法),初始化代码如下:
SpeechUtility.createUtility (context,SpeechConstant.APPID+"=5ea3dfe2");
UI设计如图4所示,最外层采用相对布局RelativeLayout,内嵌两个水平方向的线性布局Linear-Layout,利用属性android:weight实现屏幕适配。
在VoiceMessageActivity类中封装initSpeech方法,核心代码如下:
图4 UI布局
识别的结果是以JSON格式返回的,如语音输入“今天天气很好”,返回的JSON数据为:
{"sn":1,"ls":false,"bg":0,"ed":0,"ws":[{"bg":80,"cw":[{"sc":0.0,"w":"今天"}]},{"bg":140,"cw":[{"sc":0.0,"w":"天气"}]},{"bg":188,"cw":[{"sc":0.0,"w":"很好"}]}]}
{"sn":2,"ls":true,"bg":0,"ed":0,"ws": [{"bg":0,"cw":[{"sc":0.0,"w":"。"}]}]}
可以使用在线JSON查看器如https://www.sojson.com/editor.html查看格式化之后的数据。
各个JSON字段的含义如表1所示。
表1 JSON字段说明
首先,使用gson技术对返回的JSON格式的数据进行解析,选择File-Project Structure-Dependencies,搜索 gson,添加 gson 包。
然后,封装Sound类,代码如下“
最后,封装解析数据的方法parseSound,代码如下:
首先,在语音对应的ImageView组件中增加onClick属性,代码如下:
然后,在VoiceMessageActivity中定义voicetomessage方法
经测试,如果在 voicetomessage方法中直接调用initSpeech方法,每次运行应用程序时,都会引发SecurityException,调试器的错误如下:
java.lang.SecurityException:“gps”location provider requiresACCESS_COARSE_LOCATION orACCESS_FINE_LOCATIONpermission.
这是因为android6.0之后对一些危险权限必须运行时动态权限申请,所以在
VoiceMessageActivity中增加动态权限申请的方法checkVoice(),当用户点击语音识别图片时,首先弹出动态权限认证提示框,只有用户通过了相应的权限,才会弹出初始化语音对话框。
语音识别在移动设备中的集成使得智能手机的使用更加的便捷,使用这样的系统开启了无数的可能性。VoiceMessage应用将语音转化为文本信息给指定的联系人发送短消息,除了为移动设备的当前用户提供便利的操作之外,老年人和有各种残疾的人将有机会参与到科技活动中,感受到智能手机的好处。