2019-03-18 10:08:49 mcsbary 阅读数 1212
  • 云从科技:详解CNN-pFSMN模型以及在语音识别中的应用

    近日,云从科技在语音识别技术上取得重大突破,在全球最大的开源语音识别数据集Librispeech上刷新了世界纪录,错词率(Worderrorrate,WER)降到了2.97%,将Librispeech的WER指标提升了25%,大幅刷新原先记录。本视频课程讲解了:大规模词汇连续语音识别,LVCSR前沿与最新进展,和CNN-pFSMN声学模型。

    1134 人正在学习 去看看 CSDN讲师


转载本文
语音识别的基础知识与CMUsphinx介绍:
http://blog.csdn.net/zouxy09/article/details/7941585
PocketSphinx语音识别系统的编译、安装和使用:
http://blog.csdn.net/zouxy09/article/details/7942784
PocketSphinx语音识别系统语言模型的训练和声学模型的改进:
http://blog.csdn.net/zouxy09/article/details/7949126
PocketSphinx语音识别系统声学模型的训练与使用
http://blog.csdn.net/zouxy09/article/details/7962382

本文主要实现PocketSphinx语音识别系统的编程使用,主要分两个方面,一个是编程解码语音文件(主要参考CMU sphinx的wiki:http://cmusphinx.sourceforge.net/wiki/),二是编程识别麦克风的语音(主要参考PocketSphinx源码包里的pocketsphinx.c文件)。对于后面加入我的人机交互系统的话,采用的是识别麦克风的语音的编程,具体使用时还需要对其进行精简。

一、编程解码语音文件

1、编程

#include <pocketsphinx.h>  
  
int main(int argc, char *argv[])  
{  
    ps_decoder_t *ps;  
    cmd_ln_t *config;  
    FILE *fh;  
    char const *hyp, *uttid;  
        int16 buf[512];  
    int rv;  
    int32 score;  
  
    //1、初始化:创建一个配置对象 cmd_ln_t *  
    //cmd_ln_init函数第一个参数是我们需要更新的上一个配置,因为这里是初次创建,所以传入NULL;  
    //第二个参数是一个定义参数的数组,如果使用的是标准配置的参数集的话可以通过调用ps_args()去获得。  
    //第三个参数是是一个标志,它决定了参数的解释是否严格,如果为TRUE,那么遇到重复的或者未知的参  
    //数,将会导致解释失败;  
    //MODELDIR这个宏,指定了模型的路径,包括声学模型,语言模型和字典三个文件,是由gcc命令行传入,  
    //我们通过pkg-config工具从PocketSphinx的配置中去获得这个modeldir变量  
    config = cmd_ln_init(NULL, ps_args(), TRUE,  
                 "-hmm", MODELDIR "/hmm/en_US/hub4wsj_sc_8k",  
                 "-lm", MODELDIR "/lm/en/turtle.DMP",  
                 "-dict", MODELDIR "/lm/en/turtle.dic",  
                 NULL);  
    if (config == NULL)  
        return 1;  
      
    //2、初始化解码器(语言识别就是一个解码过程,通俗的将就是将你说的话解码成对应的文字串)  
    ps = ps_init(config);  
    if (ps == NULL)  
        return 1;  
  
    //3、解码文件流  
    //因为音频输入接口(麦克风)受到一些特定平台的影响,不利用我们演示,所以我们通过解码音频文件流  
    //来演示PocketSphinx API的用法,goforward.raw是一个包含了一些诸如“go forward ten meters”等用来  
    //控制机器人的短语(指令)的音频文件,其在test/data/goforward.raw。把它复制到当前目录  
    fh = fopen("/dev/input/event14", "rb");  
    if (fh == NULL) {  
        perror("Failed to open goforward.raw");  
        return 1;  
    }  
      
    //4、使用ps_decode_raw()进行解码  
      
    rv = ps_decode_raw(ps, fh, NULL, -1);  
    if (rv < 0)  
        return 1;  
      
    //5、得到解码的结果(概率最大的字串) hypothesis  
    hyp = ps_get_hyp(ps, &score, &uttid);  
    if (hyp == NULL)  
        return 1;  
    printf("Recognized: %s\n", hyp);  
  
    //从内存中解码音频数据  
    //现在我们将再次解码相同的文件,但是使用API从内存块中解码音频数据。在这种情况下,首先我们  
    //需要使用ps_start_utt()开始说话:  
    fseek(fh, 0, SEEK_SET);  
      
    rv = ps_start_utt(ps, NULL);  
    if (rv < 0)  
        return 1;  
        while (!feof(fh)) {  
    rv = ps_start_utt(ps, NULL);  
        if (rv < 0)  
                return 1;  
  
        printf("ready:\n");  
            size_t nsamp;  
            nsamp = fread(buf, 2, 512, fh);  
        printf("read:\n");  
            //我们将每次从文件中读取512大小的样本,使用ps_process_raw()把它们放到解码器中:  
            rv = ps_process_raw(ps, buf, nsamp, FALSE, FALSE);  
        printf("process:\n");  
        }  
        //我们需要使用ps_end_utt()去标记说话的结尾处:  
        rv = ps_end_utt(ps);  
    if (rv < 0)  
        return 1;  
          
    //以相同精确的方式运行来检索假设的字符串:  
    hyp = ps_get_hyp(ps, &score, &uttid);  
    if (hyp == NULL)  
        return 1;  
    printf("Recognized: %s\n", hyp);  
    }  
    //6、清理工作:使用ps_free()释放使用ps_init()返回的对象,不用释放配置对象。  
    fclose(fh);  
        ps_free(ps);  
    return 0;  
}  

