分享

机器人之语音识别(15) | DEHAOz

 icecity1306 2017-05-20
  • 1、语音处理

语音处理包括两部分:(1) 一块是语音识别SR:Speech Recognition,也称为自动语音识别ASR:Automatic Speech Recognition;(2) 另一块是语音合成SS:Speech Synthesis,也称为TTS:Text-To-Speech。
语音处理目前多为基于语音识别芯片的嵌入实现,也有靠软件实现的例如商用的IBM的Viavoice和MS的SAPI以及开源的Sphinx和Julius等,都是些面向非特定人的大词汇量的连续语音识别系统。

  • 2、语音识别

语音识别,属于模式识别的一种应用,将未知的输入语音的模式和已知语音库里的参考模式逐一比较,所获得的最佳匹配的参考模式即为识别出来的结果。
语音识别目前大多是基于统计模式的,主流算法有基于参数模型的隐式马尔可夫模型HMM方法、基于人工神经网络ANN和支持向量机SVN的识别方法等。

  • 3、识别模型

(1)根据语音的机理,语音识别大框架可以分为语音层和语言层两个层级,可以理解为语音层 即子音母音或者叫声母韵母,而语言层则是sequence of words。(2) 根据功能,连续语音识别系统,主要分为特征提取,声学模型训练,语言模型训练、解码器和搜索算法四大块。

更琐碎的分为:
1、预处理。滤除次要信息和背景噪声,对语音信号作端点检测从而找出语音始末位置,假设在10-30ms内语音是平稳的从而将语音分帧。
2、特征提取。背景过滤,保留能够反映语音本质特征的信息,取出反映语音信号特征的关键参数形成特征向量序列,获得特征向量后由此特征向量通过计算余弦值可以初步获得被选的单词文本。
特征提取方法都是频谱衍生的,sphinx是用Mel频率倒谱系数MFCC。首先用FFT将时域信号转化成频域,之后对它的对数能量谱依照Mel刻度分布的三角滤波器组进行卷积,最后对各滤波器输出所构成的向量进行离散余弦变换DCT,取其前N个系数。sphinx用大概10ms的帧frames去分割语音波形,然后对每帧提取可以代表该帧语音的39个数字,这39个数字就是该帧语音的MFCC特征,即特征向量。
3、字典,用于选练声学模型。
4a、声学模型,通常是隐式马尔科夫模型,从而由声音特征可以获得音素单元。
4b、声学模型训练,由训练语音库的特征参数训练出声学模型参数。语音识别时将待识别的语音的特征参数同声学模型进行匹配得到识别结果。目前语音识别系统多用隐式马尔可夫模型HMM进行声学模型建模。HMM模型的建模单元,可以是音素,音节,词等各个层次。对于小词汇量的语音识别系统,可以用音节进行建模。对于词汇量大的识别系统,一般选取音素即声母/韵母进行建模。识别规模越大识别单元选取的越小。HMM是对语音信号的时间序列结构建立统计模型,将其看作一个数学上的双重随机过程:一个是用具有有限状态数的Markov链来模拟语音信号统计特性变化的隐含(马尔可夫模型的内部状态外界不可见)的随机过程,另一个是与Markov链的每一个状态相关联的外界可见的观测序列(通常就是从各个帧计算而得的声学特征)的随机过程语音识别中使用HMM,通常是用从左向右单向、带自环、带跨越的拓扑结构来对识别基元建模,一个音素就是一个三至五种状态的HMM,一个词就是构成词的多个音素的HMM串行起来构成的HMM,而连续语音识别的整个模型就是词和静音组合起来的HMM。

