2017-04-20 19:41:51 victoryaoyu 阅读数 1573
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    6094 人正在学习 去看看 杨波

本文主要对基于GMM/HMMs的传统语音识别系统做一个整体介绍。

Outline:

  1. 识别原理
  2. 统计学模型
  3. 系统框架

首先需要说明本文讨论的对象是连续语音识别(Continuous Speech Recognition, CSR),意味着基于DTW(动态时间规整)的孤立词识别(Isolated Word Recognition)不在讨论范围内(out-of-date)。同时,整篇围绕自动语音识别解码过程(识别过程)展开的讨论的。

1.识别原理

首先明白,我们的语音是一种声波,是模拟信号,一般在电脑中保存为wav文件(无压缩格式)或者可以直接通过麦克风采集获得(online)。

这里写图片描述

需先进行预处理与数字化操作:滤波降噪、预加重(提升高频)、端点检测、加窗分帧,把我们的一段语音信号分解为很多很多的小段语音片段(语音帧)。一般每帧长度为25ms,相邻两帧有10ms的重叠,也就是常说的帧长25ms,帧移10ms。
然后,我们再对每一帧做信号分析,来进一步压缩数据,也被称作特征提取,常见的特征参数有:MFCC,PLP。经过特征提取后,每帧由原来上百个记录点,压缩为39维的MFCC特征参数。(瞬间轻松了好多)

这里写图片描述

接下来,就是怎么把一系列特征参数序列转化为一段话的问题了?也就是声学模型(GMM-HMMs)、语言模型派上用场的时候到了。首先我们要知道一段话是由一串文字序列组成,一个文字由一串音素(phoneme)组成(如bal:/b/ /ɔː/ /l/)。通常在英文中我们选择音素来建立了隐马尔科夫模型(中文建模单元常为声韵母),即一个音素对应一个HMM,同时通常一个HMM由三个状态(state)组成。好的我们再反过来,我们现在手上有一个特征参数序列,识别的过程,就是解决怎么把每个特征参数识别为一个状态,再由状态到音素,音素到单词,单词到单词序列(一段话)?其中特征参数到状态,由GMMs(混合高斯模型)解决;三个状态到一个音素,由HMM解决;音素到单词,由词典解决;单词到单词序列,由语言模型解决。当然,在整个过程中,我们都是在一个状态网络(time-state)中进行的,都是基于HMMs的。这也是为什么说是HMMs解决了语音识别问题。

这里写图片描述

统计学模型

自动语音识别(Automatic Speech Recognition, ASR)的任务是将一个段声学信号映射为一串文字。(对其建模是我们实际去解决问题的第一步)即

W=argmaxWP(W|X)(1)

其中X=xTi=x1x2,,xt,,xT代表一段长度为T的声学信号(语音帧),W=wni=w1w2,,xn代表一段长度为n的单词序列(word sequence),W为在所有 中,最有可能的一段单词序列,也就是我们的识别结果了。
然而公式(1)很难直接计算得出(对于generative models)。我们进行Bayes变换:

P(W|X)=P(X|W)P(W)P(X)P(X|W)P(W)(2)

W=argmaxW(P(X|W)AMP(W)LM)(3)

最终得到公式(3),其中 代表了一个声学似然度,包含了字典、语音学和声学知识,通过声学模型计算得到; 表示单词序列的一个先验概率(Occam’s Razor),包含了语言学信息,可由语言模型获得。自此,我们知道语音识别问题可以利用声学模型和语言模型来解决。(不过在实际处理中,我们要对公式(3)作进一步细化)

系统架构

一个语音识别系统框架主要包括:声学分析(Signal Analysis)、声学模型(Acoustic Model)、辞典(Lexicon)、语言模型(Language Model)、搜索/解码(Search/Decoding)。原始语音经过信号分析后,结合声学模型、语言模型和辞典, 在搜索空间中找出一个最有可能的单词序列。

这里写图片描述

声学分析:也称特征提取(Feature Extraction)。
作用:降维,提取有用信息,比如将一段语音帧,解析为一个固定维数(39维)的特征向量。
常用:MFCC(Mel-frequency cepstral Coefficient)、PLP(Perceptual Linear Prediction)。

