机器学习很有趣Part6:怎样使用深度学习进行语音识别

还记得machine learning is fun吗?本文是该系列文章的第六部分,博主通俗细致地讲解了神经网络语音识别的整个过程, 是篇非常不错的入门级文章。


语音识别正闯入我们的生活。它内置于我们的手机、游戏机和智能手表。它甚至正在让我们的家庭变得自动化。只需要 50 美元,你就可以买到亚马逊的 Echo Dot——一个能允许你订购比萨饼,获得天气报告,甚至购买垃圾袋的魔法盒——只要你大声说:「Alexa,订购一个大披萨!」


1-z2BKMXtFGhsW6_NFfguecg.jpeg

Alexa, order a large pizza!


Echo Dot 在这个假期很受欢迎,亚马逊似乎没有 Echo Dot 的库存了。


语音识别已经存在数十年了,但是为什么现在才刚刚开始成为主流呢?原因是深度学习让语音识别足够准确,能够让语音识别在需要精心控制的环境之外中使用。


吴恩达早就预测,当语音识别的准确率从 95%达到 99%时,语音识别将成为人与计算机交互的主要方式。4%的准确性差距就相当于「难以容忍的不可靠」到「令人难以置信的有用性」之间的差异。由于有深度学习,我们正在走向顶峰。


让我们学习怎样利用深度学习进行语音识别!


机器学习并不总是黑箱


如果你知道神经网络机器翻译怎样工作,你可能会猜到:我们可以简单地将声音录音输入神经网络,然后训练神经网络来生成文本:


1-nJNxFmJaHxyJTtVFkhGTlg.png


这是用深度学习进行语音识别的核心,但我们还没有完全做到(至少在我写这篇文章的时候没做到——我打赌,在未来的几年我们可以做到)。


最大的问题是语音会随着速度变化。一个人可能很快地说出「Hello!」,而另外一个人可能会很缓慢说「heeeelllllllllllllooooo!」。这就产生了一个更长的声音文件和更多的数据。这两个声音文件本应该被识别为完全相同的文本「hello!」而事实证明,把各种长度的音频文件自动对齐到一个固定长度的文本是很难的一件事情。


为了解决这个问题,我们必须使用一些特殊的技巧和一些除了深度神经网络以外的额外处理。让我们看看它是如何工作的吧!


将声音转换成「字节」


语音识别的第一步是很显而易见的——我们需要将声波输入到计算机。


在第 3 章中(https://medium.com/@ageitgey/machine-learning-is-fun-part-3-deep-learning-and-convolutional-neural-networks-f40359318721#.tvzicp8bh),我们学习了如何把图像处理成数字序列,以便我们能直接将其输入进神经网络进行图像识别:


1-zY1qFB9aFfZz66YxxoI2aw.gif

图像仅是图片中每个像素值的数字编码数组


声音以波的形式传播。我们怎样将声波转换成数字呢?让我们使用我说的「hello」这个声音片段作为例子:


1-6_q1VIVJuavYa-9Uby_L-A.png

音频「Hello」的波形


声波是一维的。在每个时刻,它有单一的高度值对应。让我们放大声波的一个小部分,看看:


1-dqWhWUIzIyOLIqVReTBaiA.png


为了将这个声波转换成数值,我们只记录波在等间隔点的高度值:


1-dICZCcmEm_EWWx0yA6B3Cw.gif


声波采样


这被称为「采样」。我们采取每秒读取数千次的方式,并把声波在对应时刻的高度值记录下来。这基本上是一个未被压缩的.wav 音频文件。


「CD 音质」以 44.1kHZ(每秒读取 44100 次)进行采样。但是对于语音识别,16kHz 的采样频率足以覆盖人类语言的频率范围。


让我们用 16kHz 的方式对「Hello」音频采样,这是前 100 个样本:


1-BG4iFbx7qhb5v_JTr958PQ.png

每个数字代表声波在第 1/16000 间隔处时刻的高度值。


数字采样快速入门助手


你可能会认为:采样只是对原始声波的粗略近似,因为它只是间歇性读取数据,我们的读数之间有差距,所以我们丢失了数据,对吗?


1-KkWfr3a6HtRSZ8-4LUw0kg.png


数字采样能否完美重现原始声波?如何处理那些间距?


借鉴奈奎斯特定理 (Nyquist theorem),我们可以利用数学从间隔的采样中完美地重建原始声波——只要以我们希望得到的最高频率的两倍来进行采样就可以实现。


我提到这一点,是因为几乎每个人都会犯这个错误:认为使用更高的采样率总是能获得更好的音频质量。


采样声音数据的预处理


我们现在有一个数值数组,每个数值代表声波在间隔为 1 / 16,000 秒的时刻时的高度值(振幅)。


我们可以将这些数值输入神经网络。但是试图通过直接处理这些样本来识别语音模式是困难的。相反,我们可以通过对音频数据预处理来简化问题。


让我们将采样的音频以 20 毫秒时间段长进行分组。这是我们第一个 20 毫秒的样本音频,即我们的前 320 个样本。


1-_qUExEvllTKFhsrITxsa-A.png


将这些数值绘制为简单的线图,给出了对于 20 毫秒时间段的原始声波的粗略近似:


1-ZMxcyjNFqIOVzJRM9BCMWw.png


虽然这段录音只有 1/50 秒的时长,但即使这样短暂的时长也包含不同频率的声音。有低音、中音,甚至高音混在一起。但总的来说,这些不同频率的声音混合在一起构成了人类复杂的语音。


为了使这些数据更容易进行神经网络处理,我们将这复杂的声波分成不同部分。我们将一步步分离低音部分,下一个最低音部分,以此类推。然后通过将每个频带(从低到高)中的能量相加,我们就为各个类别(音调)的音频片段创建了一个指纹。


想象你有一段某人在钢琴上弹奏 C 大调的音频。这段音频是由三个音符组合而成的 - C,E 和 G – 他们混合在一起组成一个复杂的音频。我们想把这个复杂的音频分解成单独的音符:C,E 和 G。这和我们语音识别的想法一样。


我们可以使用数学中的傅里叶变换来完成。傅里叶变换将复杂的声波分解成简单的声波,一旦我们得到了这些简单声波,我们将每一个声波包含的能量加在一起。


最终结果是从低音(即低音音符)到高音,每个频率范围的重要程度。下面的每个数字表示在我们的 20 毫秒音频剪辑中每个 50Hz 频带中的能量:


1-2Vg8z3--moE-E7KybJlUPg.png

表中的每个数值表示每个 50Hz 频带中的能量


当你把它以图表形式画出,你更容易看出:


1-A4CxgdyqYd_nrF3e-7ETWA.png


你可以看出,我们的 20 毫秒的声音片段中有很多低频能量,高频能量较少。这是典型的「男性」的声音。


如果我们以每 20 毫秒的音频块重复这个过程,我们最终会得到一个频谱图(每一列从左到右都是一个 20 毫秒的块):


1-bhd7B-s-Qnds3HGV6LOo8A.png

「hello」声音片段的完整频谱图


频谱图很棒,因为你可以从音频数据中看到音符和其他音高模式。相比于原始声波,神经网络可以更加容易地从这种数据中找到规律。因此,这(频谱图)就是我们将实际输入到神经网络的数据表征方式。


从短声音中识别字符


有了易于处理音频形式,我们将把它输入到深度神经网络。神经网络的输入是 20 毫秒的音频块,对于每个小的音频切片,神经网络都会试图找出与声音对应的字母。


1-z1Nf0ES1YVUfdZZGW0PSdQ.png


我们将使用循环神经网络——即是具有能影响未来预测的记忆的神经网络。因为它预测的每个字母都将影响它对下一个字母的预测。例如,如果我们已经说出「HEL」,那么接下来我们很可能说出「LO」以说出「Hello」。我们不太可能会说像「XYZ」这种根本无法发音的词。因此,具有先前预测的记忆将有助于神经网络对未来进行更准确的预测。


当我们在神经网络上运行我们的整个音频剪辑(一次一块)后,我们最终将得到与每个音频块最可能对应的字符的一个映射。这是一个看起来像是我说」Hello」时的映射:


1-d1ktMdOnFOJRKKyjFP6sqQ.png


我们的神经网络可能预测到我说的是「HHHEE_LL_LLLOOO」,也可能是「HHHUU_LL_LLLOOO」或甚至「AAAUU_LL_LLLOOO」。


我们用几个步骤来整理输出结果。首先,我们会用单个字符替换重复的的字符:


  • HHHEE_LL_LLLOOO becomes HE_L_LO


  • HHHUU_LL_LLLOOO becomes HU_L_LO


  • AAAUU_LL_LLLOOO becomes AU_L_LO


然后,我们将移除所有空白


  • HE_L_LO 变成 HELLO


  • HU_L_LO 变成 HULLO


  • AU_L_LO 变成 AULLO


这让我们得到三种可能的转录 -「Hello」,「Hullo」和「Aullo」。如果你大声说出这些单词,这些转录的声音都类似于「Hello」。因为它每次只预测一个字符,神经网络会得出一些试探性的转录。例如,如果你说「He would not go」,它可能会给一个可能转录「He wud net go」


技巧是将这些基于发音的预测与基于书写文本(书籍,新闻文章等)的大数据库的似然分数相结合。你抛出看起来最不可能是真的的转录,并保持转录看起来最现实。



在我们可能的转录「Hello」、「Hullo」和「Aullo」中,显然「Hello」在文本数据库中更频繁地出现(更不用说在我们原始的基于音频的训练数据中),因此可能是正确的。所以我们选择「Hello」作为我们的最后的转录。这就完成了!


等一下!


但是如果有人说「Hullo」那又怎么样?「Hullo」是一个有效的词。也许「Hello」是错误的转录!


1-YzVDel59VoKFmZDKhPE-cQ.jpeg


当然实际上可能有人说的是「Hullo」而不是「Hello」。但是这样的语音识别系统(基于美式英语训练)基本上不会将「Hullo」作为转录。相比」Hello「,用户不太可能说「Hullo」,即是你在说」Hullo「ullo,它也总是会认为你在说「Hello」,无论你发「U」的声音有多重。


试试看!如果你的手机设置为美式英语,尝试让你的手机的数字助理识别「Hullo」。你不能达到目标!它会拒绝!它总是会理解为「Hello」。


不识别「Hullo」是合理的,但有时你会发现令人讨厌的情况:你的手机就是不能理解你说的语句。这就是为什么这些语音识别模型总需要更多的数据训练来处理这些少数情况。


我能建立自己的语音识别系统吗?


机器学习最酷的事情之一就是它有时看起来十分简单。你得到一堆数据,将把它输入到机器学习算法当中去,然后就能神奇的得到一个运行在你的游戏笔记本电脑显卡上的世界级人工智能系统... 对吧?


有些情况下的确是这样,但是语音识别却并不如此简单。语音识别是一个难题,你必须克服无限的挑战:质量差的麦克风、背景噪声、混响和回声、口音变化等等。这些问题都需要呈现在你的训练数据中,以确保神经网络可以处理它们。


还有另一个例子:你知道当你在一个大房间里说话时,你会不自觉地提高你的音调以便掩盖噪音吗?人类在什么情况下都可以理解你,但神经网络需要特殊训练来处理这些情况。所以你需要得到人们在噪音中大声说话的训练数据!


要构建一个达到 Siri、Google Now!或 Alexa 等水平的语音识别系统,你需要得到大量的训练数据,如果没有雇佣成百上千的人为你记录数据,你很难做到。用户对低质量语音识别系统的容忍度很低,因此你不能吝啬语音数据。没有人想要一个只有 80% 的时间有效的语音识别系统。


像谷歌或亚马逊这样的公司,现实生活中记录的成千上万小时的口语音频,对他们来说就是「黄金」。这就是将他们世界级语音识别系统与你自己的系统拉开差距的法宝。在手机上免费使用 Google Now! 和 Siri 或是不收取转录费且售价 50 美元的 Alexa,都是为了让你尽可能地使用它们。你说的每句话都将被这些系统所记录,然后这些数据将被用于训练未来的语音识别算法。


不相信我?如果你有一部安装了 Google Now!的安卓手机,点击这里去收听你对它说过的每一句话:


1-lwfLuSOFH032tbttD52Evw.png


你可以通过 Alexa 在亚马逊上找到相同的东西。然而不幸的是,苹果手机并不允许你利用你的 Siri 语音数据。


所以,如果你正在寻找创业的想法,我不建议你建立自己的语音识别系统与 Google 竞争。相反,你应该找到一种能让人们将他们几个小时的录音给予你的方法。这种数据可以是你的产品。


学习更多


这个被用来处理不同长度音频的算法被称为 Connectionist Temporal Classification(CTC)。你可以阅读来自 2006 年的原始文章:

http://www.cs.toronto.edu/~graves/icml_2006.pdf。


百度的 Adam Coates 在湾区深度学习学校做了关于「用深度学习做语音识别」的精彩演讲。你可以在 YouTube 上观看这段视频(https://youtu.be/9dXiAecyJrY?t=13874,他的演讲从 3 分 51 秒开始)。强烈推荐。


原文链接:https://medium.com/@ageitgey/machine-learning-is-fun-part-6-how-to-do-speech-recognition-with-deep-learning-28293c162f7a#.34p9sntcc

工程机器学习语音识别入门应用
1
什么算法语音采样呢?