5a、语言模型,训练文本序列,除了包括前述字典,还有额外材料。
5b、语言模型训练,语言模型是用来计算一个句子出现概率的概率模型。它主要用于决定哪个词序列的可能性更大,或者在出现了几个词的情况下预测下一个即将出现的词语的内容。换个说法即语言模型是用来约束单词搜索的。语言模型分为字典知识、语法知识、句法知识三个层次,Sphinx中是采用二元语法和三元语法的统计语言概率模型,也就是通过前一个或两个单词来判定当前单词出现的概率P(w2| w1),P(w3| w2, w1)。
6、解码和搜索算法,通过语言模型和字典,给出概率可能的结果。
解码即指语音技术中的识别过程。根据己经训练好的HMM声学模型、语言模型及字典建立一个识别网络,根据搜索算法在该网络中寻找最佳的一条路径,这个路径就是能够以最大概率输出该语音信号的词串。所以解码操作即指搜索算法:是指在解码端通过搜索技术寻找最优词串的方法。为在搜索中利用各种知识源,通常要进行多遍搜索,第一遍使用代价低的知识源(如声学模型、语言模型和音标词典),产生一个候选列表或词候选网格,在此基础上进行使用代价高的知识源(如4阶或5阶的N-Gram、4阶或更高的上下文相关模型)的第二遍搜索得到最佳路径。

4、sphinx

Sphinx产生于卡内基梅隆大学CMU,最早由李开复Kai-Fu Lee开发于1987年,是一个大词汇非特定人连续语音识别系统。pocketSphinx是Sphinx的桌面版,词汇量中等计算量较小。
组成包括以下:
1、Sphinxbase — Pocketsphinx所需要的支持库,主要完成的是语音信号的特征提取;
2、Pocketsphinx —用C语言编写的轻量级识别库,主要是进行识别的。
3、Sphinx3 — 为语音识别研究用C语言编写的解码器
3、Sphinxtrain —声学模型训练工具
4、CMUclmtk —语言模型训练工具

  • 5、Linux应用

1、安装需要的pocketsphinx包
$ sudo apt-get install pocketsphinx-hmm-wsj1 #install HMM of Pocket Sphinx
$ sudo apt-get install pocketsphinx-lm-wsj #install LM of Pocket Sphinx
$ sudo apt-get install python-pocketsphinx #install the Python extension of Pocket Sphinx
2、验证能够跑得起来
$ pocketsphinx_continuous
READY....
出现ready安装成功
3、文件说明
(1)安装后,模型位于/usr/share/pocketsphinx/model文件夹,里面hmm表示隐马尔可夫声学模型,lm表示language model语言模型。
(2)语言模型,lm/en_US文件夹,包括cmu07a.dic和hub4.5000.DMP。
(3)声学模型,hmm/en_US/hub4wsj_sc_8k文件夹,包括:feat.params/mdef/means/noisedict/sendump/transition_matrices/variances
4、再用默认的模型测试下
$ pocketsphinx_continuous -hmm /usr/share/pocketsphinx/model/hmm/en_US/hub4wsj_sc_8k -lm /usr/share/pocketsphinx/model/lm/en_US/hub4.5000.DMP -dict/usr/share/pocketsphinx/model/lm/en_UScmu07a.dic
$ pocketsphinx_continuous -lm  ~/catkin_ws/src/rbx1/rbx1_speech/config/nav_commands.lm  -dict ~/catkin_ws/src/rbx1/rbx1_speech/config/nav_commands.dic

5、怎样建立英文的语言模型
(1)建立语料库,vi corpus.txt
(2)利用在线工具LMTool建立语言模型,http://www.speech.cs./tools/lmtool.html,COMPILE KNOWLEDGE BASE。
(3)把得到的文件解压,即可得到.dic和.lm文件。
$ tar xzf ***.tar.gz
测试:
$ pocketsphinx_continuous -hmm /usr/share/pocketsphinx/model/hmm/en_US/hub4wsj_sc_8k -lm /usr/share/pocketsphinx/model/lm/en_US/hub4.5000.DMP -dict /usr/share/pocketsphinx/model/lm/en_UScmu07a.dic
英文的识别,尚好,还可以。