2、编译:

编译方法

gcc -o test_ps test_ps.c -DMODELDIR=\"`pkg-config --variable=modeldir pocketsphinx`\" `pkg-config --cflags --libs pocketsphinx sphinxbase`

gcc的-D选项,指定宏定义,如-Dmacro=defn 相当于C语言中的#define macro=defn那么上面就表示在test_ps.c文件中,新加入一个宏定义:

#define MODELDIR=\"`pkg-config --variable=modeldir pocketsphinx`\"

\表示转义符,把“号转义。

这么做是为什么呢?因为程序中需要指定MODELDIR这个变量,但是因为不同的使用者,这个变量不一样,没办法指定死一个路径,所以只能放在编译时,让用户去根据自己的情况来指定。

pkg-config工具可以获得一个库的编译和连接等信息;
#pkg-config --cflags --libs pocketsphinx sphinxbase
显示:

-I/usr/local/include/sphinxbase  -I/usr/local/include/pocketsphinx
-L/usr/local/lib -lpocketsphinx -lsphinxbase –lsphinxad

#pkg-config --variable=modeldir pocketsphinx
显示结果输出:

/usr/local/share/pocketsphinx/model

二、编程解码麦克风的录音

1、编程

麦克风录音数据的获得主要是用sphinxbase封装了alsa的接口来实现。

#include <stdio.h>  
#include <string.h>  
#include <sys/types.h>  
#include <sys/time.h>  
#include <signal.h>  
#include <setjmp.h>  
  
#include <sphinxbase/err.h>  
//generic live audio interface for recording and playback  
#include <sphinxbase/ad.h>  
#include <sphinxbase/cont_ad.h>  
  
#include "pocketsphinx.h"  
  
static ps_decoder_t *ps;  
static cmd_ln_t *config;  
  
static void print_word_times(int32 start)  
{  
    ps_seg_t *iter = ps_seg_iter(ps, NULL);  
    while (iter != NULL)   
    {  
        int32 sf, ef, pprob;  
        float conf;  
          
        ps_seg_frames (iter, &sf, &ef);  
        pprob = ps_seg_prob (iter, NULL, NULL, NULL);  
        conf = logmath_exp(ps_get_logmath(ps), pprob);  
        printf ("%s %f %f %f\n", ps_seg_word (iter), (sf + start) / 100.0, (ef + start) / 100.0, conf);  
        iter = ps_seg_next (iter);  
    }  
}  
  
/* Sleep for specified msec */  
static void sleep_msec(int32 ms)  
{  
    struct timeval tmo;  
  
    tmo.tv_sec = 0;  
    tmo.tv_usec = ms * 1000;  
  
    select(0, NULL, NULL, NULL, &tmo);  
}  
  
/* 
 * Main utterance processing loop: 
 *     for (;;) { 
 *     wait for start of next utterance; 
 *     decode utterance until silence of at least 1 sec observed; 
 *     print utterance result; 
 *     } 
 */  
static void recognize_from_microphone()  
{  
    ad_rec_t *ad;  
    int16 adbuf[4096];  
    int32 k, ts, rem;  
    char const *hyp;  
    char const *uttid;  
    cont_ad_t *cont;  
    char word[256];  
  
    if ((ad = ad_open_dev(cmd_ln_str_r(config, "-adcdev"),  
                          (int)cmd_ln_float32_r(config, "-samprate"))) == NULL)  
        E_FATAL("Failed top open audio device\n");  
  
    /* Initialize continuous listening module */  
    if ((cont = cont_ad_init(ad, ad_read)) == NULL)  
        E_FATAL("Failed to initialize voice activity detection\n");  
    if (ad_start_rec(ad) < 0)  
        E_FATAL("Failed to start recording\n");  
    if (cont_ad_calib(cont) < 0)  
        E_FATAL("Failed to calibrate voice activity detection\n");  
  
    for (;;) {  
        /* Indicate listening for next utterance */  
        printf("READY....\n");  
        fflush(stdout);  
        fflush(stderr);  
  
        /* Wait data for next utterance */  
        while ((k = cont_ad_read(cont, adbuf, 4096)) == 0)  
            sleep_msec(100);  
  
        if (k < 0)  
            E_FATAL("Failed to read audio\n");  
  
        /* 
         * Non-zero amount of data received; start recognition of new utterance. 
         * NULL argument to uttproc_begin_utt => automatic generation of utterance-id. 
         */  
        if (ps_start_utt(ps, NULL) < 0)  
            E_FATAL("Failed to start utterance\n");  
        ps_process_raw(ps, adbuf, k, FALSE, FALSE);  
        printf("Listening...\n");  
        fflush(stdout);  
  
        /* Note timestamp for this first block of data */  
        ts = cont->read_ts;  
  
        /* Decode utterance until end (marked by a "long" silence, >1sec) */  
        for (;;) {  
            /* Read non-silence audio data, if any, from continuous listening module */  
            if ((k = cont_ad_read(cont, adbuf, 4096)) < 0)  
                E_FATAL("Failed to read audio\n");  
            if (k == 0) {  
                /* 
                 * No speech data available; check current timestamp with most recent 
                 * speech to see if more than 1 sec elapsed.  If so, end of utterance. 
                 */  
                if ((cont->read_ts - ts) > DEFAULT_SAMPLES_PER_SEC)  
                    break;  
            }  
            else {  
                /* New speech data received; note current timestamp */  
                ts = cont->read_ts;  
            }  
  
            /* 
             * Decode whatever data was read above. 
             */  
            rem = ps_process_raw(ps, adbuf, k, FALSE, FALSE);  
  
            /* If no work to be done, sleep a bit */  
            if ((rem == 0) && (k == 0))  
                sleep_msec(20);  
        }  
  
        /* 
         * Utterance ended; flush any accumulated, unprocessed A/D data and stop 
         * listening until current utterance completely decoded 
         */  
        ad_stop_rec(ad);  
        while (ad_read(ad, adbuf, 4096) >= 0);  
        cont_ad_reset(cont);  
  
        printf("Stopped listening, please wait...\n");  
        fflush(stdout);  
        /* Finish decoding, obtain and print result */  
        ps_end_utt(ps);  
        hyp = ps_get_hyp(ps, NULL, &uttid);  
        printf("%s: %s\n", uttid, hyp);  
        fflush(stdout);  
  
        /* Exit if the first word spoken was GOODBYE */  
        if (hyp) {  
            sscanf(hyp, "%s", word);  
            if (strcmp(word, "goodbye") == 0)  
                break;  
        }  
  
        /* Resume A/D recording for next utterance */  
        if (ad_start_rec(ad) < 0)  
            E_FATAL("Failed to start recording\n");  
    }  
  
    cont_ad_close(cont);  
    ad_close(ad);  
}  
  
static jmp_buf jbuf;  
static void sighandler(int signo)  
{  
    longjmp(jbuf, 1);  
}  
  
int main(int argc, char *argv[])  
{  
      
    config = cmd_ln_init(NULL, ps_args(), TRUE,  
                 "-hmm", MODELDIR "/hmm/en_US/hub4wsj_sc_8k",  
                 "-lm", MODELDIR "/lm/en/turtle.DMP",  
                 "-dict", MODELDIR "/lm/en/turtle.dic",  
                 NULL);  
    if (config == NULL)  
        return 1;  
      
    ps = ps_init(config);  
    if (ps == NULL)  
        return 1;  
  
    signal(SIGINT, &sighandler);  
    if (setjmp(jbuf) == 0)   
        recognize_from_microphone();  
      
        ps_free(ps);  
    return 0;  
}  

