2016-12-30 15:06:26 dujiajiyi_xue5211314 阅读数 15350
  • C++语音识别开篇

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

    5921 人正在学习 去看看 杨波

    2006年,Hinton提出深度学习网络,指出深度神经网络因为层数过多导致训练参数多的问题可以利用逐层初始化解决。在工业界和学术界掀起了深度学习的浪潮,并在语音识别和图像处理领域取得了巨大成功。2011年微软和谷歌在语音识别上采用DNN模型,将词错误率降低20%-30%。这里的DNN主要采用的是DBN,即深度置信网络。随着语音识别以及深度学习的发展,研究人员发现将CNN和RNN模型应用于语音识别领域可以取得更好的效果。本文中主要介绍声学模型的优缺点。

    CNN模型,即卷积神经网络,最开始应用于图像处理。而语音识别中的频谱图,应用于CNN模型,可以克服传统语音识别中采用时间、频率而导致的不稳定问题。DBN和CNN模型没有考虑语音之间的关联信息。而RNN模型,充分考虑了语音之间的相互关系,因此取得更加好的效果。现有的最好的基于深度学习的语音识别一般是基于DBN+CNN+RNN模型的。

上述总结成为,现有的声学模型建立,一般可分为:

(1)混合声学模型

混合高斯-隐马尔科夫模型   GMM-HMM

深度神经网络-隐马尔科夫模型   DNN-HMM

深度循环神经网络-隐马尔科夫模型   RNN-HMM

深度卷积神经网络-隐马尔科夫模型   CNN-HMM

(2)端到端的声学模型

连接时序分类-长短时记忆模型CTC-LSTM

注意力模型Attention

各个模型的优缺点介绍

(1)基于GMM-HMM的声学模型

优点:GMM训练速度快

           声学模型较小,容易移植到嵌入式平台

缺点:GMM没有利用帧的上下文信息

            GMM不能学习深层非线性特征变换

(2)基于DNN-HMM模型

优点: DNN能利用帧的上下文信息,比如前后个扩展5帧

             DNN能学习深层非线性特征变换,表现优于GMM

缺点: 不能利用历史信息来辅助当前任务

(3)基于RNN-HMM模型:

优点:  RNN能有效利用历史信息,将历史消息持久化

              在很多任务上,RNN性能变现优于DNN

缺点:  RNN随着层数的增加,会导致梯度爆炸或者梯度消失

(4)基于CNN-HMM声学模型

优点:CNN对于语音信号,采用时间延迟卷积神经网络可以很好地对信号进行描述学习

            CNN比其他神经网络更能捕捉到特征的不变形

接下来将详细介绍各个声学模型的应用,现在比较熟悉的是DBN模型以及CNN模型,而RNN模型还在学习中。

2017-09-01 16:52:06 jianyuchen23 阅读数 1030
  • C++语音识别开篇

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

    5921 人正在学习 去看看 杨波

语音识别的研究和发展情况基本分为三个主要时期:

2011年之前
没什么进展
2011年—2014年
第一个基于深度学习的语音识别系统。此后有了更多的数据,云计算后,一些公司均采用深度学习技术。
2015年至今
递归神经网络与注意力模型、记忆网络以及其他技术一起,掀起了第三次发展的浪潮。

机器所识别的语音可能包括一部分噪声,所以要求其能够从噪声中提取出与对话相关的部分并将其转化为有意义的文字。

语音识别系统的基本构造块

语音识别基本分为三个部分:

  • 信号位准:信号位准的目的是提取语音信号并增强信号(如果有必要的的话),或是进行适当预处理、清理和特征提取。
  • 噪声位准:噪音位准的目的在于将不同的特征划分成不同的声音。换句话说,声音本身并不能提供一个足够精准的标准,而有时我们将次于原声的声音称为声学标准。
  • 语言位准:因为我们假设这些声音都是人类所产生而且是有意义的,因此我们可以把这些声音组合成词语,然后把这些词语组合成句子。

评级标准

人们对语音识别系统的评价都基于一个名为配电盘(SWBD)的行业标准。(SWBD)是一个语音语料库,整合了电话中的即兴对话,包含音频和人声的副本。
语音识别系统的评价标准主要基于其误字率(WER),误字率是指语音识别系统识别错误的单词有多少。

从2008年得到2011年,误字率一直处于一个稳定的状态,位于23%到24%之间;深度学习从2011年开始出现时,误字率从23%降低至5.5%。

在信号位准中,有着不同的基于神经模型从信号中提取和增强语音本身的技术。同时,还有能够用更加复杂高效的基于神经模型的方法取代经典特征提取方法的技术。
声音和语言位准也包含有各种各样不同的深度学习技术,无论是声音等级分类还是语言等级分类,都采用了不同类型基于神经模型的架构。

2018-09-24 10:24:21 weixin_43268986 阅读数 805
  • C++语音识别开篇

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

    5921 人正在学习 去看看 杨波

自动语音识别
ASR(自动语音识别技术)是使人与人,人与机器更顺畅交流的关键技术。

2018-12-15 13:34:55 chinatelecom08 阅读数 16846
  • C++语音识别开篇

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

    5921 人正在学习 去看看 杨波

利用thchs30为例建立一个语音识别系统

  • 数据处理
  • 搭建模型
    • DFCNN

论文地址:http://xueshu.baidu.com/usercenter/paper/show?paperid=be5348048dd263aced0f2bdc75a535e8&site=xueshu_se
代码地址:https://github.com/audier/my_ch_speech_recognition/tree/master/tutorial

语言模型代码实践tutorial也有啦:

基于CBHG结构:https://blog.csdn.net/chinatelecom08/article/details/85048019
基于自注意力机制:https://blog.csdn.net/chinatelecom08/article/details/85051817

1. 特征提取

input为输入音频数据,需要转化为频谱图数据,然后通过cnn处理图片的能力进行识别。

1. 读取音频文件

import scipy.io.wavfile as wav
import matplotlib.pyplot as plt
import os

# 随意搞个音频做实验
filepath = 'test.wav'

fs, wavsignal = wav.read(filepath)

plt.plot(wavsignal)
plt.show()

png

2. 构造汉明窗

import numpy as np

x=np.linspace(0, 400 - 1, 400, dtype = np.int64)
w = 0.54 - 0.46 * np.cos(2 * np.pi * (x) / (400 - 1))
plt.plot(w)
plt.show()

png

3. 对数据分帧

  • 帧长: 25ms
  • 帧移: 10ms
采样点(s) = fs
采样点(ms)= fs / 1000
采样点(帧)= fs / 1000 * 帧长
time_window = 25
window_length = fs // 1000 * time_window

4. 分帧加窗

# 分帧
p_begin = 0
p_end = p_begin + window_length
frame = wavsignal[p_begin:p_end]
plt.plot(frame)
plt.show()
# 加窗
frame = frame * w
plt.plot(frame)
plt.show()

png

在这里插入图片描述

5. 傅里叶变换

所谓时频图就是将时域信息转换到频域上去,具体原理可百度。人耳感知声音是通过

from scipy.fftpack import fft

# 进行快速傅里叶变换
frame_fft = np.abs(fft(frame))[:200]
plt.plot(frame_fft)
plt.show()

# 取对数,求db
frame_log = np.log(frame_fft)
plt.plot(frame_log)
plt.show()

在这里插入图片描述

在这里插入图片描述

  • 分帧
  • 加窗
  • 傅里叶变换
import numpy as np
import scipy.io.wavfile as wav
from scipy.fftpack import fft


# 获取信号的时频图
def compute_fbank(file):
	x=np.linspace(0, 400 - 1, 400, dtype = np.int64)
	w = 0.54 - 0.46 * np.cos(2 * np.pi * (x) / (400 - 1) ) # 汉明窗
	fs, wavsignal = wav.read(file)
	# wav波形 加时间窗以及时移10ms
	time_window = 25 # 单位ms
	window_length = fs / 1000 * time_window # 计算窗长度的公式,目前全部为400固定值
	wav_arr = np.array(wavsignal)
	wav_length = len(wavsignal)
	range0_end = int(len(wavsignal)/fs*1000 - time_window) // 10 # 计算循环终止的位置,也就是最终生成的窗数
	data_input = np.zeros((range0_end, 200), dtype = np.float) # 用于存放最终的频率特征数据
	data_line = np.zeros((1, 400), dtype = np.float)
	for i in range(0, range0_end):
		p_start = i * 160
		p_end = p_start + 400
		data_line = wav_arr[p_start:p_end]	
		data_line = data_line * w # 加窗
		data_line = np.abs(fft(data_line))
		data_input[i]=data_line[0:200] # 设置为400除以2的值(即200)是取一半数据,因为是对称的
	data_input = np.log(data_input + 1)
	#data_input = data_input[::]
	return data_input
  • 该函数提取音频文件的时频图
import matplotlib.pyplot as plt
filepath = 'test.wav'

a = compute_fbank(filepath)
plt.imshow(a.T, origin = 'lower')
plt.show()

在这里插入图片描述

2. 数据处理

下载数据

thchs30: http://www.openslr.org/18/

2.1 生成音频文件和标签文件列表

考虑神经网络训练过程中接收的输入输出。首先需要batch_size内数据需要统一数据的shape。

格式为:[batch_size, time_step, feature_dim]

然而读取的每一个sample的时间轴长都不一样,所以需要对时间轴进行处理,选择batch内最长的那个时间为基准,进行padding。这样一个batch内的数据都相同,就能进行并行训练啦。

source_file = 'data_thchs30'

定义函数source_get,获取音频文件及标注文件列表

形如:

E:\Data\thchs30\data_thchs30\data\A11_0.wav.trn
E:\Data\thchs30\data_thchs30\data\A11_1.wav.trn
E:\Data\thchs30\data_thchs30\data\A11_10.wav.trn
E:\Data\thchs30\data_thchs30\data\A11_100.wav.trn
E:\Data\thchs30\data_thchs30\data\A11_102.wav.trn
E:\Data\thchs30\data_thchs30\data\A11_103.wav.trn
E:\Data\thchs30\data_thchs30\data\A11_104.wav.trn
E:\Data\thchs30\data_thchs30\data\A11_105.wav.trn
E:\Data\thchs30\data_thchs30\data\A11_106.wav.trn
E:\Data\thchs30\data_thchs30\data\A11_107.wav.trn
def source_get(source_file):
    train_file = source_file + '/data'
    label_lst = []
    wav_lst = []
    for root, dirs, files in os.walk(train_file):
        for file in files:
            if file.endswith('.wav') or file.endswith('.WAV'):
                wav_file = os.sep.join([root, file])
                label_file = wav_file + '.trn'
                wav_lst.append(wav_file)
                label_lst.append(label_file)
            
    return label_lst, wav_lst

label_lst, wav_lst = source_get(source_file)

print(label_lst[:10])
print(wav_lst[:10])
['data_thchs30/data/A23_73.wav.trn', 'data_thchs30/data/C4_681.wav.trn', 'data_thchs30/data/D12_793.wav.trn', 'data_thchs30/data/A19_137.wav.trn', 'data_thchs30/data/D11_898.wav.trn', 'data_thchs30/data/B33_491.wav.trn', 'data_thchs30/data/C7_546.wav.trn', 'data_thchs30/data/C32_671.wav.trn', 'data_thchs30/data/D32_817.wav.trn', 'data_thchs30/data/A32_115.wav.trn']
['data_thchs30/data/A23_73.wav', 'data_thchs30/data/C4_681.wav', 'data_thchs30/data/D12_793.wav', 'data_thchs30/data/A19_137.wav', 'data_thchs30/data/D11_898.wav', 'data_thchs30/data/B33_491.wav', 'data_thchs30/data/C7_546.wav', 'data_thchs30/data/C32_671.wav', 'data_thchs30/data/D32_817.wav', 'data_thchs30/data/A32_115.wav']

确认相同id对应的音频文件和标签文件相同

for i in range(10000):
    wavname = (wav_lst[i].split('/')[-1]).split('.')[0]
    labelname = (label_lst[i].split('/')[-1]).split('.')[0]
    if wavname != labelname:
        print('error')

2.2 label数据处理

定义函数read_label读取音频文件对应的拼音label

def read_label(label_file):
    with open(label_file, 'r', encoding='utf8') as f:
        data = f.readlines()
        return data[1]

print(read_label(label_lst[0]))

def gen_label_data(label_lst):
    label_data = []
    for label_file in label_lst:
        pny = read_label(label_file)
        label_data.append(pny.strip('\n'))
    return label_data

label_data = gen_label_data(label_lst)
print(len(label_data))
zhe4 ci4 quan2 guo2 qing1 nian2 pai2 qiu2 lian2 sai4 gong4 she4 tian1 jin1 zhou1 shan1 wu3 han4 san1 ge5 sai4 qu1 mei3 ge5 sai4 qu1 de5 qian2 liang3 ming2 jiang4 can1 jia1 fu4 sai4

13388

为label建立拼音到id的映射,即词典

def mk_vocab(label_data):
    vocab = []
    for line in label_data:
        line = line.split(' ')
        for pny in line:
            if pny not in vocab:
                vocab.append(pny)
    vocab.append('_')
    return vocab

vocab = mk_vocab(label_data)
print(len(vocab))
1209

有了词典就能将读取到的label映射到对应的id

def word2id(line, vocab):
    return [vocab.index(pny) for pny in line.split(' ')]

label_id = word2id(label_data[0], vocab)
print(label_data[0])
print(label_id)
zhe4 ci4 quan2 guo2 qing1 nian2 pai2 qiu2 lian2 sai4 gong4 she4 tian1 jin1 zhou1 shan1 wu3 han4 san1 ge5 sai4 qu1 mei3 ge5 sai4 qu1 de5 qian2 liang3 ming2 jiang4 can1 jia1 fu4 sai4
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 9, 20, 21, 19, 9, 20, 22, 23, 24, 25, 26, 27, 28, 29, 9]

总结:

我们提取出了每个音频文件对应的拼音标签label_data,通过索引就可以获得该索引的标签。

也生成了对应的拼音词典.由此词典,我们可以映射拼音标签为id序列。

输出:

  • vocab
  • label_data
print(vocab[:15])
print(label_data[10])
print(word2id(label_data[10], vocab))
['zhe4', 'ci4', 'quan2', 'guo2', 'qing1', 'nian2', 'pai2', 'qiu2', 'lian2', 'sai4', 'gong4', 'she4', 'tian1', 'jin1', 'zhou1']
can1 jin1 shi4 ca1 zui3 he2 shou2 zhi3 de5 bei1 bian1 qing3 yong4 can1 zhi3 ca1 shi4 lian3 shang4 de5 han4 huo4 zhan1 shang5 de5 shui3 zhi1 qing3 yong4 zi4 ji3 de5 shou3 juan4 ca1 diao4
[27, 13, 199, 200, 201, 63, 202, 203, 22, 204, 205, 206, 207, 27, 203, 200, 199, 208, 120, 22, 17, 209, 210, 211, 22, 31, 212, 206, 207, 213, 214, 22, 215, 216, 200, 217]

2.3 音频数据处理

音频数据处理,只需要获得对应的音频文件名,然后提取所需时频图即可。

其中compute_fbank时频转化的函数在前面已经定义好了。

