上一期,我们围绕智能语音助手的话题,与大家聊了聊声源分离的两种方法:基于麦克风阵列波束成形的方法和基于深度学习的掩模估计的方法。本期,我们将继续本文的最后一个话题,聊聊关于深度学习的语音识别。
本文共分三期:
1)音频算法快速原型试音;
2)声源分离与提取;
3)深度学习语音识别
Part 3
语音关键词识别
深度学习的语音识别,目前以家用智能音箱、语音导航等首当其冲。
语音操控,本来就是人与人沟通最便捷的方式,只是过去技术水平限制,被迫用按键、遥控器、触摸屏,而今语音操控已自然而然成了新一代的人机接口。所有空调、电视、净化器这所有家电,甚至各处的灯光,都可以方便的采用语音指令进行控制,是不是很美好。
很多小伙伴,可能一提到语音识别,第一反应就是深度学习。确实会用到深度学习不假,然而,想设计好实际工程化实现的语音识别模型,需要考虑的远不只是深度学习本身。工程化实现与在科研探索,最大的区别在于,科研只是单点突破即可,比如可以是仅仅优化某个损失函数改进某个层的算法,就可以发表论文,算作成果了。而工程化实现,其实是一个完整的链条,任何一个环节出问题,都无法得到满足工程化实现要求的产品。
如下图所示,实际的工程化实现,需要完成如下所示的从左到右四个阶段。
深度学习开发基本流程
首先要采集数据,不仅需要获得足够大的高质量样本集,并且如果是有监督的学习,那你的标注也需要足够的精确;接下来就是预处理和特诊提取,这个步骤对获得轻量化的模型,适合进行嵌入式低功耗、小型化设备进行产品工程化实现至关重要;接下来是模型训练和开发;最后还需要在嵌入式设备或者云端上,产品化实现我们的算法。
而之前我们开发人员的大多数精力,是不是基本都只关注在第三个阶段呢?我们模型的整体性能其实是由这个链条里四个阶段,整体决定的,而非单一环节。
这也就解释了,为什么很多时候,若模型精度欠佳,如果希望只在第三个阶段努力,即仅通过模型优化和超参调解,通常很难得到有效改善的。反而可能使模型变得复杂,得到一个臃肿不适合产品化的模型。
首先在音频采集阶段,就需要考虑到回声消除、去混叠、降噪等一系列的预处理算法,而且在准备数据时,还需要根据自己的实际需要和训练平台的情况,来选择合适算法对音频数据进行预处理,这里可能涉及采样率变换、感兴趣频带的提取,也可能涉及感兴趣特征的提取。
接下来,我们以语音指令识别为例【1】,介绍如何在 MATLAB 中,快速完成产品化的整个链条。
我们的目标是将识别以下的十个英文指令,将采用 Google 随如下论文一同刚发表的语音指令数据集。
首先,我们导入数据集,数据集通常会比较庞大,若同时加载很可能占用大量内存使运算卡顿。MATLAB 提供了一系列的 datastore,对数据集进行管理和操作,datastore 仅记录数据集的索引和标签,而只在需要时,才会去加载对应的样本。
如下所示,采用音频专用的 audioDatastore,自动把样本文件夹下的各个子文件夹中数据建立索引数据集,而后自动以每个子文件夹名字作为其中各样本的标签。
这里,其实 Google 提供了一个显然由高手,精心加工的高水准的音频指令数据集。
而你的实际工程中,通常采集到的原始数据还需要进行一系列的预处理,如前面提到的去回声、去混叠、降噪等一系列操作,通常还会有滤波、采样率变换,然后才会得到这样一个理想的数据集。这个部分恰恰是很多大牛都会重视去做,却很少谈及的。
敲黑板~划重点~高质量的数据集,才能产生高质量的模型呦。
Notes: 大多数实际的工程应用,都需要自己动手准备这个至关重要的数据集,音频样本的采集的质量与标签的质量,同样重要。这个过程是非常耗时费力的,往往需要人工一段一段的音频反复听,反复手工标注。MATLAB 提供了对应于音频和信号领域的快捷标注工具,Audio Labeler 和 Signal Labeler。请看以下操作视频,可以看到您可以自动标注,快捷准确的完成这个过程。
以上我们介绍了,导入了整个数据集和标注。接下来,我们把数据集分成训练集、验证集和测试集。
接下来我们讲选择用哪种网络进行指令识别。如图所示,是常见的两种对时间序列进行分类或者检测的网络,上面一种是借助卷积神经网络对二维图像的检测能力,所不同的是需要先将音频序列转换成时频图。
下面这种,采用的是 LSTM 长短周期记忆网络,虽然也可以直接把时间序列作为其输入,但通常效果欠佳。所以我们一般会在每一个时间拍,提取一个特征向量,把它作为 LSTM 网络的输入。
这里我们采用上面这种方法,即首先对信号进行时频变换,得到每个时间拍上的时频图作为特征,输入进后面的卷积神经网络。音频中有许多可用的特征,这里过去我们需要自己手写函数,选择提取哪些特征,这个过程经常需要反复尝试。目标是用尽量少的特征,来达到可以接受的模型精度。恰到好处的特征选择,可以使后序的神经网络模型搭建和调优,得以大大简化,轻量级网络即可达到惊艳的效果,并不是每个做得漂亮的项目,都需要在模型训练阶段,死磕超参优化的。
Notes:特征的选择,需要针对您的特定使用环境,巧妙选择,比如识别人类语音,则需要了解人耳对于语音的选择性,比如在几百赫兹以下,成线性分布,这部分其实是语音的主要传递信号的部分。从几百赫兹到 20K,成对数分布,而对其他频点的声音。而如果您要识别的是乐音,那么您最好花点时间了解十二平均律,以及对应的有效特征,如恒 Q 变换等。
这里MATLAB提供了一个专用的音频特征提取工具,即 audioFeatureExtractor。他把音频常见的特征都统一集成在一个模块,你只要按需求,选择即可使用。
特征提取时,因为需要提取特征的样本量很大,以滑动窗口逐帧计算特征,通常计算很耗时,这里我们采用了如下所示的并行计算方式进行加速。
MATLAB代码,仅需要使用关键词稍作修改,即可轻松扩展到多节点,并行执行,使我们的算法执行速度大幅提高。
如果您想利用 GPU 加速,却不想手写 CUDA 代码怎么办?Parallel Computing Toolbox 也可以支持无缝的使用底层的 GPU 加速。您也可以方便的使用 gpuArray 对数组声明,底层就会自动使用您的 GPU 进行加速。
上面代码中,numPar 即本机可访问的并行节点数,若 numPar=16,则特征提取的计算将被自动在底层分配到这 16 个节点上并行完成,大幅提高计算速度。你的代码只需把 for 循环,换成 parfor 循环。不必再硬着头皮去学习并行编程语言了,所有底层的 map-reduce、Hadoop 之类的繁文缛节,MATLAB 都会为你自动搞定。
接下来我们看一下,提取到的特征。
上图中上面一行是原音频波形,16000 个采样点,而下图中是其对应的时频图,可以看到横轴和纵轴的点数明显减少了,也就是特征提取起到了明显压缩数据量的作用。恰到好处的选择特征,不仅会大大提高识别精度,而且可以使后面的卷积神经网络只需要一个轻量级的模型,即可达到很理想的精度。这对于产品化实现至关重要。
准备好了训练用的时频图数据集,我们就可以着手搭建神经网络了,我们不必记住指令敲代码,而是可以直接使用如下的 Deep Network Designer 以拖拽模块和连接的方式,快速完成。
接下来,设置好训练参数后,我们开始对模型进行训练。只要指定训练环境,他会自动在底层使用你所指定的多核 CPU 或者 GPU 进行加速。
训练完成后,我们可以对训练结果,进行评估。得到如下的混淆矩阵。
那么我们还可以在 MATLAB 中,直接访问底层的麦克风,采集实时音频流,来测试我们的模型识别精度,请看下面的视频。
上边,我们实现的其实还只是一个算法原型,那么我们如果想在嵌入式硬件上,实际做一下硬件原型测试怎么办?难道还需要把所有算法都手工用底层代码敲出来吗?
显然不必如此,您可以用 MATLAB Coder 很方便的把这一整套算法(包含预处理、特征提取和深度学习模型),一起打包生成嵌入式处理器如 ARM,可运行的高性能 C++ 代码。在这个阶段,仍然保持快速的硬件原型测试和调试迭代的优势。
这个语音指令识别的案例,其对应的嵌入式硬件实现的 demo,我们也一并在 Shipping Demo 中提供了,感兴趣的童鞋可以找来试试看【2】。
简单总结
我们介绍了基于深度学习的语音识别在实际工程化实现时,需要完成如下所示的从左到右四个阶段。而之前我们中大多数注意力,往往只关注第三个阶段呢,然而实际上,我们模型的性能其实是由这个链条里四个阶段,整体决定的,而非单一环节。
深度学习开发基本流程
而 MATLAB 是面向工程化实现的平台,完整覆盖全部这四个阶段的内容。
首先要采集数据,不仅需要获得足够大的高质量样本集,并且也需要高质量的标签,这部分 MATLAB 提供了一系列能够快速自动完成标注 APP;接下来就是预处理和特诊提取,MATLAB 提供大量方便易用的信号处理和预处理的 APP,以及音频信号特征提取器,可以方便的尝试需要的预处理和特征提取;接下来是模型训练和开发;最后还支持嵌入式设备或者云端上,自动生成代码或者部署实现我们的算法。