当前位置: 首页 > 工具软件 > CMU Sphinx > 使用案例 >

一次尝试使用cmu sphinx做语音识别的失败记录

傅朝
2023-12-01

好好的C++不去写,为啥想起来搞什么语音识别?事情是这样的,我经常躺在床上听歌,使用电脑连音响播放,因为我比较懒,切歌啥的都直接召唤小娜帮我做,可以节省体力。然而小娜笨啊,除了能切歌啥也干不了,我要是听到一首好听的,还得爬起来去收藏,这多么麻烦是不是?小娜也没开放啥接口可以自定义命令,就想自己写一个程序,识别到我的指令后,按照播放器的快捷键虚拟键盘按键事件。
网上一搜“开源语音识别引擎”,好,就是你了:cmu sphinx。然而结果是惨淡的,周末两天的工作成果并没能使我轻松一点。我的“小小红”虽然能听懂更多我需要的指令,然而只有在我不播放音乐时才听得懂,环境噪声稍大就不听话了。相比之下小娜就可靠多了,即使开着音乐也能听懂我的指令。虽然失败了,但也做个记录吧,当然是以一个语音识别门外汉的视角做的记录,是自己的理解,不见得准确。

  1. 因为是在windows下播放音乐,所以直接下载了cmu sphinx的win32版源码,自带VS工程文件。
  2. 要想在win10上正常运行自带的continuous样例,需要把sphinxbase和pocketsphinx都编译成release版,同时把运行库编译参数指定为:多线程DLL(/MD)。
  3. 要注意中文编码问题,语言模型文件和字典文件编码要相同,我都设置成了GB2312,可以避免终端输出乱码。
  4. 需要使用3种模型文件,具体可见https://cmusphinx.github.io/wiki/tutorialconcepts/,声音模型用来把声音输入映射到定义好的音素,语言模型定义了所有可能的输出(即词的组合),字典用来把语言模型中的词映射到音素,字典不影响识别准确率(这一点见https://cmusphinx.github.io/wiki/tutorialdict/)。
  5. 使用cmu sphinx提供的默认普通话声音模型和语言模型,识别准确率相当感人,完全用不了。
  6. 将语言模型限定为我定义的指令,识别准确率就上来了(当然是安静情况下),这一度令我很高兴,然而后来发现“下一首”在90%以上情况被识别为“上一首”
  7. 按照https://cmusphinx.github.io/wiki/tutorialadapt/的方法,使用我的语音做适配后,“上一首”和“下一首”就分得清了,这里是一个脚本:
sphinx_fe -argfile .\zh_broadcastnews_ptm256_8000\feat.params -samprate 16000 -c .\arctic20.fileids -di . -do . -ei wav -eo mfc -mswav yes
bw -hmmdir .\zh_broadcastnews_ptm256_8000 -moddeffn .\zh_broadcastnews_ptm256_8000\mdef -ts2cbfn .ptm. -feat s2_4x -cmn current -agc none -dictfn self.dic -ctlfn .\arctic20.fileids -lsnfn .\arctic20.transcription -accumdir .
mllr_solve.exe -meanfn .\zh_broadcastnews_ptm256_8000\means -varfn .\zh_broadcastnews_ptm256_8000\variances -outmllrfn mllr_matrix -accumdir .
map_adapt.exe -moddeffn .\zh_broadcastnews_ptm256_8000\mdef -ts2cbfn .ptm. -meanfn .\zh_broadcastnews_ptm256_8000\means -varfn .\zh_broadcastnews_ptm256_8000\variances -mixwfn .\zh_broadcastnews_ptm256_8000\mixture_weights -tmatfn .\zh_broadcastnews_ptm256_8000\transition_matrices -accumdir . -mapmeanfn .\zh_ptm_adapt\means -mapvarfn .\zh_ptm_adapt\variances -mapmixwfn .\zh_ptm_adapt\mixture_weights -maptmatfn .\zh_ptm_adapt\transition_matrices
  1. 识别时很容易受到噪声影响,该开始识别时不开始,该结束识别时不结束(在recognize_from_microphone函数中的utt_started in_speech记录一段语音识别的开始和结束。
  2. 通过设置vad_threshold能一定程度改善问题8,尤其是在安静情况下,能让识别率上升到90%以上,打开音乐时也有一定改善。
  3. 一旦打开音乐,问题8再次出现,使用9中的方法很难把握阈值,最终没有很大的改善。
  4. 刚打开程序时,或者一段时间没说指令时,初次说出的两三个指令几乎没被识别对过,后面的才能识别,原因未知。这个让我想不通,使用in_speech标识的每次识别过程难道不是独立的吗?
 类似资料: