2019-07-31 09:55:17 thinktothings 阅读数 874
  • C++语音识别开篇

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

    5911 人正在学习 去看看 杨波

在线对比

https://aismartvip.com/voice/pk/billing/index

百度阿里语音识别对比

  百度 阿里

格式支持

pcm(不压缩)

wav(不压缩,pcm编码)

amr(压缩格式)

pcm(无压缩的pcm文件或wav文件)

 

Opus

mono

支持语言

中文,英文,粤语,四川话

中文,英文,湖北话,四川话

并发

普通版QPS:2,每秒请求2

       极速版QPS:50,每秒请求50

试用并发:2

商用并发:200

采样率

固定16k 采样率

8000Hz16000Hz

      计费方式          按次计费          按将计费,按时长计费
      时长限制  短语音60秒内,长语音实测超20分钟很容易自动中断,失败率很高 短语音60秒内,
      文件大小限制   录音文件512MB
     自动加标点符号 支持 支持
      时间戳 只有linux支持,超过20分钟时长,自动中断频率很高 支持,精确到每个字或单词的时间戳

 

 

 

 

 

 

 

 

 

 

 

 

 

百度极速版价格

月调用量(万次) 语音识别极速版(元/次)
0<调用次数<=600 0.0042
600<调用次数<=3000 0.0036
3000<调用次数<=6000 0.0029
6000<调用次数<=15000 0.0019
15000<调用次数 0.0014

百度普通版qps价格

QPS购买方式 单价(元)
1QPS/天 80
1QPS/月 1400

阿里调用方式

一句话识别,实时语音识别,录音文件识别

阿里计费方式和报价(预付费方式)

æ°é¢ä»è´¹æ¥ä»·

阿里计费方式和报价(后付费方式)

åä»è´¹æ¹å¼

阿里百度语音识别实测结果

百度阿里语音识别对比

bilibli视频评测: https://www.bilibili.com/video/av61302199

爱奇艺视频评测: https://www.iqiyi.com/v_19rrp089ss.html

统计

  百度 百度极速版 阿里
统计字个数 396 396 396
错误字个数 9 25 26
错误率 6.31% 6.56% 2.27%
       

说明:单一案例数据不能完全反映识别率,但在一定程度上可以反应识别率的高低,以及数据适用广度

详细记录

行号 开始时间 结束时间 时长(秒) 字幕   错误字数 字个数
1 0:00:01.500 0:00:03.930 2.43 (百度)    不爱刷牙的小狮子   0    
(百度极速版)    不爱刷牙的小狮子   0    
(阿里)    不爱刷牙的小狮子   0    
        (人工)    不爱刷牙的小狮子       8
                 
2 0:00:04.350 0:00:09.330 4.98 (百度)    小狮子不讲卫生,不爱刷牙,他的嘴巴越来越臭   0    
        (百度极速版)    小狮子不讲卫生,不爱刷牙,他的嘴巴越来越臭   0    
        (阿里)    小狮子不讲卫生,不爱刷牙,他的嘴巴越来越臭   0    
        (人工)    小狮子不讲卫生,不爱刷牙,他的嘴巴越来越臭       19
                 
3 0:00:09.420 0:00:12.000 2.58 (百度)    有一天,小狮子来找小熊玩   0    
(百度极速版)    有一天,小狮子来找小熊玩   0    
(阿里)    有一天,小狮子来找小熊玩   0    
        (人工)    有一天,小狮子来找小熊玩       11
                 
4 0:00:12.030 0:00:14.970 2.94 (百度)    刚开口说枭雄   4    
(百度极速版)    刚开口说枭雄   4    
(阿里)    他刚开口说,小熊,我   0    
        (人工)    他刚开口说,小熊,我       8
                 
5 0:00:15.540  0:00:19.170 3.63 (百度)    还没说完呢,只听小熊说了句什么吗?   1    
(百度极速版)    话还没说完呢,只听小熊说了句什么味儿   1    
(阿里)    包还没说完呢?只听小熊说了句什么味   1    
        (人工)    话还没说完呢?只听小熊说了句什么味       16
                 
6 0:00:19.380 0:00:21.840 2.46 (百度)    接着扑通一声倒在了地上   0    
(百度极速版)    接着扑通一声倒在了地上   0    
(阿里)    接着扑通一声倒在了地上   0    
        (人工)    接着扑通一声倒在了地上       11
                 
7 0:00:21.990 0:00:25.470 3.48 (百度)    小兔,我们小狮子看了小兔子过来   0    
(百度极速版)    小兔,我们小狮子看了小兔子过来   0    
(阿里)    小兔,我们小狮子看了小兔,走过来   0    
        (人工)    小兔,我们小狮子看了小兔,走过来       14
                 
8 0:00:25.560 0:00:27.780 2.22 (百度)    想好的想和她一起玩   2    
(百度极速版)    想好的想和她一起玩   2    
(阿里)    想,很想和他一起玩   1    
        (人工)    想,想和他一起玩       7
                 
9 0:00:27.840 0:00:31.560 3.72 (百度)    话还没说完呢,小兔头晕晕的说了句   0    
(百度极速版)    他话还没说完呢,小兔头晕晕的说了句   0    
(阿里)    他话还没说完呢?小兔头晕晕的,说了句   0    
        (人工)    他话还没说完呢?小兔头晕晕的,说了句       16
                 
10 0:00:31.710 0:00:35.310 3.6 (百度)    好臭,接着也不通一声倒在了地上   0    
(百度极速版)    好臭,接着也不通一声倒在了地上   0    
(阿里)    好臭,接着也扑通一声,倒在了地上   0    
        (人工)    好臭,接着也扑通一声,倒在了地上       14
                 
11 0:00:35.370 0:00:37.350 1.98 (百度)    小狮子呆呆的看着   0    
(百度极速版)    小狮子呆呆的看着   0    
(阿里)    小狮子呆呆地看着   0    
        (人工)    小狮子呆呆地看着       8
                 