6、如何建立中文普通话的语言模型
官网上:声学模型,是zh_broadcastnews_16k_ptm256_8000.tar.bz2;语言模型,是zh_broadcastnews_64000_utf8.DMP;字典文件,是zh_broadcastnews_utf8.dic。
如果自安装:pocketsphinx-0.7/model/hmm/zh/tdt_sc_8k目录下是中文声学模型,pocketsphinx-0.7/model/lm/zh_CN目录下是中文语言模型,
(1)下载中文普通话语言模型MandarinLanguageModel:zh_broadcastnews_utf8.dic和zh_broadcastnews_64000_utf8.DMP。
(2)下载中文普通话新闻播音声学模型MandarinBroadcastNewsAcousticModels:zh_broadcastnews_16k_ptm256_8000文件夹
(3)解压缩
$ tar xjf zh_broadcastnews_16k_ptm256_8000.tar.bz2
(4)得到的声学模型包括以下:feat.params/mdef/means/noisedict/sendump/transition_matrices/mixture_weights/variances
(3)测试,
$ pocketsphinx_continuous -hmm ~/zdhSpeech2/zh_broadcastnews_ptm256_8000 -lm ~/zdhSpeech2/zh_broadcastnews_64000_utf8.DMP -dict ~/zdhSpeech2/zh_broadcastnews_utf8.dic
中文的是被效果,不咋的,估计还是得训练模型。

7、语言模型的训练
(0)准备语料库,产生词汇表,每个utterances由 <s> 和 </s>分隔,结尾不留“\n”。
#vi weather.txt
(1)命令text2wfreq:统计文本文件中每个词出现的次数,得到后缀为wfreq的文件。命令wfreq2vocab:统计文本文件中含有多少个词,即有哪些词。
# text2wfreq < weather.txt | wfreq2vocab > weather.tmp.vocab
(2)text2idngram:列举文本中出现的每一个n元语法。产生一个二进制文件,含有一个n元数组的数值排序列表,对应于与词有关的的N-Gram。
# text2idngram -vocab weather.vocab  -idngram weather.idngram < weather.closed.txt
(3)idngram2lm:输入文件包括一个idngram文件,一个vocab文件和一个ccs文件,输出是一个后缀为binlm的语言模型文件。其中ccs文件指句首和句尾的静音<s>和</s>
#idngram2lm -vocab_type 0 -idngram weather.idngram -vocab weather.vocab -arpa weather.arpa
(4)命令binlm2arpa:是将binlm文件转换为实验中需要的arpa格式语言模型文件。
(5)#sphinx_lm_convert -i weather.arpa -o weather.lm.DMP
如果语言模型比较大,最好就转换为CMU的二进制格式 (DMP),这样可以加快加载语言模型的速度,减少解码器初始化的时间。但小模型来说就这个必要,因为sphinx3能处理这两种后缀名的语言模型文件。
(6)这样最终生成了语言模型weather.lm.DMP,此文件为解码器端所需要的文件格式
8、声音模型的改进
(1)创建语料库,共需要四个文件:
arctic20.txt,文本文件:里面是中文的句子
arctic20.fileids,控制文件:记录语音文件(读arctic20.txt里面的句子的录音)的路径
arctic20.transcription,脚本文件:中文句子和语音文件的对应关系
arctic20.dic,字典文件:记录arctic20.txt里面的句子因素的音标组成
(2)声音录制:
$ sudo apt-get install sox
$ vi rec_wav.sh
$ for i in `seq 1 12`; do
fn=`printf arctic_%04d $i`;
read sent; echo $sent;
rec -r 16000 -e signed-integer -b 16 -c 1 $fn.wav 2>/dev/null;
done < arctic20.txt
$ chmod 777 rec_wav.sh
这个脚本会显示一句话然后进入录音,把这个句子读出来然后按ctrl+c显示下一句话然后录音,如此循环。
测试下,逐个播放:
for i in *.wav; do play $i; done
(3)适应声学模型
首先拷贝默认的pocketsphinx自带的中文声学模型到当前目录下
$ cp -a /usr/local/share/pocketsphinx/model/hmm/zh/tdt_sc_8k/ .
对录制的wav语音文件提取MFCC特征,而且须用和默认的模型相同的声学模型参数去提取这些特征,他们存储在声学模型目录的feat.params文件中。
$ sphinx_fe -argfile tdt_sc_8k/feat.params -samprate 16000 -c arctic20.fileids -di . -do . -ei wav -eo mfc -mswav yes
这样在当前文件夹下就会对每一个语音文件生成一个*.mfc后缀的特征文件,可能将其修改为*..mfc

  • 9、(离线识别英文)的Python脚本