声学模型
作用:解析声学信号,比如将特征向量解析到一个特征的建模单元上,并获得相应的score,如音素,声韵母等等。
常用:GMM-HMM、hybrid ANN-HMMs、DNN-HMM、RNN-CTC。

辞典:
作用:给单词和发音提供HMM模型(亚词)和语言模型间关联。
通常:基于音素,由专家手工完成,如CMU-dict。

语言模型:
作用:提供P(W)这部分的先验概率,可以区分相同发音时的识别结果,如wreck a nice beach。
常用:n-gram。

搜索/解码:
作用:根据状态系列,在time-state Trellis中找到一个最优路径,或者说根据声学模型输出的结果,结合辞典、语言模型信息,找出最有可能的识别结果。
常用:Viterbi search、Beam search。

2012-03-26 11:17:23 huazaihepa 阅读数 354
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    6094 人正在学习 去看看 杨波

 最近语音识别很火,但是都是用的在线语音识别,研究了一下离线语音识别,小范围内的语音识别率还不错,在此记录一下

首先本文要说的两个前提1.android平台离线语音识别 2.小范围语音

小范围语音指的是相对固定的命令。本文的例子大概实现了20条语音命令,超出范围的无法识别。因此本文中离线语音的使用范围也有限,对于一些固定的输入可能有用,比如用语音命令代替打开,播放,重启这些简单的固定的命令。

先上个例子

1.按照 http://leiwuluan.iteye.com/blog/1287305 的方法,先跑一个PocketSphinxDemo的例子起来。跑起来之后会发现语音识别率很低,大概20%不到。下面来优化一下

2.编写自己的命令集

<s>百度</s>
<s>谷歌</s>
<s>音乐</s>
<s>抬头</s>
<s>低头</s>

保存为command.txt

http://www.speech.cs.cmu.edu/tools/lmtool.html上点Browse,提交command.txt,在线生成语言模型文件。这里只要生成的lm文件,命名为test.lm。从这里下载pocketsphinx-win32,解压后在/model/lm/zh_cn有个mandarin_notone.dic的文件,打开后,搜索command.txt里面的词,然后替换相应的内容,替换后的内容如下

 存为test.dic

3.替换语言模型文件。下载附件中的data.zip,解压后文件如下(之前附件中的data不可用,已更新)

分别放到一下目录

/sdcard/Android/data/test/hmm/tdt_sc_8k
/sdcard/Android/data/test/lm/test.dic
/sdcard/Android/data/test/lm/test.lm

如果要换目录的话,对应修改RecognizerTask.RecognizerTask()里的如下代码

  c.setString("-hmm", "/sdcard/Android/data/test/hmm/tdt_sc_8k");
  c.setString("-dict", "/sdcard/Android/data/test/lm/test.dic");
  c.setString("-lm", "/sdcard/Android/data/test/lm/test.lm");

lm和dic文件即3中生成的文件,tdt_sc_8k也可以从这里下载。

4.文件准备完毕,重新跑1中的demo。语音输入2中的命令,识别率99%以上,但是输入命令集以外的无法识别。



 

6.附件为工程文件,将data解压,按照3里面写的位置放到sd卡里面即可。以下字典内的词可以识别

 

 

2013-08-12 13:47:01 rhljiayou 阅读数 6992
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    6094 人正在学习 去看看 杨波

1、首先下载讯飞sdk及文档:http://open.voicecloud.cn/

2、学习里面的demo简单实现了一个小的语音识别功能

先做一个简单demo,看看识别效果。注:语音识别必须联网。

所有接口必需在联网状态下才能正常使用。

效果图:


#import <UIKit/UIKit.h>
#import "iflyMSC/IFlySpeechRecognizer.h"
#import "iflyMSC/IFlyDataUploader.h"

@protocol SpeechAlertViewDelegate <NSObject>
@optional
- (void)getResultText:(NSString *)text;
@end

@interface SpeechAlertView : UIAlertView<IFlySpeechRecognizerDelegate>
{
    UIImageView *speechImage;//声音图片
    
