Deep Learning Note: 5-13 语音识别

1. 语音识别

  在语音识别问题中,输入是一段语音的音频,输出是语音的文本。就像人类的耳朵不能直接处理声波,而是通过检测声音中不同频率的强度来拾取语音,语音识别的一个常见的预处理步骤是生成原始音频数据的频谱,如图 1 所示,将频谱数据交给算法进行处理。图 1 中下图所示的频谱中,横轴是时间,纵轴是频谱,颜色表示声音在该频率上的能量。

图 1

图 1

  语音识别系统层一度使用音素(Phoneme)这一人工设计的特征,音素指的是根据音节的发音动作来划分的最小语音单位,语音学家假设语音识别的最佳方式是将语音书写为音素的形式。而在端到端学习中,像音素这类人工设计的概念变得不再必要,我们可以让系统直接将输入的音频转换为文本。端到端学习需要大量的训练数据,训练数据包括音频数据和对应的文本。对于语音识别任务,典型的数据集通常要有 300 小时的数据;而对于学术研究,有 3000 小时的数据才比较合适;而对于商用的语音识别系统,通常使用了超过过 1 万甚至 10 万小时的数据来训练。

  对于语音识别任务,也可以使用前面介绍的 Attention 模型,如图 2 所示,模型的输入为语音数据的各个帧,输出为语音文本。

图 2

图 2

  另一种方法是使用 CTC(Connectionise Temporal Classification)代价函数,出自 Connectionist temporal classification: labelling unsegmented sequence data with recurrent neural networks 一文。网络结构如图 3 所示,这里为了简便只画了一个单向的 RNN,实际中通常会使用双向的 GRU 或 LSTM。

图 3

图 3

  注意图 3 所示网络的输入和输出具有相同的长度,而对于语音识别任务,输入的长度(Time Stamp)要远大于输出的长度。例如对于一段 10 秒 100 Hz 的语音,每秒有 100 个采样,则 10 秒共有 1000 个采样,网络有 1000 个输入;而网络的输出,即这 10 秒对应的文本会远小于 1000 个字母。

  例如对于如下的语音:

[code lang=java]the quick brown fox
[/code]

CTC 代价函数会让 RNN 输出如

[code lang=java]ttt_h_eee___ ___qqq__
[/code]

的结果,其中下划线是一个特殊的字符,称为空字符(Blank Character),这其实是前述语音开头的 “the q” 几个字母,输出文本时,将没有被空字符分割的重复字符压缩成一个,就可以得到语音对应的文本,即:

[code lang=java]the q
[/code]

2. 触发字检测

  触发字(Trigger Word)指的是用于唤醒智能设备的关键字,例如可以对着 iPhone 说 “Hey Siri” 来唤醒其上搭载的 Siri 助手。对触发字检测系统的研究仍处于快速发展阶段,目前并没有一个通用的最佳算法,一种实现方式如图 4 所示,将语音数据转换到频域后,提取特征 $x^{\lt t \gt}$,输入一个 RNN。

图 4

图 4

  触发字检测的一个问题是如何设置数据的标签 $y$。一种方法是,如果用户在 $t’$ 时刻说完了触发字(图 4 中蓝框),则设置 $y^{\lt t’ \gt} = 1$,而对于 $t < t’$ 时刻,设置 $y^{\lt t \gt} = 0$。这样设置的一个问题是训练集中会有很多样例的标签为 0,只有少量样例的标签为 1,非常不平衡。为了解决这个问题,可以在 $t’$ 时刻后的一段时间内都设置 $y^{\lt t \gt} = 1$,如图 5 所示。

图 5

图 5