12 0:00:37.410 0:00:38.250 0.84 (百度)    不久   0    
(百度极速版)    ERROR_3301_speech quality error._{"err_msg":"speech quality error.","sn":"789471505981564379425","err_no":3301}_app_id_16038894_qps_200_ACCOUNT_BILLING_1   1    
(阿里)    不久   0    
        (人工)    不久       2
                 
13 0:00:38.310 0:00:43.620 5.31 (百度)    小象甩着鼻子走过来,小狮子张开嘴巴对小象说   4    
(百度极速版)    小象甩着鼻子走过来,小狮子张开嘴巴对小象说   4    
(阿里)    小象甩着鼻子走过来,小狮子张开嘴巴对小象说,小夏,我们   1    
        (人工)    小象甩着鼻子走过来,小狮子张开嘴巴对小象说,小象,我们       24
                 
14 0:00:43.620 0:00:44.520 0.9 (百度)    来玩   0    
(百度极速版)    来玩   0    
(阿里)    来玩   0    
        (人工)    来玩       2
                 
15 0:00:44.880 0:00:47.430 2.55 (百度)    好难闻的气味   0    
(百度极速版)    好难闻的气味   0    
(阿里)    好难闻的气味儿啊   0    
        (人工)    好难闻的气味儿啊       8
                 
16 0:00:47.880 0:00:49.860 1.98 (百度)    小向打了个大喷嚏   1    
(百度极速版)    小向打了个大喷嚏   1    
(阿里)    小象打了个大喷嚏   0    
        (人工)    小象打了个大喷嚏       8
                 
17 0:00:49.890 0:00:52.800 2.91 (百度)    接着也摇摇晃晃的倒在了地上   0    
(百度极速版)    接着也摇摇晃晃的倒在了地上   0    
(阿里)    接着也摇摇晃晃地倒在了地上   0    
        (人工)    接着也摇摇晃晃地倒在了地上       13
                 
18 0:00:53.130 0:00:57.330 4.2 (百度)    小狮子没有找到一个朋友玩儿,他闷闷不乐地回到家   0    
        (百度极速版)    小狮子没有找到一个朋友玩儿,他闷闷不乐地回到家   0    
        (阿里)    小狮子没有找到一个朋友玩,他闷闷不乐的回到家   0    
        (人工)    小狮子没有找到一个朋友玩,他闷闷不乐的回到家       21
                 
19 0:00:57.330 0:00:57.330 2.97 (百度)    这时,他看到出远门的爸爸回来了   0    
(百度极速版)    这时,他看到出远门的爸爸回来了   0    
(阿里)    这时,他看到出远门的爸爸回来了   0    
        (人工)    这时,他看到出远门的爸爸回来了       14
                 
20 0:01:00.330 0:01:03.030 2.7 (百度)    小狮子张嘴巴高高兴兴的哈   1    
(百度极速版)    小狮子张嘴巴高高兴兴的哈   1    
(阿里)    小狮子张嘴巴高高兴兴的喊   0    
        (人工)    小狮子张嘴巴高高兴兴的喊       12
                 
21 0:01:03.510 0:01:04.110 0.6 (百度)    ERROR_3301_speech quality error._{"err_msg":"speech quality error.","sn":"128211790751564379419","err_no":3301}_app_id_16038875_qps_100_ACCOUNT_FREE_100   1    
(百度极速版)    ERROR_3301_speech quality error._{"err_msg":"speech quality error.","sn":"640301391711564379425","err_no":3301}_app_id_16038894_qps_200_ACCOUNT_BILLING_1   1    
(阿里)    爸   0    
        (人工)           1
                 
22 0:01:04.319 0:01:09.630 5.311 (百度)    爸爸突然把鼻子捂住,向后退,他对小事的说天呐,多久没说   4    
(百度极速版)    爸爸突然把鼻子捂住,向后退,他对小事的说天呐,多久没说   4    
(阿里)    爸爸突然把鼻子捂住向后退,他对小狮子说天呐,你多久没摔   1    
        (人工)    爸爸突然把鼻子捂住向后退,他对小狮子说天呐,你多久没刷        
                 
23 0:01:09.630 0:01:14.940  5.31 (百度)    小狮子拿到脖子上的毛,不好意思地说好像   2    
(百度极速版)    小狮子拿到脖子上的毛,不好意思地说好像   2    
(阿里)    刷牙了,小狮子拿到脖子上的毛不好意思地说,好像   2    
        (人工)    刷牙了,小狮子挠挠脖子上的毛不好意思地说,好像   0   21
            0    
24 0:01:15.150 0:01:16.620 1.47 (百度)    好像两个星期   0    
(百度极速版)    好像两个星期   0    
(阿里)    好像两个星期   0    
        (人工)    好像两个星期   0   6
            0    
25 0:01:17.010 0:01:17.760 0.75 (百度)    爸爸   0    
(百度极速版)    爸爸   0    
(阿里)    爸爸   0    
        (人工)    爸爸   0   2
            0    
26 0:01:17.790 0:01:22.620 4.83 (百度)    急忙给小狮子找出牙刷和牙膏,让他仔细刷牙   0    
(百度极速版)    急忙给小狮子找出牙刷和牙膏,让他仔细刷牙   0    
(阿里)    急忙给小狮子找出牙刷和牙膏,让他仔细刷牙   0    
        (人工)    急忙给小狮子找出牙刷和牙膏,让他仔细刷牙       19
                 
27 0:01:22.680 0:01:23.580 0.9 (百度)    一会儿   1    
(百度极速版)    一会儿   1    
(阿里)    坐一会儿   1    
        (人工)    不一会儿       4
                 
28 0:01:23.610 0:01:27.540 3.93 (百度)    狮子把牙齿刷干净了,她的嘴巴一点都不抽了   2    
(百度极速版)    狮子把牙齿刷干净了,她的嘴巴一点都不抽了   2    
(阿里)    小狮子把牙齿刷干净了,他的嘴巴一点都不抽了   1    
        (人工)    小狮子把牙齿刷干净了,他的嘴巴一点都不臭了       20
                 