2、编译

和1.2一样。

至于说后面把PocketSphinx语音识别系统加入我的人机交互系统这个阶段,因为感觉这个系统本身的识别率不是很高,自己做了适应和重新训练声学和语言模型后,提升还是有限,暂时实用性还不是很强,所以暂时搁置下,看能不能通过其他方法去改进目前的状态。希望有牛人指导下。另外,由于开学了,需要上课,所以后续的进程可能会稍微减慢,不过依然期待各位多多交流!呵呵

2019-04-24 09:37:17 whale52hertz 阅读数 132
  • 云从科技:详解CNN-pFSMN模型以及在语音识别中的应用

    近日,云从科技在语音识别技术上取得重大突破,在全球最大的开源语音识别数据集Librispeech上刷新了世界纪录,错词率(Worderrorrate,WER)降到了2.97%,将Librispeech的WER指标提升了25%,大幅刷新原先记录。本视频课程讲解了:大规模词汇连续语音识别,LVCSR前沿与最新进展,和CNN-pFSMN声学模型。

    1134 人正在学习 去看看 CSDN讲师

来源:ATYUN AI平台 

技术的进步推动了语音界面的发展,通过机器学习工具的普及,使得更多的互联网连接产品能够比以往任何时候都更能倾听和回应我们的声音。许多人将会体验到新的语音设备带来的便利。

语音识别取得了两个里程碑进展 Mozilla发布开源语音识别模型和语音数据集

Mozilla(缩写MF或MoFo)全称Mozilla基金会,是为支持和领导开源的Mozilla项目而设立的一个非营利组织。Mozilla对语音识别的潜力感到兴奋。他们相信这项技术能够并且将会带来一波创新产品和服务的浪潮,并且应该对所有人开放。

上个月29日,Mozilla的机器学习小组的语音识别工作取得了两个重要的里程碑进展。其中之一是Mozilla的开源语音识别模型首次发布,该模型的准确性接近人类在听同样的录音时的感知。其次,Mozilla还发布了世界上第二大公开的语音数据集,这是全球近2万名用户的贡献。

一个接近用户期望性能的开放源码的语音文本引擎
目前只有少数几家大公司的商业质量语音识别服务是可行的。这就减少了用户的选择,也减少了初创公司、研究人员甚至更大的公司的可用功能,这些公司想要为他们的产品和服务提供支持。

这就是为什么Mozilla将DeepSpeech作为一个开放源码项目。Mozilla和一群志同道合的开发人员、公司和研究人员组成的社区一起,应用了复杂的机器学习技术和各种各样的创新,在LibriSpeech的测试数据集上构建了一个语音到文本的引擎,出错率仅为6.5%。

在发布的第一个版本中,引擎包含了Python、NodeJS和一个命令行二进制代码的预构建包,开发者可以马上使用它来进行语音识别。

构建世界上最多样化的公开语音数据集,为训练语音技术最优化
如此少的服务在商业上可用的一个原因是缺乏数据。创业公司、研究人员或任何想要建立语音技术的人都需要高质量的、转录的语音数据来训练机器学习算法。现在,他们只能访问相当有限的数据集。

为了解决这一障碍,Mozilla在今年7月启动了Common Voice项目。目标是让人们可以很容易地把他们的声音捐赠给一个公开的数据库,这样就可以建立一个语音数据集,每个人都可以用它来训练新的语音应用程序。

语音识别取得了两个里程碑进展 Mozilla发布开源语音识别模型和语音数据集

到目前为止,Mozilla已经发布了第一批捐赠者的声音:近40万种录音,相当于500小时的演讲。任何人都可以下载这些数据。

Mozilla收到了来自全球范围内的2万多人提供的不同的声音。通常,现有的语音识别服务无法理解不同的口音,而且大多数情况,比起女性更善于理解男性的语音——这是语音识别服务接受训练的数据中存在的偏见结果。Mozilla希望说话者的数量和他们的不同的口音能够创造出一个全球性的代表数据集,从而带来更具包容性的技术。