这个识别.wav文件的语音,不需要安装流框架
#!/usr/bin/env python
import sys
#In Ubuntu 14.04.2, the pocketsphinx module error first import and ok the second import.
#The following code is a temporary fix
try:
import pocketsphinx
except:
import pocketsphinx
if __name__ == "__main__":
hmdir = "/usr/share/pocketsphinx/model/hmm/en_US/hub4wsj_sc_8k"
lmdir = "/usr/share/pocketsphinx/model/lm/en_US/hub4.5000. DMP"
dictd = "/usr/share/pocketsphinx/model/lm/en_US/cmu07a.dic"

wavfile = sys.argv[1]
speechRec = pocketsphinx.Decoder( hmm = hmdir, lm = lmdir, dict = dictd)
wavFile = file( wavfile,'rb')
speechRec.decode_raw( wavFile)
result = speechRec.get_hyp()
print "\n\n\nDetected text:>", result

  • 10、安装GStreamer framework语音包

$ sudo apt-get install gstreamer0.10-pocketsphinx
# 如果有问题,需要安装这个plugin使得获取GConf信息
$ sudo apt-get install gstreamer0.10-gconf
安装GStreamer Python binding从而python可以使用GStreamer APIs
$ sudo apt-get install python-gst0.10

  • 11、(在线识别英文)的Python脚本

#!/usr/bin/env python
import gobject
import sys
import pygst
# above should before gstreamer

pygst.require('0.10')
gobject.threads_init()
import gst

#mode to handle kbd interuption
import signal

def signal_handle( signal, frame):
print "Ctrl+C pressed"
sys.exit( 0)

#Implementation of Speech recognition class
class Speech_Recog( object):

#Initializing gstreamer pipeline and pocket sphinx element
def __init__(self):
self.init_gst()
#The following code create a gstreamer pipeline with pipeline description.
#The required descriptors needed for the code is given as parameters.
def init_gst(self):
self.pipeline = gst.parse_launch('gconfaudiosrc ! audioconvert ! audioresample ' + '! vader name = vad auto-threshold = true ' + '! pocketsphinx

name = asr ! fakesink')
#Accessing pocket sphinx element from gstreamer pipeline
asr = self.pipeline.get_by_name('asr')
#Connecting to asr_result function when a speech to text conversion is completed
asr.connect('result', self.asr_result)
#User can mention lm and dict for accurate detection
#asr.set_property('lm', '/home/user/mylanguagemodel.lm')
#This option will set all options configured well and can start recognition
asr.set_property('configured', True)
#Pausing the GStreamer pipeline at first.
self.pipeline.set_state( gst.STATE_PAUSED)

#Definition of asr_result
def asr_result( self, asr, text, uttid):
#Printing the detected text
print "Detected Text =>", text
#This function will start/ stop Speech recognition operation
def start_recognition( self):
vader = self.pipeline.get_by_name('vad')
vader.set_property('silent', False)
#Waiting for a key press to start recognition
raw_input("Press any key to start recognition:>")
#Start playing the pipeline
self.pipeline.set_state( gst.STATE_PLAYING)
#Waiting for stopping the recognition
raw_input("Press any key to stop recognition: >")
vader = self.pipeline.get_by_name('vad')
#Setting silent property of VADER to True
vader.set_property('silent', True)
#Pausing GStreamer pipeline
self.pipeline.set_state(gst.STATE_PAUSED)

if __name__ == "__main__":
app_object = Speech_Recog()
signal.signal( signal.SIGINT, signal_handle)
while True:
app_object.start_recognition()

  • 12、ROS的node

1、安装ROS的pocketSphinx包
$ cd ~/catkin_ws
$ git clone https://github.com/mikeferguson/pocketsphinx
$ catkin_make
2、后面这两个可能需要
$ sudo apt-get install ros-indigo-audio-common
$ sudo apt-get install ros-indigo-pocketsphinx
2、测试
运行robocup节点
$ roslaunch pocketsphinx robocup.launch
订阅主题,查看识别结果
$ rostopic echo /recognizer/output
例如
j

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多