29 0:01:27.690 0:01:30.450 2.76 (百度)    狮子,把今天的经历说给爸爸听   1    
(百度极速版)    狮子,把今天的经历说给爸爸听   1    
(阿里)    小狮子把今天的经历说给爸爸听   0    
        (人工)    小狮子把今天的经历说给爸爸听       14
                 
30 0:01:30.570  0:01:31.290 0.72 (百度)    宝贝   0    
(百度极速版)    宝贝   0    
(阿里)    宝贝   0    
        (人工)    宝贝       2
                 
31 0:01:31.530 0:01:35.610 4.08 (百度)    以后你一定要早晚按时刷牙,不然嘴巴臭臭的   0    
(百度极速版)    以后你一定要早晚20刷牙,不然嘴巴臭臭的   0    
(阿里)    以后,你一定要早晚按时刷牙,不然,嘴巴臭臭的   0    
        (人工)    以后,你一定要早晚按时刷牙,不然,嘴巴臭臭的       19
                 
32 0:01:35.670 0:01:37.620 1.95 (百度)    都不爱和你玩儿啊!   0    
(百度极速版)    都不爱和你玩儿啊!   0    
(阿里)    小伙伴都不爱,可你玩啊   0    
        (人工)    小伙伴都不爱,和你玩啊       10
                 
33 0:01:37.800 0:01:39.300 1.5 (百度)    爸爸对小狮子说   0    
(百度极速版)    爸爸对小狮子说   0    
(阿里)    爸爸对小狮子说   0    
        (人工)    爸爸对小狮子说       7
                 
34 0:01:39.300 0:01:41.340 2.04 (百度)    狮子听了点了点头   1    
(百度极速版)    狮子听了点了点头   1    
(阿里)    小狮子听了点了点头   0    
        (人工)    小狮子听了点了点头       9
                 
35 0:01:41.550 0:01:46.860 5.31 (百度)    从那以后,小狮子每天都按时刷牙,小伙伴们再也不被他熏倒了   0    
  (百度极速版)    从那以后,小狮子每天都按时刷牙,小伙伴们再也不被他熏倒了   0    
  (阿里)    从那以后,小狮子每天都按时刷牙小伙伴们再也不被他熏到了   0    
        (人工)    从那以后,小狮子每天都按时刷牙小伙伴们再也不被他熏到了       26
                 
                 
    错误率            
总字数: 396              
百度错别字 25 6.31%            
百度极速版错别字 26 6.56%            
阿里 9 2.27%            

 

 

2019-08-14 10:19:52 qq_35128576 阅读数 158
  • C++语音识别开篇

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

    5911 人正在学习 去看看 杨波

首次讲讲思路,如果说不定大佬们也可以自己完成  ,如果大佬们懒得弄那就直接

看这里看这里

上面我已经实现了语音的实时录入检测识别并且附带了录入和识别的子项目

1.)本地语音的实时录入、并检测是否有语音录入判断是否休眠

package com.wqc.sound;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.TargetDataLine;

public class EngineeCore {

    String filePath = "E:\\1jAVE\\ECLIPSE\\obj\\nls-example-recognizer\\src\\main\\resources\\voice_cache.wav";

    AudioFormat audioFormat;
    TargetDataLine targetDataLine;
    boolean flag = true;


private void stopRecognize() {
        flag = false;
        targetDataLine.stop();
        targetDataLine.close();
    }private AudioFormat getAudioFormat() {
        float sampleRate = 16000;
        // 8000,11025,16000,22050,44100
        int sampleSizeInBits = 16;
        // 8,16
        int channels = 1;
        // 1,2
        boolean signed = true;
        // true,false
        boolean bigEndian = false;
        // true,false
        return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
    }// end getAudioFormat


    void startRecognize() {
        try {
            // 获得指定的音频格式
            audioFormat = getAudioFormat();
            DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
            targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);

            // Create a thread to capture the microphone
            // data into an audio file and start the
            // thread running. It will run until the
            // Stop button is clicked. This method
            // will return after starting the thread.
            flag = true;
            new CaptureThread().start();
        } catch (Exception e) {
            e.printStackTrace();
        } // end catch
    }// end captureAudio method

    class CaptureThread extends Thread {
        public void run() {
            @SuppressWarnings("unused")
			AudioFileFormat.Type fileType = null;
            File audioFile = new File(filePath);
            boolean has= new File(filePath).exists();
            if(has) {
            	audioFile.delete();
            }
            fileType = AudioFileFormat.Type.WAVE;
            //声音录入的权值
            int weight = 2;
            //判断是否停止的计数
            int downSum = 0;

            ByteArrayInputStream bais = null;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            AudioInputStream ais = null;
            try {
                targetDataLine.open(audioFormat);
                targetDataLine.start();
                byte[] fragment = new byte[1024];

                ais = new AudioInputStream(targetDataLine);
                while (flag) {

                    targetDataLine.read(fragment, 0, fragment.length);
                    //当数组末位大于weight时开始存储字节(有声音传入),一旦开始不再需要判断末位
                    if (Math.abs(fragment[fragment.length-1]) > weight || baos.size() > 0) {
                        baos.write(fragment);
                        System.out.println("守卫:"+fragment[0]+",末尾:"+fragment[fragment.length-1]+",lenght"+fragment.length);
                        //判断语音是否停止
                        if(Math.abs(fragment[fragment.length-1])<=weight){
                            downSum++;
                        }else{
                            System.out.println("重置奇数");
                            downSum=0;
                        }//计数超过20说明此段时间没有声音传入(值也可更改)
                        if(downSum>20){
                            System.out.println("停止录入");
                            break;
                        }

                    }
                }

                //取得录音输入流
                audioFormat = getAudioFormat();
                byte audioData[] = baos.toByteArray();
                bais = new ByteArrayInputStream(audioData);
                ais = new AudioInputStream(bais, audioFormat, audioData.length / audioFormat.getFrameSize());
                //定义最终保存的文件名
                System.out.println("开始生成语音文件");
                AudioSystem.write(ais, AudioFileFormat.Type.WAVE, audioFile);
                downSum = 0;
                stopRecognize();

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //关闭流

                try {
                    ais.close();
                    bais.close();
                    baos.reset();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }// end run
    }// end inner class CaptureThread
}

2.)接下来是阿里的语音识别的系统