为此,Mozilla开始使用英语,并且正在努力确保从2018年上半年开始,Common Voice项目能够支持多种语言的语音捐赠。最后,当经历了寻找可公开的语音数据集的挑战时,Mozilla还收集了所有其他我们所知道的大型语音收集的链接。

Mozilla认为,技术应该是开放的,所有人都可以访问,包括语音。Mozilla开发这种技术的方法是由设计开放的,他们非常欢迎更多的合作者和贡献者与之一起工作。

本文转自ATYUN人工智能媒体平台,原文链接:语音识别取得了两个里程碑进展 Mozilla发布开源语音识别模型和语音数据集

更多推荐

达观数据荣获上海市软件企业核心竞争力评价,推动上海软件行业发展

云从科技 | 从初创企业上位AI“国家队”,看看背后都干了些什么?!

智行者蜗小白“无人清扫车”南翠屏上岗(图)

裤子变裙子,GAN图像转换新进展

欢迎关注ATYUN官方公众号,商务合作及内容投稿请联系邮箱:bd@atyun.com
欢迎关注ATYUN官方公众号,商务合作及内容投稿请联系邮箱:bd@atyun.com

 

2019-05-17 15:34:26 muxiue 阅读数 998
  • 云从科技:详解CNN-pFSMN模型以及在语音识别中的应用

    近日,云从科技在语音识别技术上取得重大突破,在全球最大的开源语音识别数据集Librispeech上刷新了世界纪录,错词率(Worderrorrate,WER)降到了2.97%,将Librispeech的WER指标提升了25%,大幅刷新原先记录。本视频课程讲解了:大规模词汇连续语音识别,LVCSR前沿与最新进展,和CNN-pFSMN声学模型。

    1134 人正在学习 去看看 CSDN讲师

开源语音识别工具包

目前开源世界里存在多种不同的语音识别工具包,它们为开发者构建语音识别相关的应用提供了很大的帮助。以下是目前比较流行的语音识别工具包:

  1. CMU Sphinx
  2. Kaldi
  3. HTK
  4. Julius
  5. ISIP
    作为语音识别小白,我将从CMU Sphinx入手,从简单的应用搭建到CMU Sphinx代码的阅读和理解,逐步深入了解语音识别这个深奥的世界。

语音识别简介

语音其实上是一个复杂的现象,人们很少理解语音是怎么产生和感知的,最直观的理解就是语言是由多个单词组成的,而每个单词又是由多个音素(phone)组成的,但事实却并不是这样。事实上,语言/语音是一个连续动态的过程,之间没有明显的分界,如果你用一个语音编辑器来看的话,波形就是下面的样子:
在这里插入图片描述
语音实际上是一个概率问题,从而意味着在一段连续的语音中,单词之间没有明显的分界,所以从语音到文字的转换永远不可能100% 正确,这其实颠覆了许多程序员的认知。作为程序员,大多数都在处理一就是一,二就是二的问题,而不是一有可能是一,也有可能是二的问题,而语音识别就是后者。

语音的构成

语音是一种连续的音频流,这个音频流是稳定状态与动态改变状态的叠加, 在这种状态序列中,可以定义相似类别的声音或音素。对应于每个音素的波形的声学特性受许多因素影响——环境,扬声器,语音风格等。另外,协同发音(指的是一个音受前后相邻音的影响而发生变化,从发声机理上看就是人的发声器官在一个音转向另一个音时其特性只能渐变,从而使得后一个音的频谱与其他条件下的频谱产生差异)的存在使得音素的感知与标准不一样,所以我们需要根据上下文来辨别音素。将一个音素划分为几个亚音素单元。如:数字“three”,音素的第一部分与在它之前的音素存在关联,中间部分是稳定的部分,而最后一部分则与下一个音素存在关联,这就是为什么在用HMM模型做语音识别时,选择音素的三状态HMM模型。上下文相关建模方法在建模时考虑了这一影响,从而使模型能更准确地描述语音,只考虑前一音的影响的称为双音素Bi-Phone,考虑前一音和后一音的影响的称为 3音素Tri-Phone,甚至4音素Qin-phones。
从计算角度出发,只检测3音素的一部分比把3音素作为整体考虑要有用的多,例如,现在你想创建一个3音素头部部分的检测器,那么你只需要一小部分(大约4000个)不同的短的声音检测器,我们称这些检测器为senones。一个senone的上下文依赖比单纯的左右上下文复杂得多,它是一个可以被决策树或者其他方式来定义的复杂函数。
音素phones构成亚单词单元,也就是音节syllables。音节是一个比较稳定的实体,因为当语音变得比较快的时候,音素往往会发生改变,但是音节却不变。音节与节奏语调的轮廓有关。有几种方式去产生音节:基于形态学或者基于语音学。音节经常在词汇语音识别中使用。
亚单词单元(音节)构成单词。单词在语音识别中很重要,因为单词约束了音素的组合。假如共有40个音素,然后每个单词平均有7个音素,那么就会存在40^7个单词,但幸运的是就算一个受过优等教育的人也很少使用过20k个单词,这就使识别变得可行。
单词和一些非语言学声音构成了话语(语句,utterances),我们把非语言学声音称为填充物(fillers),例如呼吸,um,uh,咳嗽等,它们在音频中是以停顿做分离的。所以它们更多只是语义上面的概念,不算是一个句子。

