1. 背景
"Hey,Siri", 很好奇iPhone是如何从一堆嘈杂的声音中识别出这句对她的呼喊的?
当然大的来说,这是个语音识别问题,但是完全按照NLP(Neuro-Linguistic Programming)来处理,那未免在功耗和效率上都会产生极大的损耗和低效。于是最近花了几天时间,简单学习了几篇相关论文,大致了解了其基本的实现原理和思路。
2. 定义概念
2.1 语音唤醒 Small-footprint Keyword Spotting
"Hey,Siri"的实现依赖于:语音唤醒技术 Keyword Spotting,但因为是适用于移动设备和智能音响的场景,所以对内存占用和计算功耗都要求尽可能低量级,所以会有前缀Small-footprint。应用领域非常广泛,所有运用语音识别的场景,第一步就是实现语音唤醒。
其基本思路是:
- 定义好keyword(比如"OK Google", "Hey Siri", "Alexa"...), keyword的长度一般为3-5个音节,太短了,识别误差率太高,太长了,识别效率会降低,所以基本业内都在这个范围。
- 当听到用户的声音时,转化为音素数据,然后进行算法识别,如果识别正确,则会触发系统的唤醒。
补充:自动语音识别ASR并不是一个单纯的算法,而是是一个包含很多部分的复杂框架,其中有声学模型Acoustic model,语音模型Language model等等。虽然近年来基于神经网络的算法越来越流行,然而基于隐马尔可夫模型Hidden Markov Model(HMM)的方法依然是现在语音识别领域中的关键部分。这里从最基本的几个概念说起,介绍一下ASR算法。
声学模型:描述一种语言的基本单位被称为音素Phoneme,例如BRYAN这个词就可以看做是由B, R, AY, AX, N五个音素构成的。英语中貌似有50多个音素,可以用50几个HMM state来表示这些音素,这种表示方法就是context independent模型中的单音素monophone模式。然而语音没有图像识别那么简单,因为我们再说话的时候很多发音都是连在一起的,很难区分,所以一般用左中右三个HMM state来描述一个音素,也就是说BRYAN这个词中的R音素就变成了用B-R, R, R-AY三个HMM state来表示。这样BRYAN这个词根据上下文就需要15个state了,根据所有单词的上下文总共大概需要几千个HMM state,这种方式属于context dependent模型中的三音素triphone模式。这个HMM state的个数在各家语音识别系统中都不一样,是一个需要调的参数。所以声学模型就是如何设置HMM state,对于信号中的每一frame抽怎样的特征,然后用训练什么分类器。实际中一般都用MFCC特征加高斯混合模型分类器GMM。然而这两种都是很古老的技术,如非必须没必要看,要看也要看更好的基于神经网络的特征和分类器。
来源:https://zhuanlan.zhihu.com/p/22482625
2.2 评判参数:
大家都可以实现,那么用哪项指标来评判你技术的优良性,目前常见的通过下面几个指标:
- 召回率:被唤醒的次数中正确次数的比例(相当于准确率)
- 虚警率:被唤醒的次数中错误次数的比例 (虚惊一场,原来你叫的是"Hey,Sorry")
- 漏报率:应该唤醒但未被换新的概率 ("愣什么愣,叫你半天了都...")
- 实时率:响应效率 (受软硬件多方面影响,如音频解码效率,硬件层识别效率等)
- 功耗:这个不用说,当然是功耗越低越好了(早期苹果功耗做的不好,所以只有充电状态下,才能识别"Hey, Siri", 现在优化了很多)
3. 技术实现
目前业内常见的实现方案有两种,一种是基于语音解码的Keyword/Fille HMM方案,一种是基于神经网络的Deep KWS方案。第一种是传统思路的识别方案,第二种是在第一种的基础上,采用目前很火的深度学习方案。
3.1 HMM方案
第一种被称为基于隐马尔科夫模型的Keyword and Filler系统,这类系统的关键是上图中左侧的解码模块,它与语音识别器中的解码器类似,也是通过维特比算法Viterbi来获取到最优的路径,但是与语音识别中LVCSR(大规模词表语音识别)系统的区别在于解码网络具体的构建,语音识别中的解码网络包含所有词典中的词汇,而唤醒的解码网络如上图右侧包含了Keyword和Filler的途径,除了关键词以外的词汇都包含在Filler路径当中,不是每一个词都会有相应的路径,这样的网络会比语音识别的网络小很多,有针对性地对关键词进行解码,可选的路径就少了很多,解码的速度也会得到大幅度的提升。对于解码出来的候选再作一个判断,就完成这样一套技术方案的整体构架.
-- [From 陈梦喆(九耳). 语音唤醒技术]
3.2 Deep KWS方案
第二种系统不再采用解码这样一个步骤,直接是由端到端的模式,即输入是语音,输出直接是关键词。这样的系统包括三个部分:如上图,
第一步是特征的提取,
第二步通常是一个神经网络,它的输入是语音特征,输出是各个关键词和非关键词即Filler这样一个后验概率。
由于第二步的网络是以帧为单位输出后验值的,就需要第三步对后验值以一定的窗长进行平滑,平滑后的后验值如果超过一定的阈值会被认为是唤醒了。
-- [From 陈梦喆(九耳). 语音唤醒技术]
4. 论文学习
4.1 From Google:
4.1.1 SMALL-FOOTPRINT KEYWORD SPOTTING USING DEEP NEURAL NETWORKS - 2014 IEEE
该论文采用DNN方案实现了KWS系统,目前看过的论文里,介绍DNN KWS相对较早的一篇论文。
通过和HMM方案的对比,来证明DNN方案的优势所在。
具体实现方式为:特征提取层 + 深度神经网络(DNN)+ 后处理判别模型
细节可参考有位同学的学习笔记
SMALL-FOOTPRINT KEYWORD SPOTTING USING DEEP NEURAL NETWORKS学习摘要
4.1.2 Convolutional Neural Networks for Small-footprint Keyword Spotting - 2015 INTERSPEECH
- Google 基于CNN实现的算法,属于Deep KWS方案
- 评判标准:FRR (False Reject Rate), "漏警率", CNN的FRR比DNN的FRR提升了27%~44%.
- 限制了乘法的运算量,限制了参数的数量
- 心路历程: 很早以前大家使用HMM,后来2014年,Google使用了DNN的方案SMALL-FOOTPRINT KEYWORD SPOTTING USING DEEP NEURAL NETWORKS - 2014 IEEE,然后2014年有人使用CNN进行语音识别Deep Convolutional Neural Networks for large-scale speech tasks, 但是这种CNN架构对计算量要求比较大,而KWS方案对计算量要求有一定的限制,所以本论文中他们提出了优化了版本的CNN方案。
4.2 From Amazon:
4.2.1 Compressed time delay neural network for small-footprint keyword spotting - 2017 INTERSPEECH
- 这是基于HMM的算法
- 做了TDNN的优化:
- 从LVCSR获得Hidden的初始值(w,b)
- 降低计算量:子采样 + 使用奇异值分解
4.3 From Baidu:
4.3.1 Convolutional Recurrent Neural Networks for Small-Footprint Keyword Spotting - 2017 INTERSPEECH
- 又一个Deep KWS方案
- CRNN (Convolutional Recurrent Neural Networks): CNN+RNN,
- 流程:PCEN -> CNN -> BRNN -> DNN -> SoftMax
- RNN对信噪比大的场景很有帮助
4.4 From Apple:
4.4.1 Hey Siri: An On-device DNN-powered Voice Trigger for Apple’s Personal Assistant - 2017
4.4.2 Personalized Hey Siri - 2018
没找到Apple发的相关论文,只找到两篇Apple官方提供的文档,Apple对音频的识别是基于DNN模型实现的,但是他有2个DNN模型,首先会用一个计算量较小的模型进行预检,然后再用更加精确的Large DNN进行计算,语音识别后,在通过HMM Scorer计算得分,如果分数满足阈值要求,会触发Siri。但是如果不满足要求,系统也会进入几秒的敏感期,这个敏感期内,如果用户再次重复这个主题,那么会快速识别,这样降低了漏报率。
手表中使用的DNN模型只有一个,是介于Small DNN和Large DNN之间的模型。
5. 代码实现
5.1 代码来源
Tensorflow提供了一个简单词汇识别的demo:speech_commands
唤醒词: (yes,no,up,down,left,right,on,off,stop,go) + silence + unknown
5.2 模型说明
5.2.1 模型总览
Tensorflow提供了4种模型:single_fc
、conv
、low_latency_conv
、low_latency_svdf
if model_architecture == 'single_fc':
return create_single_fc_model(fingerprint_input, model_settings,
is_training)
elif model_architecture == 'conv':
return create_conv_model(fingerprint_input, model_settings, is_training)
elif model_architecture == 'low_latency_conv':
return create_low_latency_conv_model(fingerprint_input, model_settings,
is_training)
elif model_architecture == 'low_latency_svdf':
return create_low_latency_svdf_model(fingerprint_input, model_settings,
is_training, runtime_settings)
else:
raise Exception('model_architecture argument "' + model_architecture +
'" not recognized, should be one of "single_fc", "conv",' +
' "low_latency_conv, or "low_latency_svdf"')
5.2.2 single_fc
模型
是个很简单的一层模型,一般用于测试或者验证,跑起来很快,用于快速验证一些简单的想法或者参数。
5.2.3 CNN模型conv
和low_latency_conv
- 两个都是基本的CNN模型,实现了我们#4.1.2的论文 Convolutional Neural Networks for Small-footprint Keyword Spotting - 2015 INTERSPEECH,
-
conv
是基于"cnn-trad-fpool3",low_latency_conv
是基于"cnn-one-fstride4" - 从论文的结果来看,cnn-trad-fpool3是效果最好的:Pooling in Frequency且p = 3
def create_conv_model(fingerprint_input, model_settings, is_training):
"""
This is roughly the network labeled as 'cnn-trad-fpool3' in the
'Convolutional Neural Networks for Small-footprint Keyword Spotting' paper:
http://www.isca-speech.org/archive/interspeech_2015/papers/i15_1478.pdf
Here's the layout of the graph:
(fingerprint_input)
v
[Conv2D]<-(weights)
v
[BiasAdd]<-(bias)
v
[Relu]
v
[MaxPool]
v
[Conv2D]<-(weights)
v
[BiasAdd]<-(bias)
v
[Relu]
v
[MaxPool]
v
[MatMul]<-(weights)
v
[BiasAdd]<-(bias)
v
"""
def create_low_latency_conv_model(fingerprint_input, model_settings,
is_training):
"""Builds a convolutional model with low compute requirements.
This is roughly the network labeled as 'cnn-one-fstride4' in the
'Convolutional Neural Networks for Small-footprint Keyword Spotting' paper:
http://www.isca-speech.org/archive/interspeech_2015/papers/i15_1478.pdf
Here's the layout of the graph:
(fingerprint_input)
v
[Conv2D]<-(weights)
v
[BiasAdd]<-(bias)
v
[Relu]
v
[MatMul]<-(weights)
v
[BiasAdd]<-(bias)
v
[MatMul]<-(weights)
v
[BiasAdd]<-(bias)
v
[MatMul]<-(weights)
v
[BiasAdd]<-(bias)
v
"""
5.2.4 low_latency_svdf
模型
这是一个基于论文Compressing Deep Neural Networks using a Rank-Constrained Topology实现的模型,精度上低于CNN模型,但使用奇异值分解进行降维,使得计算的量级和参数都有很大的降低。在训练中,relu激活之后,会丢弃一些节点。
def create_low_latency_svdf_model(fingerprint_input, model_settings,
is_training, runtime_settings):
"""Builds an SVDF model with low compute requirements.
This is based in the topology presented in the 'Compressing Deep Neural
Networks using a Rank-Constrained Topology' paper:
https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43813.pdf
Here's the layout of the graph:
(fingerprint_input)
v
[SVDF]<-(weights)
v
[BiasAdd]<-(bias)
v
[Relu]
v
[MatMul]<-(weights)
v
[BiasAdd]<-(bias)
v
[MatMul]<-(weights)
v
[BiasAdd]<-(bias)
v
[MatMul]<-(weights)
v
[BiasAdd]<-(bias)
v
"""
6. 比赛
6.1 题目
学习了论文,看了代码,接下来可以练练手了。
Kaggle中有个KWS相关的比赛:
TensorFlow Speech Recognition Challenge
6.2 赛题说明
We might be on the verge of too many screens. It seems like everyday, new versions of common objects are “re-invented” with built-in wifi and bright touchscreens. A promising antidote to our screen addiction are voice interfaces.
But, for independent makers and entrepreneurs, it’s hard to build a simple speech detector using free, open data and code. Many voice recognition datasets require preprocessing before a neural network model can be built on them. To help with this, TensorFlow recently released the Speech Commands Datasets. It includes 65,000 one-second long utterances of 30 short words, by thousands of different people.
In this competition, you're challenged to use the Speech Commands Dataset to build an algorithm that understands simple spoken commands. By improving the recognition accuracy of open-sourced voice interface tools, we can improve product effectiveness and their accessibility
6.3 参赛选手的技术分享
某位排名50位左右的参赛者博客:My solutions for Google TensorFlow Speech Recognition Challenge
备注:如果还没参加比赛,建议先不要看这个博客了,先自己想想怎么实现。
7. 总结
Small-footprint Keyword Spotting技术,因为功耗和计算量的限制,所以不能像普通的语音识别那样进行大量的计算。在保证一定召回率和漏报率的前提下,尽可能的降低训练量和运算量是很必要的。这里只是很浅层的记录了一些KWS相关的论文,缺乏一些深度的思考和数学上的推演。唯有静下心来,去研究这些论文并将之代码实现才能真正掌握这些东西。
参考文献
- 论文解读:语音唤醒技术:small-footprint keyword spotting[EB/OL], 陈梦喆(九耳)
- Google的论文: Convolutional Neural Networks for Small-footprint Keyword Spotting
- Apple 关于Hey Siri的博客: Hey Siri: An On-device DNN-powered Voice Trigger for Apple’s Personal Assistant
- Tensorflow 的代码:https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/speech_commands