package com.wqc.sound;

import java.io.File;
import java.io.InputStream;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;

import com.alibaba.nls.client.protocol.InputFormatEnum;
import com.alibaba.nls.client.protocol.NlsClient;
import com.alibaba.nls.client.protocol.SampleRateEnum;
import com.alibaba.nls.client.protocol.asr.SpeechRecognizer;
import com.alibaba.nls.client.protocol.asr.SpeechRecognizerListener;
import com.alibaba.nls.client.protocol.asr.SpeechRecognizerResponse;

/**
 * @author zhishen.ml
 * @date 2018-06-12
 */
public class SpeechRecognizerDemo {
    private String appKey;
    private String accessToken;
    NlsClient client;

    public SpeechRecognizerDemo(String appKey, String token) {
        this.appKey = appKey;
        this.accessToken = token;
        //创建NlsClient实例,应用全局创建一个即可,默认服务地址为阿里云线上服务地址
        client = new NlsClient(accessToken);
    }

    public SpeechRecognizerDemo(String appKey, String token, String url) {
        this.appKey = appKey;
        this.accessToken = token;
        //创建NlsClient实例,应用全局创建一个即可,用户指定服务地址
        client = new NlsClient(url, accessToken);
    }

    private static SpeechRecognizerListener getRecognizerListener() {
        SpeechRecognizerListener listener = new SpeechRecognizerListener() {
            //识别出中间结果.服务端识别出一个字或词时会返回此消息.仅当setEnableIntermediateResult(true)时,才会有此类消息返回
            @Override
            public void onRecognitionResultChanged(SpeechRecognizerResponse response) {
                //事件名称 RecognitionResultChanged
                System.out.println("name22222222: " + response.getName() +
                    //状态码 20000000 表示识别成功
                    ", status2222222: " + response.getStatus() +
                    //语音识别文本
                    ", result22222222: " + response.getRecognizedText());
            }

            //识别完毕
            @Override
            public void onRecognitionCompleted(SpeechRecognizerResponse response) {
                //事件名称 RecognitionCompleted
                System.out.println("name11111111: " + response.getName() +
                    //状态码 20000000 表示识别成功
                    ", status111111: " + response.getStatus() +
                    //语音识别文本
                    ", result1111111: " + response.getRecognizedText());
            }

            @Override
            public void onStarted(SpeechRecognizerResponse response) {
                System.out.println(
                    "task_id: " + response.getTaskId());
            }

            @Override
            public void onFail(SpeechRecognizerResponse response) {
                System.out.println(
                    "task_id: " + response.getTaskId() +
                        //状态码 20000000 表示识别成功
                        ", status: " + response.getStatus() +
                        //错误信息
                        ", status_text: " + response.getStatusText());

            }
        };
        return listener;
    }

    public void process(InputStream ins) {
        SpeechRecognizer recognizer = null;
        try {
            //创建实例,建立连接
            recognizer = new SpeechRecognizer(client, getRecognizerListener());
            recognizer.setAppKey(appKey);
            //设置音频编码格式
            recognizer.setFormat(InputFormatEnum.PCM);
            //设置音频采样率
            recognizer.setSampleRate(SampleRateEnum.SAMPLE_RATE_16K);
            //设置是否返回中间识别结果
            recognizer.setEnableIntermediateResult(true);

            //此方法将以上参数设置序列化为json发送给服务端,并等待服务端确认
            recognizer.start();
            //语音数据来自声音文件用此方法,控制发送速率;若语音来自实时录音,不需控制发送速率直接调用 recognizer.sent(ins)即可
            recognizer.send(ins, 3200, 100);
            //通知服务端语音数据发送完毕,等待服务端处理完成
            recognizer.stop();

        } catch (Exception e) {
            System.err.println(e.getMessage());
        } finally {
            //关闭连接
            if (null != recognizer) {
                recognizer.close();
            }
        }
    }

    public void shutdown() {
        client.shutdown();
    }

    public static void main(String[] args) throws Exception {
        String appKey = null;
        String token = null;
        String url = null;
        SpeechRecognizerDemo demo = null;
       // while (true) {
//        		EngineeCore engineeCore = new EngineeCore();
//
//        		engineeCore.startRecognize();
        		String filePath = "E:\\1jAVE\\ECLIPSE\\obj\\nls-example-recognizer\\src\\main\\resources\\nls-sample-16k.wav";
  	            File audioFile = new File(filePath);
               //boolean has= new File(filePath).exists();
        		//if (has) {
        			 if (args.length == 2) {
     	                appKey = args[0];
     	                token = args[1];
     	                //default url is wss://nls-gateway.cn-shanghai.aliyuncs.com/ws/v1
     	                demo = new SpeechRecognizerDemo(appKey, token);
     	            } else if (args.length == 3) {
     	                appKey = args[0];
     	                token = args[1];
     	                url = args[2];
     	                demo = new SpeechRecognizerDemo(appKey, token, url);
     	            } else {
     	                System.err.println("SpeechRecognizerDemo need params(url is optional): " +
     	                    "<app-key> <token> [<url>]");
     	                System.exit(-1);
     	            }
     	           
        			 AudioInputStream ins=AudioSystem.getAudioInputStream(audioFile);
     	           // InputStream ins = SpeechRecognizerDemo.class.getResourceAsStream("/voice_cache.wav");
     	            if (null == ins) {
     	                System.err.println("open the audio file failed!");
     	                System.exit(-1);
     	            }
     	            demo.process(ins);
     	            demo.shutdown();
				}
	           
			
		//}
       
   // }

}

上面两个子项目是以独立文件保存和读取的形式来实现的

接下来是pom文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
            <groupId>org.springframework.boot</groupId>
   			 <artifactId>spring-boot-starter-parent</artifactId>
    		<version>1.5.10.RELEASE</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
  <groupId>com.wqc</groupId>
  <artifactId>aliAI-sound-spring</artifactId>
  <version>1.5.10.RELEASE</version>
  <properties>
  	<java.version>1.8</java.version>
  	</properties>
   <dependencies>
        <dependency>
            <groupId>com.alibaba.nls</groupId>
            <artifactId>nls-sdk-recognizer</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.0.13</version>
        </dependency>
        <!-- 语音读书 -->
        <dependency>
		  <groupId>com.hynnet</groupId>
		  <artifactId>jacob</artifactId>
		  <version>1.18</version>
		</dependency>
		<!-- 读取xml -->
		<dependency>
            <groupId>jaxen</groupId>
            <artifactId>jaxen</artifactId>
            <version>1.1-beta-11</version>
                <exclusions>
                <exclusion>
                    <groupId>xerces</groupId>
                    <artifactId>xercesImpl</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>

        <dependency>
            <groupId>com.ibm.icu</groupId>
            <artifactId>icu4j</artifactId>
            <version>3.8</version>
        </dependency>

        <dependency>
            <groupId>xerces</groupId>
            <artifactId>xmlParserAPIs</artifactId>
            <version>2.6.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
           <plugin>
		      <groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-jar-plugin</artifactId>
			<version>2.3.1</version>
			<configuration>
				<archive>
					<manifest>
						<addClasspath>true</addClasspath>
					</manifest>
					<manifestEntries>
						<Premain-Class>
							com.xzq.test.PreAgent
						</Premain-Class>
					</manifestEntries>
				</archive>
			</configuration>
		
		     </plugin>
        </plugins>
    </build>
</project>

 

2018-01-20 16:18:16 iyaosan 阅读数 17949
  • C++语音识别开篇

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

    5911 人正在学习 去看看 杨波

FreeSWITCH 语音识别 ASR 模块