识别过程

语音识别一般的方法是:录制语音波形,再把波形通过静音(语句之间的间断,silences)分割为多个语句,然后去识别每个语句所表达的意思。为了达到这个目的,我们需要用单词的所有可能组合去匹配这段音频,然后选择匹配度最高的组合。
在匹配中有几个关键的概念需要了解的:

  1. 特征
    由于描述一个语音需要的参数个数非常多,这样对处理速度的要求就很高(而且也没必要处理那么多的信息,我们只需要处理对识别有帮助的就行),所以我们需要做优化,进行降维。我们用帧frames去分割语音波形,每帧大概10ms,然后每帧提取可以代表该帧语音的39个数字,这39个数字也就是该帧语音的特征,用特征向量来表示。而如何提取特征向量是当下热门的研究课题,不过简单说来,这些提取方法都是由频谱衍生出来的。
  2. 模型
    模型是用来描述一些数学对象的。这些数学对象描述了一些口语的共同属性。在实际应用中,senone的音频模型就是三态高斯混合模型。简单的说,它就是一个最有可能的特征向量。对于模型,有几个问题需要考虑:模型到底多大程度上可以描述实际情况?在模型本身的局限情况下模型能表现得更优吗?自适应模型如何改变条件?
    经典的语言模型称为隐马尔科夫模型(Hidden Markov Model, HMM),在该模型中,过程被描述为以一定概率彼此改变的状态序列。 此模型旨在描述任何顺序过程,如语音。 HMM已被证明对语音解码非常实用。
  3. 匹配算法
    语音识别需要对所有的特征向量和所有的模型做比较匹配,这是一个非常耗时的工作。而在这方面的优化往往是使用一些技巧,在每一点的匹配时,我们通过保留最好的匹配变体(variants),然后通过它在下一帧产生最好的匹配变体。

模型

根据语音结构,在语音识别中需要用到三种模型:

  1. 声学模型
    一个声学模型包含每个senone的声学属性,包括不依赖上下文的模型和依赖上下文的模型。其中不依赖上下文的模型包括不依赖于上下文的属性(每个音素最大可能的特征向量),而依赖上下文的模型包括依赖于上下文的属性(根据上下文构建的senone)。
  2. 语音学字典
    语音学字典包含了从单词到音素之间的映射,这种映射并不是十分有效,例如,在字典中只标注了两到三个发音变体,但是这种方法在大多数时候够用。字典并不是描述单词到音素之间的映射的唯一方法。可以通过运用机器学习算法去学习得到一些复杂的函数去完成映射功能。
  3. 语言模型
    语言模型是用来约束单词搜索的,它定义了哪些词能跟在上一个已经识别的词的后面(匹配是一个顺序的处理过程),这样就可以为匹配过程排除一些不可能的单词。最常用的语言模型是n-gram模型,它包含了单词序列的统计和有限状态模型,通过有限状态机来定义语音序列,有时候会加入权值。为了达到比较好的识别准确率,语言模型必须能够很好的约束空间搜索,也就是说可以更好的预测下一个词。语言模型是约束词汇包含的单词的,这就出现一个问题,就是名字识别(因为名字可以随便由几个单词组成)。为了处理这种情况,语言模型可以包含更小的块,例如亚单词,甚至音素。但是这种情况,识别准确率将会低于基于单词的语言模型。
    特征、模型和搜索算法三部分构成了一个语音识别系统。如果你需要识别不同的语言,那么就需要修改这三个部分。很多语言,都已经存在声学模型,字典,甚至大词汇量语言模型可供下载了。