    IFlySpeechRecognizer * _iFlySpeechRecognizer;//语音识别对象
    UIView *backgroundView;
}
@property (assign, nonatomic)id<SpeechAlertViewDelegate> speechDelegate;
@end

#import "SpeechAlertView.h"
#define APPID @"51de5743"
#define TIMEOUT @"20000"
// timeout      连接超时的时间,以ms为单位,毫秒,符号ms ,1000 毫秒 = 1秒,30000=30秒
//timeout:网络超时时间,单位:ms,默认为20000,范围0-30000
@implementation SpeechAlertView

-(id)init
{
    self = [super initWithFrame:CGRectMake(0, 0, 300, 220)];
    if (self) {
        // Initialization code
    }
    return self;
}
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

//uialertview的大小位置
-(void)setFrame:(CGRect)frame{
    //重新设置弹出框的大小和位置    
    UIWindow *window =  [UIApplication sharedApplication].keyWindow;

    [super setFrame:CGRectMake((window.frame.size.width-self.frame.size.width)/2, (window.frame.size.height-self.frame.size.height)/2, self.frame.size.width, self.frame.size.height)];
}
//重新写界面内容
- (void) layoutSubviews {
    //屏蔽系统的ImageView 和 UIButton
    for (UIView *v in [self subviews]) {
        if ([v class] == [UIImageView class]){
            [v setHidden:YES];
        }
        
        
        if ([v isKindOfClass:[UIButton class]] ||
            [v isKindOfClass:NSClassFromString(@"UIThreePartButton")]) {
            [v setHidden:YES];
        }
    }
    
    //添加背影图
    UIView *backView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
    backView.backgroundColor = [UIColor colorWithRed:66/255.0 green:68/255.0 blue:70/255.0 alpha:1.0];
    [self addSubview:backView];
    
    //添加标题
    UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 0, backView.frame.size.width-20, 30)];
    titleLabel.backgroundColor = [UIColor clearColor];
    titleLabel.text = @"语音识别";
    titleLabel.font = [UIFont systemFontOfSize:16];
    titleLabel.textColor = [UIColor colorWithRed:218.0/255.0 green:217.0/255.0 blue:217.0/255.0 alpha:1];
    [backView addSubview:titleLabel];
    
    //添加关闭按钮huati_close
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setImage:[UIImage imageNamed:@"alert_close.png"] forState:UIControlStateNormal];
    [backView addSubview:button];
    button.tag = 1;
    button.frame = CGRectMake(backView.frame.size.width-25, 5, 20, 20);
    [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
    
    //添加黄线
    UIView *xianView = [[UIView alloc]initWithFrame:CGRectMake(0, 30, backView.frame.size.width, 1)];
    xianView.backgroundColor = [UIColor yellowColor];
    [backView addSubview:xianView];
    
    //添加内容
    UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 35, backView.frame.size.width, 40)];
    label.backgroundColor = [UIColor clearColor];
    label.text = @"默认不讲话5秒后自动关闭,间隔不讲话2秒后关闭,最多说20秒";
    label.font = [UIFont boldSystemFontOfSize:15];
    label.textAlignment = UITextAlignmentCenter;
    label.textColor = [UIColor yellowColor];
    [backView addSubview:label];
    label.numberOfLines = 0;
    
    //添加中间图片
    speechImage = [[UIImageView alloc]initWithFrame:CGRectMake((self.frame.size.width-50)/2, 80, 50, 85)];
    speechImage.image = [UIImage imageNamed:@"yuyin_01.png"];
    [backView addSubview:speechImage];
    
    //添加说完了按钮
    UIButton *submitButton = [UIButton buttonWithType:UIButtonTypeCustom];
    
    submitButton.frame = CGRectMake((backView.frame.size.width-170)/2, 170, 150, 35);
    submitButton.tag = 2;
    [submitButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [submitButton setTitle:@"说完了" forState:UIControlStateNormal];
    [submitButton setBackgroundImage:[UIImage imageNamed:@"alert_tButton.png"] forState:UIControlStateNormal];
    [submitButton addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
    [backView addSubview:submitButton];
    //想添加什么由此添加
    
    //创建对象
    NSString *initString = [[NSString alloc] initWithFormat:@"appid=%@,timeout=%@",APPID,TIMEOUT];
    //语音识别对象创建
    _iFlySpeechRecognizer = nil;
    _iFlySpeechRecognizer = [IFlySpeechRecognizer createRecognizer:initString delegate:self];
//    _iFlySpeechRecognizer.delegate = self;
    /*
     2.vad_bos:静音超时时间,即用户多长时间不说话则当做超 时处理,单位:ms,engine 指定 sms 识别默认值为 5000,其他 情况默认值为 4000,范围 0-10000;
     3.vad_eos:后端点静音检测时间,即用户停止说话多长时间 内即认为不再输入,自动停止录音,单位:ms,sms 识别默认 值为 1800,其他默认值为 700,范围 0-10000;
     */
    [_iFlySpeechRecognizer setParameter:@"domain" value:@"sms"];
    [_iFlySpeechRecognizer setParameter:@"sample_rate" value:@"16000"];
    [_iFlySpeechRecognizer setParameter:@"plain_result" value:@"0"];
    initString = nil;
    
    //开始识别
    [_iFlySpeechRecognizer startListening];
    
}
//按钮处理方法
-(void) buttonClicked:(id)sender
{
    [self dismissWithClickedButtonIndex:0 animated:YES];
    
}

//显示
-(void)show
{
//    [super show];
    UIWindow *window =  [UIApplication sharedApplication].keyWindow;
    backgroundView = [[UIView alloc]initWithFrame:window.frame];
    backgroundView.backgroundColor = [UIColor clearColor];
    [backgroundView addSubview:self];
    [window addSubview:backgroundView];
}
//弹出框消失
-(void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated
{
    [_iFlySpeechRecognizer stopListening];
    [_iFlySpeechRecognizer cancel];
    [_iFlySpeechRecognizer setDelegate:nil];
    _iFlySpeechRecognizer = nil;
    speechImage = nil;
    [backgroundView removeFromSuperview];
    backgroundView = nil;
}


#pragma mark - IFlySpeechRecognizerDelegate
- (void) onVolumeChanged: (int)volume
{
    NSLog(@"%d",volume);
    //录音的音量,音量范围1~100
    if (volume>=0 &&volume<=5) {
        speechImage.image = [UIImage imageNamed:@"yuyin_01.png"];
    }else if(volume>5 && volume<=30){
        speechImage.image = [UIImage imageNamed:@"yuyin_02.png"];
    }else{
        speechImage.image = [UIImage imageNamed:@"yuyin_03.png"];
    }
}

- (void) onBeginOfSpeech
{
    NSLog(@"正在录音");
}

- (void) onEndOfSpeech
{
    NSLog(@"停止录音");
}

- (void) onError:(IFlySpeechError *) error
{
    NSLog(@"停止录音%@,%@",error,[error errorDesc]);
    [self dismissWithClickedButtonIndex:0 animated:YES];
}

//结果
- (void) onResults:(NSArray *) results
{
    NSMutableString *result = [[NSMutableString alloc] init];
    NSDictionary *dic = [results objectAtIndex:0];
    for (NSString *key in dic) {
        [result appendFormat:@"%@",key];
    }
    NSLog(@"转写结果:%@--results:%@",result,results);
    
    //返回结果
    [_speechDelegate getResultText:result];
}

@end

源码下载地址:

http://download.csdn.net/detail/rhljiayou/5889565

2015-06-15 22:08:50 taiyb 阅读数 756
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    6094 人正在学习 去看看 杨波
<span style="font-size:24px;">对于搜索来说,首先,也最重要的就是建立搜索空间。在语言识别中搜索空间是怎么建立的了。我们知道语音识别一般包括语言模型和声学模型。而语音识别就是要在搜索空间中找到最有可能的字的序列。我们一般是按句来处理的。一句话有许多词所组成,我们所要做的就是确定一句话,中的那些词即字。我们一般会在搜索空间中加上一些特殊的词来表示一句话的开始和结束。在sphinx中一般为<sil>表示句的开始,</sil>表示句的结束。
 对于搜索空间的建立,一般我们是根据语言模型来此字的搜索空间,即每个搜索节点都为一个字。我们建立的搜索空间可以是单向,也开始是双向即即可向前右可以回退。一般在每个搜索空间中每一个节点对象中都会存在着此节点的表示即此节点表示的是哪字或者其它确定的对象如单元即音素。包括指向下一个搜索节点的弧或者指针因为下一搜索节点是存在多个的,所以我们在一个搜索节点存储了弧或指针的集合来指向所有可能的下一搜索节点。如果允许回退的话还可能包括parent节点的指针即对象索引,来指示此搜索节点的上一搜索节点。
根据语言模型建立的字的搜索空间后,我们可以对字搜索空间中的每一个字搜索节点进行扩展。 我们知道一个字是可能有多个发音的。每一个字的发音被用于字搜索节点的扩展,每个发音都是并行的关系。在由于发音是由多个单元即音素所组成,而我们在训练声学模型时在sphinx中一般是对音素进行建模的,即一个音素一个hmm模型。因此我们可以根据字的发音来确定单元即音素之间的串行连接顺序,即扩展扩展成单元串。在我们可以按照我们所训练的声学模型来对单元来进行扩展,把单元即音素扩展成hmm网络。
在进行搜索空间的建立时我们需要注意的是扩展后的相互连接。对于搜索空间的建立有多种方法。应根据需要来选取。我们也可以建立字的扩展成hmm网络的的小的网络。然后在把所有小网络按照语言模型来组成大网络。
在搜索空间中我们站在不同的角度来思考问题或扩展问题,其就会有不同的处理过程。
在搜索空间建立的时候我们可以不用建立完整的搜索空间,而是建立那些最有可能的结果的搜索空间。来节省内容。在此期间我们会用到一个限制条件。如限制每一搜索节点的直接后续节点数,此限制可以是动态的。我们也可以在不同的角度来却限制的方面,如在字的角度,在hmm链的角度。
搜索空间建立好了我们就可以根据输入的声学特征矢量来进行搜索。在此搜索我们可以分为多种方法。一般一次打分,和多次打分的方法。我们一次搜索中一条最有可能的搜索路径作为结果。也可以搜索多条路径作为结果。我们可以在搜索结果上再进行处理。来确保我们所搜索到的是全局的最优搜索路径。在就需在进行多次打分处理。</span>

2015-07-14 03:09:30 yuanmeng001 阅读数 1312
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    6094 人正在学习 去看看 杨波

        语音识别(SR)功能是当今国外操作系统的标准特征,而国产操作系统根本不具备这种特质,而且国家队没有相关的主观动力,去开发实际可用的语音识别系统。与国外相比,国产操作系统落后了一大节子,怪谁?



怎样让机器识别人的语音?其实大道理并不复杂,首先,让机器设备听懂元音,然后听懂辅音,将两者合成起来成为单词,再做进一步的处理。但是,实际做起来就复杂了。怎么做?



建立“语料库”(Corpus),就是建立语音的声学模型库。比如,”猫“这个单词的发音,必须让机器记住“猫”的发音,设法让机器听到“猫”所对应的“声音”(所谓”生物信号“)就知道主人对它说的是“猫”。语料库就是建立单词与语音的对应关系。这是基本建设,需要投入大量的人力、物力,别无他法。



任何语音都有个人特征,虽然100个人的发音基本相同,但是,存在一定的差异。所以机器的听觉总是存在“错误率”,这是必然的。降低机器识别错误率是必要的,这是一个基本认识,对机器不能要求过高。机器耳朵永远比不过人耳。



微软、谷歌、百度语音识别巨头都拥有各自的数万小时的语料库,但是,我们却没有,Linux社区也没有GPL可用的语料库(VoxForge不带我们玩)。怎么办?天上不会自动掉馅饼。要知道,私有公司建立自己的版权大型语料库总是要付出巨大的投入成本。而我们有人喜欢天上掉馅饼,整天坐在院子里面张着大嘴巴对着蓝天等着天上掉下馅饼来。



袁萌 714



没有更多推荐了,返回首页