最近很多人都对FreeSWITCH和ASR对接比较感谢兴趣,我之前已经做了一个商业模块(商业模块请点击这里http://www.dingdingtong.cn/smartivr/),考虑到大部分人,只是研究一下,并不准确购买商业模块,特意做一个开源项目给大家提供一个参考。

第一个版本实现 阿里云ASR和FreeSWITCH的直接对接,把识别结果通过ESL输出。

想了开发进度,和本项目的技术交流欢迎加QQ群:340129771

2017-12-10 第一版本代码提交

  • 安装

    • 如果你觉得自己编译太麻烦,可以直接下载我编译好的,放在bin 目录里面。路径请根据自己情况修改。注意只支持x64系统
    • mod_asr.so 复制到到 FreeSWITCH mod 目录。 cp mod_asr.so /usr/local/freeswitch/mod/,如果是fs1.2,请用fs1.2_mod_asr.so的那个。
    • librealTimeUnity.so FreeSWITCH lib 目录,或者系统lib目录。cp librealTimeUnity.so /usr/local/freeswitch/lib/
    • libopus.so FreeSWITCH lib 目录,或者系统lib目录。cp libopus.so.0 /usr/local/freeswitch/lib/
    • config-realtime.txt 复制到 /etc/目录。cp config-realtime.txt /etc/
    • /usr/local/freeswitch/conf/autoload_configs/modules.conf.xml 加入 <load module="mod_asr"/>
    • 重启FreeSWITCH,或者fs_cli 里面执行 reload mod_asr
    • 注意默认只支持单声道8000hz的编码,opus或者g722编码不支持。
  • 编译

  • 使用

    • 申请阿里云的Access Key ID 和 Secret ,请参考 https://help.aliyun.com/document_detail/30437.html?spm=5176.doc35312.6.539.7eNuaN,如果你还没有,可以先使用我已经申请的id(LTAIRLpr2pJFjQbY)和key(oxrJhiBZB5zLX7LKYqETC8PC8ulwh0)测试。
    • fs_cli 执行 originate user/1001 ‘start_asr:id secret,park’ inline,如 bgapi originate user/1001 'start_asr:LTAIRLpr2pJFjQbY oxrJhiBZB5zLX7LKYqETC8PC8ulwh0,park' inline,分机接起来开始说话,就可以看到识别结果输出了。 输出结果的日志等级是 notify console loglevel 5
    • dialplan中使用 测试的时候如果不执行其他APP,park超时会自动挂断,可以加入<action application="set" data="park_timeout=60"/>修改park超时时间。

      <extension name="asr">
          <condition field="destination_number" expression="^(888)$">
              <action application="answer"/>
              <action application="start_asr" data="LTAIRLpr2pJFjQbY oxrJhiBZB5zLX7LKYqETC8PC8ulwh0"/>
              <action application="park"/>
          </condition>
      </extension> 
      
  • 开发

    • fs_cli 测试方式 ,执行 /event custom asr 订阅事件。
    • 识别结果会通过esl输出(需要订阅 custom asr 事件)(阿里云返回的原始json数据)例子如下:

      RECV EVENT
      Event-Subclass: asr
      Event-Name: CUSTOM
      Core-UUID: 48a08a69-7858-407a-be69-679150d34193
      FreeSWITCH-Hostname: MiWiFi-R3D-srv
      FreeSWITCH-Switchname: MiWiFi-R3D-srv
      FreeSWITCH-IPv4: 192.168.31.164
      FreeSWITCH-IPv6: ::1
      Event-Date-Local: 2017-12-10 11:30:32
      Event-Date-GMT: Sun, 10 Dec 2017 03:30:32 GMT
      Event-Date-Timestamp: 1512876632835590
      Event-Calling-File: mod_asr.cpp
      Event-Calling-Function: OnResultDataRecved
      Event-Calling-Line-Number: 55
      Event-Sequence: 914
      ASR-Response: {"finish":0,"request_id":"ee87d7fd5e304bdaa9343d9262f34125","result":{"sentence_id":2,"begin_time":4200,"end_time":6525,"status_code":0,"text":"美国拜拜"},"status_code":200,"version":"2.0"}
      Channel: sofia/external/linphone@192.168.31.210
      

      ASR-Response:asr返回结果。
      Channel:当前通道。主要使用这2个通道变量。

    • 如果你需要用户说完一整句话,再一次性返回结果。请把config-realtime.txt文件ResponseMode:streaming修改为ResponseMode:normal
    • 如果你觉得自己开发太麻烦了,可以联系QQ:1280791187 或者微信:cdevelop,获取商业服务和支持。
2018-06-08 12:52:19 alitech2017 阅读数 4363
  • C++语音识别开篇

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

    5911 人正在学习 去看看 杨波

阿里妹导读:近日,阿里巴巴达摩院机器智能实验室开源了新一代语音识别模型DFSMN,将全球语音识别准确率纪录提高至96.04%(这一数据测试基于世界最大的免费语音识别数据库LibriSpeech)。


对比目前业界使用最为广泛的LSTM模型,DFSMN模型训练速度更快、识别准确率更高。采用全新DFSMN模型的智能音响或智能家居设备,相比前代技术深度学习训练速度提到了3倍,语音识别速度提高了2倍。


开源地址:

https://github.com/tramphero/kaldi

 

本文作者:张仕良


阿里开源语音识别模型DFSMN


在近期举行的云栖大会武汉峰会上,装有DFSMN语音识别模型的“AI收银员”在与真人店员的PK中,在嘈杂环境下准确识别了用户的语音点单,在短短49秒内点了34杯咖啡。此外,装备这一语音识别技术的自动售票机也已在上海地铁“上岗”。


著名语音识别专家,西北工业大学教授谢磊表示:“阿里此次开源的DFSMN模型,在语音识别准确率上的稳定提升是突破性的,是近年来深度学习在语音识别领域最具代表性的成果之一,对全球学术界和AI技术应用都有巨大影响。”


图:阿里在GitHub平台上开源了自主研发的DFSMN语音识别模型


语音识别声学模型


语音识别技术一直都是人机交互技术的重要组成部分。有了语音识别技术,机器就可以像人类一样听懂说话,进而能够思考、理解和反馈。


近几年随着深度学习技术的使用,基于深度神经网络的语音识别系统性能获得了极大的提升,开始走向实用化。基于语音识别的语音输入、语音转写、语音检索和语音翻译等技术得到了广泛的应用。


目前主流的语音识别系统普遍采用基于深度神经网络和隐马尔可夫(Deep Neural Networks-Hidden Markov Model,DNN-HMM)的声学模型,其模型结构如图 1所示。声学模型的输入是传统的语音波形经过加窗、分帧,然后提取出来的频谱特征,如 PLP, MFCC 和 FBK等。而模型的输出一般采用不同粒度的声学建模单元,例如单音素 (mono-phone)、单音素状态、绑定的音素状态 (tri-phonestate) 等。从输入到输出之间可以采用不同的神经网络结构,将输入的声学特征映射得到不同输出建模单元的后验概率,然后再结合HMM进行解码得到最终的识别结果。


最早采用的网络结构是前馈全连接神经网路(Feedforward Fully-connected Neural Networks, FNN)。FNN实现固定输入到固定输出的一对一映射,其存在的缺陷是没法有效利用语音信号内在的长时相关性信息。一种改进的方案是采用基于长短时记忆单元(Long-Short Term Memory,LSTM)的循环神经网络(Recurrent Neural Networks,RNN)。LSTM-RNN通过隐层的循环反馈连接,可以将历史信息存储在隐层的节点中,从而可以有效地利用语音信号的长时相关性。


 1. 基于DNN-HMM的语音识别系统框图


进一步地通过使用双向循环神经网络(BidirectionalRNN),可以有效地利用语音信号历史以及未来的信息,更有利于语音的声学建模。基于循环神经网络的语音声学模型相比于前馈全连接神经网络可以获得显著的性能提升。但是循环神经网络相比于前馈全连接神经网络模型更加复杂,往往包含更多的参数,这会导致模型的训练以及测试都需要更多的计算资源。


另外基于双向循环神经网络的语音声学模型,会面临很大的时延问题,对于实时的语音识别任务不适用。现有的一些改进的模型,例如,基于时延可控的双向长短时记忆单元(Latency Controlled LSTM,LCBLSTM )[1-2],以及前馈序列记忆神经网络(Feedforward SequentialMemory Networks,FSMN)[3-5]。去年我们在工业界第一个上线了基于LCBLSTM的语音识别声学模型。配合阿里的大规模计算平台和大数据,采用多机多卡、16bit量化等训练和优化方法进行声学模型建模,取得了相比于FNN模型约17-24%的相对识别错误率下降。


FSMN模型的前世今生


1.    FSMN模型


FSMN是近期被提出的一种网络结构,通过在FNN的隐层添加一些可学习的记忆模块,从而可以有效地对语音的长时相关性进行建模。FSMN相比于LCBLSTM不仅可以更加方便地控制时延,而且也能获得更好的性能,需要的计算资源也更少。但是标准的FSMN很难训练非常深的结构,会由于梯度消失问题导致训练效果不好。而深层结构的模型目前在很多领域被证明具有更强的建模能力。因而针对此我们提出了一种改进的FSMN模型,称之为深层的FSMN(DeepFSMN, DFSMN)。进一步地我们结合LFR(lowframe rate)技术构建了一种高效的实时语音识别声学模型,相比于去年我们上线的LCBLSTM声学模型可以获得超过20%的相对性能提升,同时可以获得2-3倍的训练以及解码的加速,可以显著地减少我们的系统实际应用时所需要的计算资源。

 

图 2. FSMN模型结构以及和RNN的对比


2.    FSMN到cFSMN的发展历程


最早提出的FSMN的模型[3]结构如图 2(a)所示,其本质上是一个前馈全连接神经网络,通过在隐层旁添加一些记忆模块(memory block)来对周边的上下文信息进行建模,从而使得模型可以对时序信号的长时相关性进行建模。记忆模块采用如图 2(b)所示的抽头延迟结构将当前时刻以及之前 N 个时刻的隐层输出通过一组系数编码得到一个固定的表达。FSMN的提出是受到数字信号处理中滤波器设计理论的启发:任何无限响应冲击(Infinite Impulse Response, IIR)滤波器可以采用高阶的有限冲击响应(Finite Impulse Response, FIR)滤波器进行近似。从滤波器的角度出发,如图 2(c)所示的RNN模型的循环层就可以看作如图 2(d)的一阶IIR滤波器。而FSMN采用的采用如图 2(b)所示的记忆模块可以看作是一个高阶的FIR滤波器。从而FSMN也可以像RNN一样有效地对信号的长时相关性进行建模,同时由于FIR滤波器相比于IIR滤波器更加稳定,因而FSMN相比于RNN训练上会更加简单和稳定。


根据记忆模块编码系数的选择,可以分为:1)标量FSMN(sFSMN);2)矢量FSMN(vFSMN)。sFSMN 和 vFSMN顾名思义就是分别使用标量和矢量作为记忆模块的编码系数。sFSMN和vFSMN记忆模块的表达分别如下公式:



以上的FSMN只考虑了历史信息对当前时刻的影响,我们可以称之为单向的FSMN。当我们同时考虑历史信息以及未来信息对当前时刻的影响时,我们可以将单向的FSMN进行扩展得到双向的FSMN。双向的sFSMN和vFSMN记忆模块的编码公式如下:



这里分别代表回看(look-back)的阶数和向前看(look-ahead)的阶数。我们可以通过增大阶数,也可以通过在多个隐层添加记忆模块来增强FSMN对长时相关性的建模能力。


图 3. cFSMN结构框图


FSMN相比于FNN,需要将记忆模块的输出作为下一个隐层的额外输入,这样就会引入额外的模型参数。隐层包含的节点越多,则引入的参数越多。研究[4]结合矩阵低秩分解(Low-rank matrix factorization)的思路,提出了一种改进的FSMN结构,称之为简洁的FSMN(CompactFSMN,cFSMN),是一个第隐层包含记忆模块的cFSMN的结构框图。


对于cFSMN,通过在网络的隐层后添加一个低维度的线性投影层,并且将记忆模块添加在这些线性投影层上。进一步的,cFSMN对记忆模块的编码公式进行了一些改变,通过将当前时刻的输出显式地添加到记忆模块的表达中,从而只需要将记忆模块的表达作为下一层的输入。这样可以有效得减少模型的参数量,加快网络的训练。具体单向和双向的cFSMN记忆模块的公式表达分别如下:


图 4. Deep-FSMN (DFSMN)模型结构框图


LFR-DFSMN声学模型


1.    Deep-FSMN (DFSMN)网络结构


如图 4是我们进一步提出的Deep-FSMN(DFSMN)的网络结构框图,其中左边第一个方框代表输入层,右边最后一个方框代表输出层。我们通过在cFSMN的记忆模块(红色框框表示)之间添加跳转连接(skip connection),从而使得低层记忆模块的输出会被直接累加到高层记忆模块里。这样在训练过程中,高层记忆模块的梯度会直接赋值给低层的记忆模块,从而可以克服由于网络的深度造成的梯度消失问题,使得可以稳定地训练深层的网络。我们对记忆模块的表达也进行了一些修改,通过借鉴扩张(dilation)卷积[6]的思路,在记忆模块中引入一些步幅(stride)因子,具体的计算公式如下:


其中表示第层记忆模块第t个时刻的输出。S1和S2分别表示历史和未来时刻的编码步幅因子,例如S1=2则表示对历史信息进行编码时每隔一个时刻取一个值作为输入。这样在相同的阶数的情况下可以看到更远的历史,从而可以更加有效的对长时相关性进行建模。


对于实时的语音识别系统我们可以通过灵活的设置未来阶数来控制模型的时延,在极端情况下,当我们将每个记忆模块的未来阶数都设置为0,则我们可以实现无时延的一个声学模型。对于一些任务,我们可以忍受一定的时延,我们可以设置小一些的未来阶数。


相比于之前的cFSMN,我们提出的DFSMN优势在于,通过跳转连接可以训练很深的网络。对于原来的cFSMN,由于每个隐层已经通过矩阵的低秩分解拆分成了两层的结构,这样对于一个包含4层cFSMN层以及两个DNN层的网络,总共包含的层数将达到13层,从而采用更多的cFSMN层,会使得层数更多而使得训练出现梯度消失问题,导致训练的不稳定性。我们提出的DFSMN通过跳转连接避免了深层网络的梯度消失问题,使得训练深层的网络变得稳定。需要说明的是,这里的跳转连接不仅可以加到相邻层之间,也可以加到不相邻层之间。跳转连接本身可以是线性变换,也可以是非线性变换。具体的实验我们可以实现训练包含数十层的DFSMN网络,并且相比于cFSMN可以获得显著的性能提升。


从最初的FSMN到cFSMN不仅可以有效地减少模型的参数,而且可以获得更好的性能[4]。进一步的在cFSMN的基础上,我们提出的DFSMN,可以更加显著地提升模型的性能。如下表是在一个2000小时的英文任务上基于BLSTM,cFSMN,DFSMN的声学模型性能对比。


Model

BLSTM

cFSMN

DFSMN

WER%

10.9

10.8

9.4


从上表中可以看到,在2000小时这样的任务上,DFSMN模型可以获得比BLSTM声学模型相对14%的错误率降低,显著提高了声学模型的性能。


2.    基于LFR-DFSMN的语音识别声学模型


图 5. LFR-DFSMN声学模型结构框图