其他概念

  • 网格(Lattice)是一个代表识别变体的有向图。一般来说,很难去获得一个最好的语音匹配结果,所以Lattices就是一个比较好的格式去存放语音识别的中间结果。
  • N-best lists of variants和网格(lattice)有点像,但是它没有网格那么密集(也就是保留的结果没有网格多)。N-best搜索和多遍搜索:为在搜索中利用各种知识源,通常要进行多遍搜索,第一遍使用代价低的知识源(如声学模型、语言模型和音标词典),产生一个候选列表或词候选网格,在此基础上进行使用代价高的知识源(如4阶或5阶的N-Gram、4阶或更高的上下文相关模型)的第二遍搜索得到最佳路径。
  • 单词混淆网络是从网格的边缘得到的一个严格的节点顺序序列。
  • 语音数据库是一个从任务数据库得到的典型的录音集。如果我们开发的是一个对话的系统,那么数据库就是包含了多个用户的对话录音。而对于听写系统,包含的就是朗读的录音。语音数据库是用来训练,调整和测试解码系统的(也就是语音识别系统)。
  • 文本数据库是为了训练语言模型而收集的文本,一般是以样本文本的方式来收集形成的。而收集过程存在一个问题就是误把PDFs, web pages, scans等现成文档也当成口语文本的形式放进数据库中。所以,我们就需要把这些文件里的标签和文件头去掉,还有把数字展开为它们的语音形式(例如1展开为英文的one或者汉语的yi),另外还需要把缩写给扩大还原为完整单词。

CMU Sphinx

简介

CMU Sphinx(简称Sphinx)是美国卡内基梅隆大学开发的一系列语音识别工具包以及相关工具(例如声学模型训练软件,语言模型编辑软件和语音词典CMUDICT等)的总称。在2000年,卡内基梅隆的Sphinx小组致力于开源几个语音识别器组件,包括Sphinx 2和后来的Sphinx 3(2001年)。Sphinx包括许多工具包,可以用于搭建具有不同需求的应用。

  • Pocketsphinx - 用C语言编写的轻量级的语音识别库;
  • Sphinxbase - Pocketsphinx的支撑库;
  • Sphinx4 - 用Java编写的自适应的,可修改的语音识别库;
  • Sphinxtrain - 声学模型训练软件;
    现在最新的发布版本是:
  • sphinxbase-5prealpha
  • pocketsphinx - 5prealpha
  • sphinx4 - 5prealpha
  • sphinxtrain - 5prealpha
    Sphinx除了是开源之外,还具有很多优势,可以自己定制声音模型,语言模型,语音学字典,用于多个不同的场景,例如语音搜索,语义分析,翻译,智能助手等。
    如何选择你需要的工具包呢?
  • 由于Sphinx有用不同的编程语言开发的工具包,所以开发者可以根据自己的习惯选择相应的语言识别包。
  • 如果你想要快速和可携带性,那么选择pocketsphinx,如果你想要灵活和可管理,那么可以选择sphinx4.

Sphinx初体验

让我们先来用Sphinx自带的Pocketsphinx来体验一下Sphinx语音识别的效果吧。由于Pocketsphinx依赖于SphinxBase库(提供了公共的函数功能),所以需要同时安装SphinxBase和Pocketsphinx,Pocketsphinx才能正常工作。Pocketsphinx可以安装在Linux,windows,MacOS,iPhone和Android上,本文中我们将在windows上进行安装。

下载

sphinxbase下载页
pocketsphinx下载页

下载"sphinxbase-5prealpha-win32.zip"和“pocketsphinx-5prealpha-win32.zip”,并解压缩。
在这里插入图片描述