fbank = compute_fbank(wav_lst[0])
print(fbank.shape)
(1026, 200)
plt.imshow(fbank.T, origin = 'lower')
plt.show()

在这里插入图片描述

由于声学模型网络结构原因(3个maxpooling层),我们的音频数据的每个维度需要能够被8整除。

fbank = fbank[:fbank.shape[0]//8*8, :]
print(fbank.shape)
(1024, 200)

总结:

  • 对音频数据进行时频转换
  • 转换后的数据需要各个维度能够被8整除

2.4 数据生成器

确定batch_size和batch_num

total_nums = 10000
batch_size = 4
batch_num = total_nums // batch_size

shuffle

打乱数据的顺序,我们通过查询乱序的索引值,来确定训练数据的顺序

from random import shuffle
shuffle_list = [i for i in range(10000)]
shuffle(shuffle_list)

generator

batch_size的信号时频图和标签数据,存放到两个list中去

def get_batch(batch_size, shuffle_list, wav_lst, label_data, vocab):
    for i in range(10000//batch_size):
        wav_data_lst = []
        label_data_lst = []
        begin = i * batch_size
        end = begin + batch_size
        sub_list = shuffle_list[begin:end]
        for index in sub_list:
            fbank = compute_fbank(wav_lst[index])
            fbank = fbank[:fbank.shape[0] // 8 * 8, :]
            label = word2id(label_data[index], vocab)
            wav_data_lst.append(fbank)
            label_data_lst.append(label)
        yield wav_data_lst, label_data_lst

batch = get_batch(4, shuffle_list, wav_lst, label_data, vocab)

wav_data_lst, label_data_lst = next(batch)
for wav_data in wav_data_lst:
    print(wav_data.shape)
for label_data in label_data_lst:
    print(label_data)
(1272, 200)
(792, 200)
(872, 200)
(928, 200)
[27, 13, 199, 200, 201, 63, 202, 203, 22, 204, 205, 206, 207, 27, 203, 200, 199, 208, 120, 22, 17, 209, 210, 211, 22, 31, 212, 206, 207, 213, 214, 22, 215, 216, 200, 217]
[731, 5, 353, 301, 344, 41, 36, 212, 250, 103, 246, 199, 22, 766, 16, 380, 243, 411, 420, 9, 206, 259, 435, 244, 249, 113, 245, 344, 41, 188, 70]
[0, 674, 444, 316, 20, 22, 103, 117, 199, 392, 376, 512, 519, 118, 438, 22, 328, 308, 58, 63, 1065, 198, 624, 472, 232, 159, 163, 199, 392, 376, 512, 519, 173, 22]
[39, 51, 393, 471, 537, 198, 58, 535, 632, 100, 655, 63, 226, 488, 69, 376, 190, 409, 8, 349, 242, 93, 305, 1012, 369, 172, 166, 58, 156, 305, 179, 274, 44, 435]
lens = [len(wav) for wav in wav_data_lst]
print(max(lens))
print(lens)
1272
[1272, 792, 872, 928]

padding

然而,每一个batch_size内的数据有一个要求,就是需要构成成一个tensorflow块,这就要求每个样本数据形式是一样的。
除此之外,ctc需要获得的信息还有输入序列的长度。
这里输入序列经过卷积网络后,长度缩短了8倍,因此我们训练实际输入的数据为wav_len//8。

  • padding wav data
  • wav len // 8 (网络结构导致的)
def wav_padding(wav_data_lst):
    wav_lens = [len(data) for data in wav_data_lst]
    wav_max_len = max(wav_lens)
    wav_lens = np.array([leng//8 for leng in wav_lens])
    new_wav_data_lst = np.zeros((len(wav_data_lst), wav_max_len, 200, 1))
    for i in range(len(wav_data_lst)):
        new_wav_data_lst[i, :wav_data_lst[i].shape[0], :, 0] = wav_data_lst[i]
    return new_wav_data_lst, wav_lens

pad_wav_data_lst, wav_lens = wav_padding(wav_data_lst)
print(pad_wav_data_lst.shape)
print(wav_lens)
(4, 1272, 200, 1)
[159  99 109 116]

同样也要对label进行padding和长度获取,不同的是数据维度不同,且label的长度就是输入给ctc的长度,不需要额外处理

  • label padding
  • label len
def label_padding(label_data_lst):
    label_lens = np.array([len(label) for label in label_data_lst])
    max_label_len = max(label_lens)
    new_label_data_lst = np.zeros((len(label_data_lst), max_label_len))
    for i in range(len(label_data_lst)):
        new_label_data_lst[i][:len(label_data_lst[i])] = label_data_lst[i]
    return new_label_data_lst, label_lens

pad_label_data_lst, label_lens = label_padding(label_data_lst)
print(pad_label_data_lst.shape)
print(label_lens)
(4, 36)
[36 31 34 34]
  • 用于训练格式的数据生成器
def data_generator(batch_size, shuffle_list, wav_lst, label_data, vocab):
    for i in range(len(wav_lst)//batch_size):
        wav_data_lst = []
        label_data_lst = []
        begin = i * batch_size
        end = begin + batch_size
        sub_list = shuffle_list[begin:end]
        for index in sub_list:
            fbank = compute_fbank(wav_lst[index])
            pad_fbank = np.zeros((fbank.shape[0]//8*8+8, fbank.shape[1]))
            pad_fbank[:fbank.shape[0], :] = fbank
            label = word2id(label_data[index], vocab)
            wav_data_lst.append(pad_fbank)
            label_data_lst.append(label)
        pad_wav_data, input_length = wav_padding(wav_data_lst)
        pad_label_data, label_length = label_padding(label_data_lst)
        inputs = {'the_inputs': pad_wav_data,
                  'the_labels': pad_label_data,
                  'input_length': input_length,
                  'label_length': label_length,
                 }
        outputs = {'ctc': np.zeros(pad_wav_data.shape[0],)} 
        yield inputs, outputs

3. 模型搭建

训练输入为时频图,标签为对应的拼音标签,如下所示:

搭建语音识别模型,采用了 CNN+CTC 的结构。

在这里插入图片描述

import keras
from keras.layers import Input, Conv2D, BatchNormalization, MaxPooling2D
from keras.layers import Reshape, Dense, Lambda
from keras.optimizers import Adam
from keras import backend as K
from keras.models import Model
from keras.utils import multi_gpu_model
Using TensorFlow backend.

3.1 构建模型组件

  • 定义3*3的卷积层
def conv2d(size):
    return Conv2D(size, (3,3), use_bias=True, activation='relu',
        padding='same', kernel_initializer='he_normal')
  • 定义batch norm层
def norm(x):
    return BatchNormalization(axis=-1)(x)
  • 定义最大池化层,数据的后两维维度都减半
def maxpool(x):
    return MaxPooling2D(pool_size=(2,2), strides=None, padding="valid")(x)
  • dense层
def dense(units, activation="relu"):
    return Dense(units, activation=activation, use_bias=True,
        kernel_initializer='he_normal')
  • 由cnn + cnn + maxpool构成的组合
# x.shape=(none, none, none)
# output.shape = (1/2, 1/2, 1/2)
def cnn_cell(size, x, pool=True):
    x = norm(conv2d(size)(x))
    x = norm(conv2d(size)(x))
    if pool:
        x = maxpool(x)
    return x
  • 添加CTC损失函数,由backend引入

注意:CTC_batch_cost输入为:

  • labels 标签:[batch_size, l]
  • y_pred cnn网络的输出:[batch_size, t, vocab_size]
  • input_length 网络输出的长度:[batch_size]
  • label_length 标签的长度:[batch_size]
def ctc_lambda(args):
    labels, y_pred, input_length, label_length = args
    y_pred = y_pred[:, :, :]
    return K.ctc_batch_cost(labels, y_pred, input_length, label_length)

3.2 搭建cnn+dnn+ctc的声学模型

class Amodel():
    """docstring for Amodel."""
    def __init__(self, vocab_size):
        super(Amodel, self).__init__()
        self.vocab_size = vocab_size
        self._model_init()
        self._ctc_init()
        self.opt_init()

    def _model_init(self):
        self.inputs = Input(name='the_inputs', shape=(None, 200, 1))
        self.h1 = cnn_cell(32, self.inputs)
        self.h2 = cnn_cell(64, self.h1)
        self.h3 = cnn_cell(128, self.h2)
        self.h4 = cnn_cell(128, self.h3, pool=False)
        # 200 / 8 * 128 = 3200
        self.h6 = Reshape((-1, 3200))(self.h4)
        self.h7 = dense(256)(self.h6)
        self.outputs = dense(self.vocab_size, activation='softmax')(self.h7)
        self.model = Model(inputs=self.inputs, outputs=self.outputs)

    def _ctc_init(self):
        self.labels = Input(name='the_labels', shape=[None], dtype='float32')
        self.input_length = Input(name='input_length', shape=[1], dtype='int64')
        self.label_length = Input(name='label_length', shape=[1], dtype='int64')
        self.loss_out = Lambda(ctc_lambda, output_shape=(1,), name='ctc')\
            ([self.labels, self.outputs, self.input_length, self.label_length])
        self.ctc_model = Model(inputs=[self.labels, self.inputs,
            self.input_length, self.label_length], outputs=self.loss_out)

    def opt_init(self):
        opt = Adam(lr = 0.0008, beta_1 = 0.9, beta_2 = 0.999, decay = 0.01, epsilon = 10e-8)
        #self.ctc_model=multi_gpu_model(self.ctc_model,gpus=2)
        self.ctc_model.compile(loss={'ctc': lambda y_true, output: output}, optimizer=opt)

am = Amodel(1176)
am.ctc_model.summary()
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
the_inputs (InputLayer)         (None, None, 200, 1) 0                                            
__________________________________________________________________________________________________
conv2d_1 (Conv2D)               (None, None, 200, 32 320         the_inputs[0][0]                 
__________________________________________________________________________________________________
batch_normalization_1 (BatchNor (None, None, 200, 32 128         conv2d_1[0][0]                   
__________________________________________________________________________________________________
conv2d_2 (Conv2D)               (None, None, 200, 32 9248        batch_normalization_1[0][0]      
__________________________________________________________________________________________________
batch_normalization_2 (BatchNor (None, None, 200, 32 128         conv2d_2[0][0]                   
__________________________________________________________________________________________________
max_pooling2d_1 (MaxPooling2D)  (None, None, 100, 32 0           batch_normalization_2[0][0]      
__________________________________________________________________________________________________
conv2d_3 (Conv2D)               (None, None, 100, 64 18496       max_pooling2d_1[0][0]            
__________________________________________________________________________________________________
batch_normalization_3 (BatchNor (None, None, 100, 64 256         conv2d_3[0][0]                   
__________________________________________________________________________________________________
conv2d_4 (Conv2D)               (None, None, 100, 64 36928       batch_normalization_3[0][0]      
__________________________________________________________________________________________________
batch_normalization_4 (BatchNor (None, None, 100, 64 256         conv2d_4[0][0]                   
__________________________________________________________________________________________________
max_pooling2d_2 (MaxPooling2D)  (None, None, 50, 64) 0           batch_normalization_4[0][0]      
__________________________________________________________________________________________________
conv2d_5 (Conv2D)               (None, None, 50, 128 73856       max_pooling2d_2[0][0]            
__________________________________________________________________________________________________
batch_normalization_5 (BatchNor (None, None, 50, 128 512         conv2d_5[0][0]                   
__________________________________________________________________________________________________
conv2d_6 (Conv2D)               (None, None, 50, 128 147584      batch_normalization_5[0][0]      
__________________________________________________________________________________________________
batch_normalization_6 (BatchNor (None, None, 50, 128 512         conv2d_6[0][0]                   
__________________________________________________________________________________________________
max_pooling2d_3 (MaxPooling2D)  (None, None, 25, 128 0           batch_normalization_6[0][0]      
__________________________________________________________________________________________________
conv2d_7 (Conv2D)               (None, None, 25, 128 147584      max_pooling2d_3[0][0]            
__________________________________________________________________________________________________
batch_normalization_7 (BatchNor (None, None, 25, 128 512         conv2d_7[0][0]                   
__________________________________________________________________________________________________
conv2d_8 (Conv2D)               (None, None, 25, 128 147584      batch_normalization_7[0][0]      
__________________________________________________________________________________________________
batch_normalization_8 (BatchNor (None, None, 25, 128 512         conv2d_8[0][0]                   
__________________________________________________________________________________________________
reshape_1 (Reshape)             (None, None, 3200)   0           batch_normalization_8[0][0]      
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, None, 256)    819456      reshape_1[0][0]                  
__________________________________________________________________________________________________
the_labels (InputLayer)         (None, None)         0                                            
__________________________________________________________________________________________________
dense_2 (Dense)                 (None, None, 1176)   302232      dense_1[0][0]                    
__________________________________________________________________________________________________
input_length (InputLayer)       (None, 1)            0                                            
__________________________________________________________________________________________________
label_length (InputLayer)       (None, 1)            0                                            
__________________________________________________________________________________________________
ctc (Lambda)                    (None, 1)            0           the_labels[0][0]                 
                                                                 dense_2[0][0]                    
                                                                 input_length[0][0]               
                                                                 label_length[0][0]               
==================================================================================================
Total params: 1,706,104
Trainable params: 1,704,696
Non-trainable params: 1,408
__________________________________________________________________________________________________

4. 模型训练及推断

4.1 模型训练

这样训练所需的数据,就准备完毕了,接下来可以进行训练了。我们采用如下参数训练:

  • batch_size = 4

  • batch_num = 10000 // 4

  • epochs = 1

  • 准备训练数据,shuffle是为了打乱训练数据顺序

total_nums = 100
batch_size = 20
batch_num = total_nums // batch_size
epochs = 50
source_file = 'data_thchs30'
label_lst, wav_lst = source_get(source_file)
label_data = gen_label_data(label_lst[:100])
vocab = mk_vocab(label_data)
vocab_size = len(vocab)

print(vocab_size)

shuffle_list = [i for i in range(100)]

716
  • 使用fit_generator

  • 开始训练

am = Amodel(vocab_size)

for k in range(epochs):
    print('this is the', k+1, 'th epochs trainning !!!')
    #shuffle(shuffle_list)
    batch = data_generator(batch_size, shuffle_list, wav_lst, label_data, vocab)
    am.ctc_model.fit_generator(batch, steps_per_epoch=batch_num, epochs=1)
this is the 1 th epochs trainning !!!
Epoch 1/1
5/5 [==============================] - 30s 6s/step - loss: 422.8893
this is the 2 th epochs trainning !!!
.....

5/5 [==============================] - 7s 1s/step - loss: 0.4708
this is the 50 th epochs trainning !!!
Epoch 1/1
5/5 [==============================] - 7s 1s/step - loss: 0.4580

4.2 模型推断

  • 解码器
def decode_ctc(num_result, num2word):
	result = num_result[:, :, :]
	in_len = np.zeros((1), dtype = np.int32)
	in_len[0] = result.shape[1];
	r = K.ctc_decode(result, in_len, greedy = True, beam_width=10, top_paths=1)
	r1 = K.get_value(r[0][0])
	r1 = r1[0]
	text = []
	for i in r1:
		text.append(num2word[i])
	return r1, text
  • 模型识别结果解码
# 测试模型 predict(x, batch_size=None, verbose=0, steps=None)
batch = data_generator(1, shuffle_list, wav_lst, label_data, vocab)
for i in range(10):
  # 载入训练好的模型,并进行识别
  inputs, outputs = next(batch)
  x = inputs['the_inputs']
  y = inputs['the_labels'][0]
  result = am.model.predict(x, steps=1)
  # 将数字结果转化为文本结果
  result, text = decode_ctc(result, vocab)
  print('数字结果: ', result)
  print('文本结果:', text)
  print('原文结果:', [vocab[int(i)] for i in y])
数字结果:  [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19  9 20 21 19
  9 20 22 23 24 25 26 27 28 29  9]
文本结果: ['zhe4', 'ci4', 'quan2', 'guo2', 'qing1', 'nian2', 'pai2', 'qiu2', 'lian2', 'sai4', 'gong4', 'she4', 'tian1', 'jin1', 'zhou1', 'shan1', 'wu3', 'han4', 'san1', 'ge5', 'sai4', 'qu1', 'mei3', 'ge5', 'sai4', 'qu1', 'de5', 'qian2', 'liang3', 'ming2', 'jiang4', 'can1', 'jia1', 'fu4', 'sai4']
原文结果: ['zhe4', 'ci4', 'quan2', 'guo2', 'qing1', 'nian2', 'pai2', 'qiu2', 'lian2', 'sai4', 'gong4', 'she4', 'tian1', 'jin1', 'zhou1', 'shan1', 'wu3', 'han4', 'san1', 'ge5', 'sai4', 'qu1', 'mei3', 'ge5', 'sai4', 'qu1', 'de5', 'qian2', 'liang3', 'ming2', 'jiang4', 'can1', 'jia1', 'fu4', 'sai4']
数字结果:  [30 31 32 33 34 35 36 32 37 38 39 40 41 22 15 42 43 44 41 45 46 47 48  3
 39 49 50 51 52 42 53 54]
文本结果: ['xian1', 'shui3', 'yan2', 'zhi4', 'fei1', 'ma2', 'zu3', 'yan2', 'chang2', 'da2', 'shi2', 'hua2', 'li3', 'de5', 'shan1', 'ya2', 'dong4', 'xue2', 'li3', 'you3', 'chun1', 'qiu1', 'zhan4', 'guo2', 'shi2', 'qi1', 'gu3', 'yue4', 'zu2', 'ya2', 'mu4', 'qun2']
原文结果: ['xian1', 'shui3', 'yan2', 'zhi4', 'fei1', 'ma2', 'zu3', 'yan2', 'chang2', 'da2', 'shi2', 'hua2', 'li3', 'de5', 'shan1', 'ya2', 'dong4', 'xue2', 'li3', 'you3', 'chun1', 'qiu1', 'zhan4', 'guo2', 'shi2', 'qi1', 'gu3', 'yue4', 'zu2', 'ya2', 'mu4', 'qun2']
数字结果:  [55 56 57 11 58 18 59 60 22 61 62 63 64 62 65 66 57 11 58 67 18 59 60 68
 32 69 70 22  0 71 72 32 73 74 22 76]
文本结果: ['wo3', 'men5', 'pai1', 'she4', 'le5', 'san1', 'wang4', 'chong1', 'de5', 'yuan3', 'jing3', 'he2', 'jin4', 'jing3', 'te4', 'bie2', 'pai1', 'she4', 'le5', 'cong2', 'san1', 'wang4', 'chong1', 'shen1', 'yan2', 'er2', 'chu1', 'de5', 'zhe4', 'tiao2', 'wan1', 'yan2', 'ni2', 'ning4', 'de5', 'lu4']
原文结果: ['wo3', 'men5', 'pai1', 'she4', 'le5', 'san1', 'wang4', 'chong1', 'de5', 'yuan3', 'jing3', 'he2', 'jin4', 'jing3', 'te4', 'bie2', 'pai1', 'she4', 'le5', 'cong2', 'san1', 'wang4', 'chong1', 'shen1', 'yan2', 'er2', 'chu1', 'de5', 'zhe4', 'tiao2', 'wan1', 'yan2', 'ni2', 'ning4', 'de5', 'xiao3', 'lu4']
数字结果:  [77 78 79 80 81 82 83 82 84 79 83 79 84 82 82 80 85 79 79 82 10 86]
文本结果: ['bu2', 'qi4', 'ya3', 'bu4', 'bi4', 'su2', 'hua4', 'su2', 'wei2', 'ya3', 'hua4', 'ya3', 'wei2', 'su2', 'su2', 'bu4', 'shang1', 'ya3', 'ya3', 'su2', 'gong4', 'shang3']
原文结果: ['bu2', 'qi4', 'ya3', 'bu4', 'bi4', 'su2', 'hua4', 'su2', 'wei2', 'ya3', 'hua4', 'ya3', 'wei2', 'su2', 'su2', 'bu4', 'shang1', 'ya3', 'ya3', 'su2', 'gong4', 'shang3']
数字结果:  [ 87  13  88  25  89  90  91  92  93  90  94  95  96  97  98  99  84 100
  89 101 102  96 103 104 104  77 105 106 107 108 109  28 110 111]
文本结果: ['ru2', 'jin1', 'ta1', 'ming2', 'chuan2', 'si4', 'fang1', 'sheng1', 'bo1', 'si4', 'hai3', 'yang3', 'xie1', 'ji4', 'shu4', 'guang3', 'wei2', 'liu2', 'chuan2', 'you1', 'liang2', 'xie1', 'zhong3', 'yuan2', 'yuan2', 'bu2', 'duan4', 'shu1', 'song4', 'dao4', 'qian1', 'jia1', 'wan4', 'hu4']
原文结果: ['ru2', 'jin1', 'ta1', 'ming2', 'chuan2', 'si4', 'fang1', 'sheng1', 'bo1', 'si4', 'hai3', 'yang3', 'xie1', 'ji4', 'shu4', 'guang3', 'wei2', 'liu2', 'chuan2', 'you1', 'liang2', 'xie1', 'zhong3', 'yuan2', 'yuan2', 'bu2', 'duan4', 'shu1', 'song4', 'dao4', 'qian1', 'jia1', 'wan4', 'hu4']
数字结果:  [112 113 114  28  22 115 116 117 118 119 108  20 120 121 122 123  58 124
 125 126 127 128 129 130 130 131 132 133  88 134  11]
文本结果: ['yang2', 'dui4', 'zhang3', 'jia1', 'de5', 'er4', 'wa2', 'zi5', 'fa1', 'shao1', 'dao4', 'qu1', 'shang4', 'zhen2', 'suo3', 'kan4', 'le5', 'bing4', 'dai4', 'hui2', 'yi1', 'bao1', 'zhen1', 'yao4', 'yao4', 'yi4', 'qiong2', 'gei3', 'ta1', 'zhu4', 'she4']
原文结果: ['yang2', 'dui4', 'zhang3', 'jia1', 'de5', 'er4', 'wa2', 'zi5', 'fa1', 'shao1', 'dao4', 'qu1', 'shang4', 'zhen2', 'suo3', 'kan4', 'le5', 'bing4', 'dai4', 'hui2', 'yi1', 'bao1', 'zhen1', 'yao4', 'yao4', 'yi4', 'qiong2', 'gei3', 'ta1', 'zhu4', 'she4']
数字结果:  [135  89 136 112 137 138 139 112  14 123 132 140 141 142 143 144  39 145
 146 143 144 147 148 149  37 119 150 151 152 118 153 154]
文本结果: ['xiang1', 'chuan2', 'sui2', 'yang2', 'di4', 'nan2', 'xia4', 'yang2', 'zhou1', 'kan4', 'qiong2', 'hua1', 'tu2', 'jing1', 'huai2', 'yin1', 'shi2', 'wen2', 'de2', 'huai2', 'yin1', 'pao2', 'chu2', 'shan4', 'chang2', 'shao1', 'yu2', 'nai3', 'tu1', 'fa1', 'qi2', 'xiang3']
原文结果: ['xiang1', 'chuan2', 'sui2', 'yang2', 'di4', 'nan2', 'xia4', 'yang2', 'zhou1', 'kan4', 'qiong2', 'hua1', 'tu2', 'jing1', 'huai2', 'yin1', 'shi2', 'wen2', 'de2', 'huai2', 'yin1', 'pao2', 'chu2', 'shan4', 'chang2', 'shao1', 'yu2', 'nai3', 'tu1', 'fa1', 'qi2', 'xiang3']
数字结果:  [ 87  63 155 156 157  69 158 159  22  33 160 107 161 162 163 155  70  58
 164 165  51  22 166 167 168 169 170 171 172 173 171 106 174]
文本结果: ['ru2', 'he2', 'ti2', 'gao1', 'shao4', 'er2', 'du2', 'wu4', 'de5', 'zhi4', 'liang4', 'song4', 'qing4', 'ling2', 'ye3', 'ti2', 'chu1', 'le5', 'hen3', 'zhuo2', 'yue4', 'de5', 'jian4', 'jie3', 'na4', 'jiu4', 'shi5', 'zhua1', 'chuang4', 'zuo4', 'zhua1', 'shu1', 'gao3']
原文结果: ['ru2', 'he2', 'ti2', 'gao1', 'shao4', 'er2', 'du2', 'wu4', 'de5', 'zhi4', 'liang4', 'song4', 'qing4', 'ling2', 'ye3', 'ti2', 'chu1', 'le5', 'hen3', 'zhuo2', 'yue4', 'de5', 'jian4', 'jie3', 'na4', 'jiu4', 'shi5', 'zhua1', 'chuang4', 'zuo4', 'zhua1', 'shu1', 'gao3']
数字结果:  [ 88 153 120 175 138 176  10 177 178 179 137  22 180 160   3 181  18 182
 183 184 185 127 185 118 186  22 187 188 189  43 179  78]
文本结果: ['ta1', 'qi2', 'shang4', 'yun2', 'nan2', 'cheng2', 'gong4', 'xun4', 'lian4', 'ji1', 'di4', 'de5', 'yi2', 'liang4', 'guo2', 'chan3', 'san1', 'lun2', 'mo2', 'tuo2', 'rou2', 'yi1', 'rou2', 'fa1', 'hong2', 'de5', 'shuang1', 'yan3', 'qi3', 'dong4', 'ji1', 'qi4']
原文结果: ['ta1', 'qi2', 'shang4', 'yun2', 'nan2', 'cheng2', 'gong4', 'xun4', 'lian4', 'ji1', 'di4', 'de5', 'yi2', 'liang4', 'guo2', 'chan3', 'san1', 'lun2', 'mo2', 'tuo2', 'rou2', 'yi1', 'rou2', 'fa1', 'hong2', 'de5', 'shuang1', 'yan3', 'qi3', 'dong4', 'ji1', 'qi4']
数字结果:  [190  75   5 173  83  22  65 191 192 193 194 153  83 195  20  66 150 145
 196  83  63   5  83 197 198  79  82  10  86]
文本结果: ['ma3', 'xiao3', 'nian2', 'zuo4', 'hua4', 'de5', 'te4', 'zheng1', 'yu3', 'shen2', 'yun4', 'qi2', 'hua4', 'feng1', 'qu1', 'bie2', 'yu2', 'wen2', 'ren2', 'hua4', 'he2', 'nian2', 'hua4', 'ke3', 'wei4', 'ya3', 'su2', 'gong4', 'shang3']
原文结果: ['ma3', 'xiao3', 'nian2', 'zuo4', 'hua4', 'de5', 'te4', 'zheng1', 'yu3', 'shen2', 'yun4', 'qi2', 'hua4', 'feng1', 'qu1', 'bie2', 'yu2', 'wen2', 'ren2', 'hua4', 'he2', 'nian2', 'hua4', 'ke3', 'wei4', 'ya3', 'su2', 'gong4', 'shang3']

转载请注明出处:https://blog.csdn.net/chinatelecom08

2017-09-08 22:00:11 qq_37572875 阅读数 15540
  • C++语音识别开篇

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

    5921 人正在学习 去看看 杨波

0 语音识别概述 1
1 语音识别的算法 2
1.1.1 DNN-HMM 2
1.1.2 RNN-CTC 3
1.1.4FSMN 3
1.1.5 LSTM-DNN电话交谈语音识别 3
1.1.6Android科大讯飞语音识别源码及API下载 3
2. 语音识别的应用场景 4
2.1语音识别的智能家居框架 4
2.2移动端的使用 5
2.3内容监管上的运用 6
2.3.1 语音识别技术应用之音频切分和分类技术 6
2.3.2 语音识别技术应用之音频模板匹配技术 6
2.3.3 语音识别技术应用之节目的自动发现技术 7
2.4 语音导航系统 7
2.4.1 语音导航系统构架 7
2.5 医疗领域 9
2.6 在社交方面的运用 9
3 语音识别数据集 11
4 语音识别行业分析 12
4.1 智能语音技术取得重大突破,商业化落地成为可能 12
4.2 智能车载、智能家居及可穿戴设备风潮的兴起加速语音技术落地 13
4.3科技巨头,初创公司纷纷从不同维度布局相关产业链 14
4.4 面向物联网的智能语音产业链的形成将引起商业模式的变化 16

0 语音识别概述

研究进程:
http://pan.baidu.com/s/1jHI22DS
算法演替:
https://www.leiphone.com/news/201608/4HJoePG2oQfGpoj2.html
基于深度学习的语音识别应用研究:
http://pan.baidu.com/s/1mhFG7xu
CNN在语音识别上的应用:
http://www.52cs.org/?p=1870
百度CNN语音识别:
https://www.jiqizhixin.com/articles/2016-11-04-4

1 语音识别的算法

1.1.1 DNN-HMM
这里写图片描述
DNN-HMM模型
介绍:
http://blog.csdn.net/xmdxcsj/article/details/52760080
程序:
https://github.com/wenjiegroup/DNN-HMM/tree/master/Codes_packaging

1.1.2 RNN-CTC
http://weibo.com/1402400261/Cz5lomszF?type=comment#_rnd1504833793294

1.1.4FSMN
Python代码:
https://github.com/katsugeneration/tensor-fsmn/blob/master/ptb.py

1.1.5 LSTM-DNN电话交谈语音识别
http://pan.baidu.com/s/1eRC4ZdC
LSTM介绍以及程序实现:https://zybuluo.com/hanbingtao/note/581764

1.1.6Android科大讯飞语音识别源码及API下载
https://www.google.co.in/url?sa=t&rct=j&q=&esrc=s&source=web&cd=4&cad=rja&uact=8&ved=0ahUKEwj38KDZj5TWAhWCv1QKHZBvB2QQFgg3MAM&url=http%3A%2F%2Fdditblog.com%2Fitshare_359.html&usg=AFQjCNG5tTtXuKWhNIxoqWUPxaJCKK1O9A

2.语音识别的应用场景

2.1语音识别的智能家居框架

本系统由软件和硬件两部分组成, 如图 2所示.软件部分又分为云端和嵌入式客户端. 云端和客户端各自集成了几个主要模块, 分别实现不同的功能
这里写图片描述

图2 系统架构模型
云端软件运行在 Linux 上, 它包含声学模型、语音模型、语料库、CMU Sphinx 工具包、Java 虚拟机. 云端主要功能是接受客户端发送的语音文件转化成文本文件返回, 应用程序模块全部使用 Java 开发, 调用
CMU Sphinx 提供的类库. 主要功能包含语音识别算法和语义转换模块, 它被部署在 Java 虚拟机上. 语音识别算法的主要过程有: 语音输入、预处理、特征提取、模型匹配、输出结果. 首先必须使用 CMU Sphinx的训练工具以特定声学模型为基础对语料库获取匹配的 MFCC 特征数据, 然后使用 MAP 和 MLLR 自适应技术来改进原来的声学模型。

2.2移动端的使用

随着移动互联网技术的不断发展,尤其是移动终端的小型化、多样化变化趋势,语音识别作为区别于键盘、触屏的人机交互手段之一,在需要解放双手的环境下、对于双手或视觉残障人士、对于无法通过触觉控制的微型设备都具有独特的优势。随着语音识别算法模型、自适应性的加强,相信在未来很长一段时间内,语音识别系统的应用将更加广泛与深入,更多丰富的移动终端语音识别产品将步入人们的日常生活。
就算对于正常人来说,例如寒冷的冬天,有无数次需要用手机却死活不想伸手。打电话,发微信,查路线,叫车,这些如果都可以用一个可穿戴设备通过语音控制实现,那该多好啊。目前出门问问团队以做出搭载 Moto 360 的智能手表操作系统Ticwear,可以实现直接语音控制滴滴打车。
早在一年前,Intel 就开发出可穿戴设备原型 Jarvis,可戴在耳朵上之后连入手机,以此实现听懂主人发出的指令、给予语音反馈的功能,充当类似 Siri 的个人语音助手角色

2.3内容监管上的运用

2.3.1 语音识别技术应用之音频切分和分类技术
音频切分和分类技术的应用范围非常广,以语音识别和关键词处理广播电视音频信息为例,首先要做的就是要打点切分音频打点切分的时候可以利用静音检测方法进行,静音检测法在定位方面确性更高,可以为之后的音频分类奠定基础。在音频打点切分完成后,将切分得到的各音频片段加以分类,使之后的音频处理有据可循。

2.3.2 语音识别技术应用之音频模板匹配技术
知道节目的片头曲或者片尾曲,则可以利用音频模板匹配技术对节目(片段)进行自动打点和分割。在压缩及信号传输的影响下,音频流与固定模板之间会产生巨大差别,而解决鲁棒性是其核心所在,通过基于多频带能量相对比率的特征提取方法,利用各时刻所对应的各个频带的能量分布趋势相对稳定这一特性,解决因为音频扭曲造成不稳定的问题。

2.3.3 语音识别技术应用之节目的自动发现技术
为了更好地进行本次研究,下面笔者将以广告识别作为样本,利用音频重复性检测获取新广告片段,具体内容概括如下:首先,因为针对的是自动发现未知新节目和广告而设计的,所以在实际过程中需要将待处理数据从已知模板中去除掉,以便能够减小计算量;其次,在进行重复候选位置的定位时,通过基于音频向量空间模型的快速音频搜索算法进行定位,但在具体过程中,因为会召回一些错误片段,所以有必要进行过滤处理;再有,利用基于音频指纹的搜索确认,用音频向量空间模型检测出来的重复片段,这样检测出的结果准确性更高,进行重复候选确认,进而检测出误报片段。
通过上述几个步骤的操作,余下的片段均是重复片段,既有广告内容的重复部分,也有新闻或者电视节目中的重复部分,然后利用图像帧变化率这一特征进行区分,将广告重复部分之外的内容去除。

2.4 语音导航系统

2.4.1 语音导航系统构架
这里写图片描述

1)客户通过手机或者固话,利用排队机接入呼叫中心系统,在 CTI 和 IVR 的控制下,当用户需要语音导航业务时,通过呼叫平台实现话务接入,平台记录下的原始语音文本,并进行播报用户确认无误后,将该文件作为语音识别引擎的输入;
2)原始的语音文件信息经过语音识别模块,分别经过特征提取、端点检测、去燥处理等语音识别预处理技术,经过处理过的较为干净的语音文件在经过离线解码、在线解码、置信度等处理,转出成自然语言文本信息,并将原始文件信息、原始语音信息、语音特征信息存入文本 / 语音语库中。
3)将自然语言文本信息经过自然语言处理,分别经过模式匹配、语法分析、语义解析、语义搜索、上下文管理、预测等技术处理,将自然语言文本信息转换成计算机能识别的语音信息作为输出物。
4)并进行业务需求的分析,为自然语言处理引擎提供关键数据输入。

2.5 医疗领域

不仅是简单的通过智能手表追踪运动情况和心率,还有直接根据人的身体状况匹配相应的服务如合适的餐厅或食物等,当然这些大多是基于可穿戴设备的。另外还需要考虑到更多场景,诸如紧急语音求助,医患对话存档,呼叫中心的对话听写等。
由于医疗领域词汇库专业性强演变性弱,只要建立完整的数据库,就可以做到对疾病名称、药品名称相对精确的识别。国内已有的应用如病历夹与珍立拍,为医生提供一个安全存储病历资料的云空间,方便查找病例,支持语音搜索功能。

2.6 在社交方面的运用

A、熟人通讯方面,我们应该都见过这样的场景,出租车上司机们通过对讲平台互相勾兑、插科打诨。路上匆忙的低头族,很多都在回微信,而如果通过声控交互构建一个对讲平台,这个体验就完全不一样了,你不需要用眼和手也可以随时给某某捎去一段话,别人给你发来语音、声控交互会提示你是否接听,而如果这个交互可以通过耳麦自动识别微小的语音(并根据接听者情况适度放大),那么以后走在路上就可以轻松而不违和地与人通话了,这个事情的意义在于将从另一个角度接管用户的关系链,形成大网优势。
B、陌生人社交方面,当下社交产品最大的痛点就是社交质量差、低效社交多、效率远远赶不上用户预期,一个突出表现就是搭讪无人理睬、理睬也在若干小时之后(所以人们为何喜欢直播,因为美女主播至少会说谢谢反馈下),但是语音沟通是一个更加强调即时性和真实性的场景,又不像视频那么需要“化妆和端着”,所以反而可能成为新的突破口。至于当下的语音社交平台为何多数做的不好,因为太像色情声讯台了!
C、兴趣推荐。如果选择值得一听的声音节目成本如此之高,那么一个比较好的办法就是基于兴趣的推荐来降低选择难度。比如喜马拉雅已经推出了“猜你喜欢”系统,可以通过深度学习、进行类似今日头条那样的个性化推荐。那么再进一步,如果以后这个推荐可以不需要通过眼睛完成呢,直接传来一个声音:“小喜根据你的爱好搜到了几个节目,下面念下标题,你感兴趣就喊要这个……”
D、时空触发。这个意思是,应该给更多的信息赋予时空属性,比如在某一时刻放出,或者在某一位置放出。举一个例子,你今天刚到一家商场,连上wifi,耳麦里立刻提醒你有最新的优惠活动信息、要不要听。你像即刻那样设置一些关注节点,比如某股又跌了,当这个消息到来,耳麦里立刻提醒你要不要听。你到达某个景点,耳边响起景点的典故。你晚上睡不着了,耳边响起周围人的声音,像不像《her》?
E、做强参与。同为视频,直播爆火的劲头远远强于当年的视频平台和短视频,这也释放了一个信号,用户并不满足于成为单向的内容接受者,他们也希望成为内容的参与者甚至再创作者,他们也希望得到更多的互动和回馈,来满足参与感、存在感和归属感,所以类似电台的互动直播很重要。

3 语音识别数据集

一2000 HUB5 English:仅包含英语的语音数据集,百度最近的论文《深度语音:扩展端对端语音识别》使用的是这个数据集。
地址:https://catalog.ldc.upenn.edu/LDC2002T43
二:LibriSpeech:包含文本和语音的有声读物数据集,由近500小时的多人朗读的清晰音频组成,且包含书籍的章节结构。
地址:http://www.openslr.org/12/
三:VoxForge:带口音的语音清洁数据集,对测试模型在不同重音或语调下的鲁棒性非常有用。
地址:http://www.voxforge.org/
四:TIMIT:英文语音识别数据集。
地址:https://catalog.ldc.upenn.edu/LDC93S1
五:CHIME:包含环境噪音的语音识别挑战赛数据集。该数据集包含真实、模拟和清洁的语音录音,具体来说,包括4个扬声器在4个有噪音环境下进行的将近9000次录音,模拟数据是将多个环境组合及在无噪音环境下记录的数据。
地址:http://spandh.dcs.shef.ac.uk/chime_challenge/data.html
六:TED-LIUM:TED Talk 的音频数据集,包含1495个TED演讲的录音及全文的文字稿。
地址:http://www-lium.univ-lemans.fr/en/content/ted-lium-corpus
七:ai_challenger_interpretation_train
地址:http://pan.baidu.com/s/1skIUjiH

4 语音识别行业分析

4.1 智能语音技术取得重大突破,商业化落地成为可能

◈智能语音技术是人工智能产业链上的关键一环
人工智能产业链主要分为三个层次。
底层是基础设施,包括芯片、模组、传感器,以及以大数据平台、云计算服务和网络运营商。这部分参与者以芯片厂商、科技巨头、运营商为主。
中间层主要是一些基础技术研究和服务提供商。包括深度学习/机器学习、计算机视觉、语音技术和自然语言处理以及机器人等领域。这一模块需要有海量的数据,强大的算法,以及高性能运算平台支撑。代表性企业主要有BAT、科大讯飞、微软、亚马逊、苹果、facebook等互联网巨头和国内一些具有较强科技实力的人工智能初创公司。
最上层是行业应用。大致分为2B和2C两个方向。2B的代表领域包括安防、金融、医疗、教育、呼叫中心等。2C的代表领域包括智能家居、可穿戴设备、无人驾驶、虚拟助理、家庭机器人等。相关代表性企业既包括互联网科技巨头,也包括一些初创厂商。
◈ 中国人工智能市场规模持续增长,智能语音将居于重要地位
◈ 智能语音技术成熟,商业化应用成为可能
深度学习、高性能运算平台和大数据是人工智能技术取得突破的核心助推力。深度学习端到端解决了特征表示与序列影射的问题,使得人工智能的性能得到了快速提升;而互联网时代海量的数据又不断为算法模型提供了训练材料,同时,云计算的兴起和高性能的运算平台为智能化提供了强大的运算能力和服务能力。
在语音识别率方面,百度、谷歌,科大讯飞等主流平台识别准确率均在96%以上,稳定的识别能力为语音技术的落地提供了可能。
◈ 商业场景落地的重要环节语音交互有了重大突破
与此同时,语音交互的核心环节也取得重大突破。语音识别环节突破了单点能力,从远场识别,到语音分析和语义理解有了重大突破,呈现一种整体的交互方案。

4.2 智能车载、智能家居及可穿戴设备风潮的兴起加速语音技术落地

◈ 智能语音市场整体处于启动期,智能车载,智能家居,智能可穿戴等垂直领域处于爆发前夜
◈ 智能车载市场前景广阔,预计五年内车联网渗透率超过50%,语音将成为车载系统标配
◈ 智能家电渗透率提高,智能家居市场蕴涵千亿市场规模,语音作为家居交互入口将大有所为

4.3科技巨头,初创公司纷纷从不同维度布局相关产业链

◈ 国外科技巨头:通过并购等手段,夯实核心技术,开放应用平台,在既有的产品和业务中实现AI first,扩展以AI为核心的生态系统
在技术层,科技巨头多推出算法平台吸引开发者,实现产品快速迭代,打造开发者生态链,形成行业标准。例如,谷歌通过一系列并购、开放平台的建立,软件硬件一体化来打造这个生态系统。
苹果在自身生态系统中相继推出面向可穿戴、家居、车载等领域的产品。亚马逊则基于自身电商生态业务,推出智能音箱,成功敲开了智能家居的大门。
◈ 谷歌:延续既有开放模式,打造开发者生态链,推出Google Home,试图建立物联网时代安卓系统
在谷歌的AI first战略中,一方面,推出人工智能学习系统平台TensorFlow,以吸引开发者,实现产品快速迭代,打造开发者生态链,形成行业标准;另一方面,推出谷歌家庭,试图建立物联网时代安卓系统。同时,将AI技术应用于其原有的产品中,比如Google输入法、Google 翻译、Google Now等,不断提升产品性能,优化用户体验。
◈ 苹果:基于智能硬件定标准、做平台、获数据 ,重视物联网时代生态控制权
与谷歌的开放生态不同,苹果依旧延续了其既有的封闭系统,瞄准物联网时代的生态控制权。同时,以硬件擅长的苹果这次仍从布局硬件起步,打造软硬件生态系统,依靠其广泛的OS系统用户,再基于已推广的OS系统拓展至物联网产业链。
◈ 国内互联网巨头:开放语音生态系统,以产业内合作的方式,将语音技术植入产品和或应用于相关业务场景,构建全产业生态链
在中国,以BAT等为代表的众多互联网巨头也纷纷开发智能语音市场。在语音生态系统方面,百度宣布语音识别技术及能力全面开放。腾讯、搜狗语音开放平台相继上线。
◈ 百度:瞄准人工智能战场,对外开放语音生态系统,对内在自身产品业务中实现AI First
◈ 国内智能语音公司:依托原有优势,从单一智能语音技术商转型全方位人工智能技术服务商
◈ 科大讯飞:传统优势明显,未来将更注重通用人工智能技术和平台级业务的拓展
科大讯飞长期在教育领域拥有绝对优势。除教育外,政府便民工程、呼叫中心和客服也是讯飞长期深耕的领域。
近两年讯飞的重点关注的领域开始向移动互联网和物联网转移。从业务布局层面看,先后发布讯飞云平台和人工智能交互平台AIUI,利用通用的人工智能技术和平台级业务,将语音识别、自然语言处理能力授权给第三方,或者与其他公司进行合作,并且开始向垂直领域拓展。
◈ 初创厂商:以垂直领域和细分场景为突破口,重点布局家居,车载和可穿戴设备
◈ 图灵机器人:定位于语义和认知计算的平台服务提供商,提供聊天机器人平台和机器人操作系统

4.4 面向物联网的智能语音产业链的形成将引起商业模式的变化

◈ 未来趋势:以语音为入口,建立以物联网为基础的商业模式
◈ 智能家居:以合适的入口级应用为载体,基于万物互联的标准,将技术与硬件结合,实现内容和服务的拓展
◈ 智能车载:车联网向纵深方向发展,硬件基础功能免费,基于用户数据的挖掘和增值服务将成为未来主要赢利点

转载自:
《新型工业化》开放式获取期刊:www.chinaxxgyh.com
语音识别技术在内容监管中的应用 郭莉亚 田书云 国家新闻出版广电总局 282 台
语音识别自适应算法在智能家居中的应用 蒋 泰, 张林军(桂林电子科技大学 计算机与信息安全学院, 桂林 541004
作者:辩手李慕阳
链接:https://www.zhihu.com/question/20128179/answer/109598639
来源:知乎
智能家居中语音识别系统的算法研究 郭莉莉,王 迪,魏惠芳 (沈阳城市建设学院,110167

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