目前的声学模型,输入的是每帧语音信号提取的声学特征,每帧语音的时长通常为10ms,对于每个输入的语音帧信号会有相对应的一个输出目标。最近有研究提出一种低帧率(LowFrame Rate,LFR)[7]建模方案:通过将相邻时刻的语音帧进行绑定作为输入,去预测这些语音帧的目标输出得到的一个平均输出目标。具体实验中可以实现三帧(或更多帧)拼接而不损失模型的性能。从而可以将输入和输出减少到原来的三分之一甚至更多,可以极大地提升语音识别系统服务时声学得分的计算以及解码的效率。我们结合LFR和以上提出的DFSMN,构建了如图 5的基于LFR-DFSMN的语音识别声学模型,经过多组实验我们最终确定了采用一个包含10层cFSMN层+2层DNN的DFSMN作为声学模型,输入输出则采用LFR,将帧率降低到原来的三分之一。识别结果和去年我们上线的最好的LCBLSTM基线比较如下表所示。

 

CER%

产品线A

产品线B

LFR-LCBLSTM

18.92

10.21

LFR-DFSMN

15.00(+20.72%)

8.04(21.25%)


通过结合LFR技术,我们可以获得三倍的识别加速。从上表中可以看到,在实际工业规模应用上,LFR-DFSMN模型比LFR-LCBLSTM模型可以获得20%的错误率下降,展示了对大规模数据更好的建模特性。


基于多机多卡的大数据声学模型训练


实际的语音识别服务通常会面对非常复杂的语音数据,语音识别声学模型一定要尽可能地覆盖各种可能的场景,包括各种对话、各种声道、各种噪音甚至各种口音,这就意味着海量的数据。而如何应用海量数据快速训练声学模型并上线服务,就直接关系到业务相应速度。


我们利用阿里的Max-Compute计算平台和多机多卡并行训练工具,在使用8机16GPU卡、训练数据为5000小时的情况下,关于LFR-DFSMN声学模型和LFR-LCBLSTM的训练速度如下表:



处理一个epoch需要的时间

LFR-LCBLSTM

10.8小时

LFR-DFSMN

3.4小时


相比于基线LCBLSTM模型,每个epoch DFSMN可以获得3倍的训练速度提升。在2万小时的数据量上训练LFR-DFSMN,模型收敛一般只需要3-4个epoch,因此在16GPU卡的情况下,我们可以在2天左右完成2万小时数据量的LFR-DFSMN声学模型的训练。


解码延时、识别速度和模型大小


设计更为实用化的语音识别系统,我们不仅需要尽可能地提升系统的识别性能,而且需要考虑系统的实时性,这样才能给用户提供更好的体验。此外在实际应用中我们还需要考虑服务成本,因而对于语音识别系统的功耗也有一定的要求。传统的FNN系统,需要使用拼帧技术,解码延迟通常在5-10帧,大约50-100ms。而去年上线的LCBLSTM系统,解决了BLSTM的整句延迟的问题,最终可以将延时控制在20帧左右,大约200ms。对于一些对延时有更高要求的线上任务,还可以在少量损失识别性能的情况下(0.2%-0.3%绝对值左右),将延迟控制在100ms,完全可以满足各类任务的需求。LCBLSTM相比于最好的FNN可以获得超过20%的相对性能提升,但是相同CPU上识别速度变慢(即功耗高),这主要是由模型的复杂度导致。


我们最新的LFR-DFSMN,通过LFR技术可以将识别速度加速3倍以上,进一步的DFSMN相比于LCBLSTM在模型复杂度上可以再降低3倍左右。如下表是我们在一个测试集上统计的不同的模型需要的识别时间,时间越短则表示我们所需要的计算功耗越低:


模型

整个测试集识别所需要的时间

LCBLSTM

956秒

DFSMN

377秒

LFR-LCBLSTM

339秒

LFR-DFSMN

142秒


关于LFR-DFSMN的解码时延问题,我们可以通过减小记忆模块滤波器向未来看的阶数来减小时延。具体实验中我们验证了不同的配置,当我们将LFR-DFSMN的延时控制在5-10帧时,大致只损失相对3%的性能。


此外,相对于复杂的LFR-LCBLSTM模型,LFR-DFSMN模型具有模型精简的特点,虽然有10层DFSMN,但整体模型大小只有LFR-LCBLSTM模型的一半,模型大小压缩了50%。


参考文献:

1.     YuZhang, Guoguo Chen, Dong Yu, and Kaisheng Yao, ng Yao,  long short term memory RNNs for distantspeech recognition,, in IEEE International Conference of Acoustics,Speech andSignal Processing (ICASSP), 2016, pp. 5755-5759.

2.     XueS, Yan Z. Improving latency-controlled BLSTM acoustic models for online speech recognition[C]//Acoustics,Speech and Signal Processing (ICASSP), 2016 IEEE International Conference on.IEEE. 2017.

3.     Zhang S, Liu C, Jiang H, et al. Feedforwardsequential memory networks: A new structure to learn long-term dependency[J].arXiv preprint arXiv:1512.08301, 2015.

4.     Zhang S, Jiang H, Xiong S, et al. CompactFeedforward Sequential Memory Networks for Large Vocabulary Continuous SpeechRecognition[C]//INTERSPEECH. 2016: 3389-3393.

5.     Zhang S, Liu C, Jiang H, et al. Non-recurrentNeural Structure for Long-Term Dependency[J]. IEEE/ACM Transactions on Audio,Speech, and Language Processing, 2017, 25(4): 871-884.

6.     Oord A, Dieleman S, Zen H, et al. Wavenet:A generative model for raw audio[J]. arXiv preprint arXiv:1609.03499, 2016.

7.    Pundak G, Sainath T N. Lower Frame Rate NeuralNetwork Acoustic Models[C]//INTERSPEECH. 2016: 22-26.

2016-06-29 19:59:00 weixin_33768481 阅读数 67
  • C++语音识别开篇

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

    5911 人正在学习 去看看 杨波
阿里小蜜的语音识别、语义理解技术用的是哪家公司的产品?有知道的不?

语音识别方案

阅读数 1015

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