编译

  • 编译Sphinxbase
    用visual studio打开sphinxbase\sphinxbase.sln,编译所有项目,其中visual studio版本需要是MS Visual Studio 2012及以上,我使用的是visual studio 2017。由于编译版本不一样,在打开solution时,会弹出如下窗口,选择OK。
    在这里插入图片描述
    在这里插入图片描述
    编译后的结果:
    在这里插入图片描述
  • 编译Pocketsphinx
    用visual studio打开pocketsphinx\pocketsphinx.sln,编译所有项目。其他步骤与编译sphinxbase相同。编译结果如下:
    在这里插入图片描述
  • 拷贝sphinxbase.dll到上图中的文件夹中
    在这个地方有个小trick,理论上应该是我们自己编译出spinxbase.dll之后进行拷贝,但是我们从网站上下载的pocketsphinx中,bin\Debug\Win32下自带拷贝好的sphinxbase.dll,当然你也可以把你编译好的dll重新拷贝覆盖掉之前的dll。提示:如果你编译了pocketsphinx,最好是把你编译的sphinxbase结果也复制过去,否则可能出现不匹配,造成程序如法运行。

运行

运行命令:
bin\Release\Win32\pocketsphinx_continuous.exe -inmic yes -hmm model\en-us\en-us -lm model\en-us\en-us.lm.bin -dict model\en-us\cmudict-en-us.dict

参数说明:

  • inmic:使用麦克风,如果使用file,修改为-infile
  • hmm:指定声学模型
  • lm:指定语言模型
  • dict:指定语言学字典

运行结果:你可以开始说话了,不过识别结果感人,暂时原因未知,还需要继续学习。
在这里插入图片描述

如果在命令行运行时,遇到如下错误:
在这里插入图片描述
其中MSVCR110D.dll是MSVCR110.dll的debug版本。如果遇到这个问题,说明你的phocketsphinx与sphinxbase不匹配,需要将编译好的sphinxbase结果复制过去。

下一篇 PocketSphinx在windows上的应用示例,开发工具Visual Studio

2019-09-04 11:54:58 whale52hertz 阅读数 126
  • 云从科技:详解CNN-pFSMN模型以及在语音识别中的应用

    近日,云从科技在语音识别技术上取得重大突破,在全球最大的开源语音识别数据集Librispeech上刷新了世界纪录,错词率(Worderrorrate,WER)降到了2.97%,将Librispeech的WER指标提升了25%,大幅刷新原先记录。本视频课程讲解了:大规模词汇连续语音识别,LVCSR前沿与最新进展,和CNN-pFSMN声学模型。

    1134 人正在学习 去看看 CSDN讲师

 

内容来源:ATYUN AI平台

Common Voice项目旨在创建开源语音识别数据集,Mozilla宣布它正在扩大此众包项目,以加入更多语言。

该技术组织于去年6月首次发布Common Voice,邀请来自世界各地的志愿者通过网络和移动应用来记录文本片段。

该项目与亚马逊,谷歌,苹果和微软等正在开发的专有语音识别技术形成了对比。上述巨头正在大力投资于语音助理,但各自的数据集均由公司自己拥有。

Mozilla于11月推出了第一批Common Voice英语数据集,收录了大约500小时的演讲,并通过20000个人构建了40万个录音。今天,Mozilla正式开始收集另外三种语言的语音数据:法语,德语和威尔士语。目前也正在准备收集另外40种语言。

很明显,语音将成为技术的下一个重要平台。正是在这种背景下,Mozilla正在推进创建开源数据集的计划,任何人都可以自由使用这些数据集来将语音识别智能构建到各种应用程序和服务中。

Mozilla首席创新官Katharina Borchert表示:“我们相信这些不应该为少数几家公司独有,并且我们希望用户自己的语言和口音能够被识别和理解。”

Common Voice项目的用途类似于其他用于对抗私人平台的开放许可项目。比如OpenStreetMap,该项目为开发人员提供开放且可自由使用的世界地图。

在可访问性方面,英语可能在互联网中作为通用语而存在,但事实是大多数人的母语并不是英语。随着语音识别AI革命的兴起,为开发机器学习模型的技术人员提供多语言数据集是必要的。

“使用多种语言标志着Common Voice迈出了重要的一步,我们希望这对于整体语音技术来说也是一种进步,”Common Voice项目的数字策略师Michael Henretty 补充道。“语音技术的民主化不仅会降低全球创新的障碍,更打破了信息获取的阻碍。”

本文转自ATYUN人工智能媒体平台,原文链接:Common Voice开源语音识别数据集项目范围再扩大,开始建立多语言数据集

更多推荐

未来的“抖音神曲”将Made in AI?

15条常用Python小技巧

Github上评价最高的几个机器学习项目

标签:

开源项目自然语言处理NLP

 

欢迎关注ATYUN官方公众号

商务合作及内容投稿请联系邮箱:bd@atyun.com

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