模型的训练由数据驱动,有些数据是必须要准备的。为了让机器学会将语音转换为文本,首先需要给它提供大量的例子,即语音及其对应的文本,这是原始素材,也最能反映学习目的。这些数据的符号化和结构化则需要一些人类先验知识,包括语言知识和数字信号处理相关手段。
4.1数据准备
1)基本数据
run.sh 中的Bookmark: basic preparation对Thchs30 原始数据进行了形式上的处理,以适应 Kaldi 的需要。一个常规的有监督语音识别数据集必然包括一一对应的语音和文本, 说话人的信息有好处但非必要。Thchs30 经过初步处理后得到四种文本文件,可以直接打开查看(比如训练集放在data/train 下),这四个文件也是 Kaldi 的必需文件:
● wav.scp,每条语音的ID及其存储路径;
● text,每条语音的ID及其对应文本;
● utt2spk,每条语音的ID及其说话人ID;
● spk2utt,每个说话人的ID及其所说语音的所有ID,使用 utils/spk2utt_to_utt2spk.pl或utils/utt2spk_to_spk2utt.pl 可实现spk2utt和utt2spk的相关转换。
对于不同数据源或任务,可能需要另外准备一些文件,比如 segments 文件标记每个语音片段属于某条语音的哪一部分,文件格式形如“ ”,时间以秒计,extra●ct-segments读取此文件后对音频进行批量剪切并保存为 Kaldi 支持的格式(sox也可逐条切割音频);spk2gender 文件标明每个说话人的性别,用于性别识别;utt2lang 文件标明每条语音 ID 对应的语种 ID,用于语种识别。由于不同的数据集有着不同的编排,并没有统一的工具提取出以上文件。当根据某个数据集自行生成以上类别的文件并用sort排序后,可以使用utils/validate_data_dir.sh校验是否满足Kaldi需求,并使用utils/fix_data_dir.sh进行修复。根据数据校验和修复脚本也可侧面了解 Kaldi 支持的文件类型和格式。
utt2spk 和 spk2utt 是 Kaldi 处理所必须的,有时候如果不能提供说话人信息,可以“伪造”,比如每条语音的说话人 ID 直接使用这条语音的 ID,这对语音识别性能影响不大,但在做说话人识别任务时,显然务必要提供真实的说话人信息。此外,两个文件都需要按第一列排序,为保证二者顺序的总体一致性,通常句子 ID 的前缀设置为说话人 ID。
2)语言资料
语言知识方面,见Bookmark: language preparation,Kaldi 至少需要以下文件,存放于data/dict 下:
● lexicon.txt,发音词典,即每个词与其所对应的音素串,格式为“word phone1 phone2 phone3 ...”,中文韵母具有不同的音调,可添加后缀,例如“1”(一声)、“2”(二声)、“3”(三声)、“4”(四声)、“5”(轻声);
● lexiconp.txt,与lexicon.txt 作用相同,多了发音概率,是人工设置的先验假设,格式为“word pronunciation-probability phone1 ...”,可由系统通过 lexicon.txt 自动生成(此时所有词的概率相同),二者提供一个即可,lexiconp.txt 优先使用;
● silence_phones.txt,静音类音素,包括静音(sil 或者 SIL)、噪音、笑声等非语言直接相关的伪音素,同一行的音素是某一个音素的不同变体(重音、音调方面),故可共享决策树根;
● nonsilence_phones.txt,语言直接相关的真实音素,同一行的音素是某一个音素的不同变体(重音、音调方面),故可共享决策树根;
● optional_silence.txt,备用的静音类音素,一般直接来自 silence_phones.txt 中的sil或者SIL;
● extra_questions.txt,可为空,同一行的音素有着相同的重音或音调,与GMM训练中自动生成的“questions”一同用于决策树的生成。
对于同一种语言,基于新的数据集训练系统时,上述语言资料文件都可以直接移植过去复用。运行egs/wsj/s5/local/wsj_prepare_dict.sh可以瞥见如何利用 CMU 英语发音词典构建出其他所需文件,Thchs30 中文数据集提供了准备好的语言资料。发音词典应尽可能覆盖训练语料,且基于已有的音素表,可更改或扩充发音词典,以适用于不同的领域或场景。到此为止,Kaldi用于语音识别系统训练的数据都齐全了,后来的事便是Kaldi对这些数据的自动处理和使用。
在决策树的生成当中,nonsilence_phones.txt 倡“合”,extra_questions.txt 倡“分”, 然而前者中的一行如果由同一基音素衍生出来,具有不同的重音或音调,则在后者中常常处于不同的行,这时保留根源性,以前者为准。
Bookmark: language processing中 utils/prepare_lang.sh 对 data/dict 进行了处理,得到data/lang。选项“position_dependent_phones”指明是否使用位置相关的音素,即是否根据一个音素在词中的位置将其加上不同的后缀:“_B”(开头)、“_E”(结尾)、“_I”(中间)、“_S”(独立成词)。参数“”取自 lexicon.txt,后续处理中所有集外词(Out Of Vocabulary,OOV)都用它来代替。lang 中生成的文件:
● phones.txt,将所有音素一一映射为自然数,即音素 ID,引入“”(epsilon)、消歧(Disambiguation)符号“#n”(n 为自然数), 便于 FST 处理;
● words.txt,将词一一映射为自然数,即词ID,引入“”(epsilon)、消歧符号 “#0”、“”(句子起始处)、“”(句子结尾处),便于 FST 处理;
● oov.txt,oov.int,集外词的替代者(此处为)及其在words.txt 中的ID;
topo,各个音素HMM模型的拓扑图,第二章提过将一个音素(或三音素)表示成一个HMM,此文件确定了每个音素使用的HMM状态数以及转移概率,用于初始化单音素GMM-HMM,可根据需要自行进行修改(并用utils/validate_lang.pl校验),实验中静音音素用了5个状态,其他音素用了3个状态;
L.fst,L_disambig.fst,发音词典转换成的FST,即输入是音素,输出是词,两个 FST的区别在于后者考虑了消歧;
phones/,是dict/ 的拓展,内部文件均可以文本形式打开查看,后缀为 txt/int/csl 的同名文件之间是相互转换的,其中 context_indep.txt 标明了上下文无关建模的音素,通常为静音音素, wdisambig.txt/wdisambig_phones.int/wdisambig_words.int 分别标明了words.txt 引入的消歧符号(#0)及其在phones.txt 和words.txt 中的ID, roots.txt 定义了同一行音素的各个状态是否共享决策树的根以及是否拆分,对应的音素集则存放于sets.txt。
消歧是为了确保发音词典能够得到一个确定性的(Deterministic) WFST。 如果有些词对应的音素串是另一些词音素串的前缀,比如 good 的音素串是 goodness 的前半段音素串,需要在前者对应的音素串后面加入消歧音素,破坏这种前缀关系,这样, WFST 中一个词的路径就不会包含于另一个词的路径中。
语言模型方面,可以单独提供 ARPA 格式的统计语言模型,也可以由现有文本训练出来(如使用 Kaldi LM 工具或 SRILM 工具包的 ngram-count ,具体训练方法可参照egs/fisher_swbd/s5/local/fisher_train_lms.sh), utils/format_lm.sh 将该语言模型转换为G.fst,即输入是词,输出也是词,与 data/lang 中的文件一同放在 data/graph/lang 下,用于后面制作解码图,与模型的训练无关。
4.2声学特征提取
原始音频信号可以直接作为模型的输入,只是在保守情况下,如数据不足、计算力薄弱时,更讨好的做法是先将其由时域信号转换为频域信号,借鉴人耳的处理机制,最终产生声学特征。声学特征提取使得语音信息更容易暴露,大大降低算法优化的压力,某种程度上也起到降维的效果,提高计算效率,比如 16 kHz 下的 25 ms 共 400 个数值可转换为 40 维的声学特征。
Bookmark: feature extraction分别提取音频的 MFCC(Mel Frequency Cepstral Coefficient,梅尔频率倒谱系数) 和 FBANK(Mel Filter Bank,梅尔滤波器组)两种声学特征,并计算二者关于说话人的倒谱均值和方差统计量,用于 CMVN(Cepstral Mean and Variance Normalization)标准化。
计算 MFCC 和 FBANK 之前需要通过 conf/{mfcc.conf,fbank.conf} 设置相关选项,可通过命令行运行 compute-mfcc-feats 和 compute-fbank-feats 得知可设置哪些选项,每个选项基本都有合理的默认值。原理上 MFCC 是基于 FBANK 生成的,Kaldi 则将两种特征的计算过程分别包装成两个命令。MFCC 特征各维度之间具有较弱的相关性,适合 GMM 的训练, FBANK 相比 MFCC 保留了更原始的声学特性,多用于 DNN 的训练。两种特征需要注意的选项有:
sample-frequency,音频的采样频率,默认为 16000(16 kHz),如果真实数据与此不同需要指明;
num-mel-bins,梅尔滤波器个数,两种特征兼有,对于 FBANK 来说也是最终特征维度(通常设为 40);
num-ceps,MFCC 特征专有,倒谱个数,也是最终特征的维度,须不大于 num-mel-bins,通常使用默认值 13,首维较为特殊,为第 0 个倒谱系数,即 C0,如果 use-energy 设为 true,则首维替换为能量值(对数形式);
use-energy,对于 MFCC 来说,表明计算时是否使用“energy”,GMM-HMM 的训练通常将其设置为“false”,对于 FBANK 来说,表明计算时是否在特征首部多加一维能量值, compute-vad 使用 MFCC 或 FBANK 中的能量值用于语音活动检测(Voice Activity Detection,VAD)时,此选项须设为“true”。
实验中对于训练集,MFCC 和 FBANK 以及它们的均值和方差统计量分别存放在data/mfcc/train 和 data/fbank/train 的 data 文件夹下,以“.ark”(archive,存档文件)和“.scp”(script,前者的索引文件)格式同步存在,最终将所有索引文件合并放入上一级目录中,即 feats.scp 和 cmvn.scp。通过索引文件可以找到每条语音特征数据的存放位置,并可通过 copy-feats 以文本形式打印出来,每条语音的声学特征都以矩阵形式存储,每一行为一帧,宽度即为特征维度(可用 feat-to-dim 查看),行数即为帧数,不同长度的语音有着不同的帧数,可用 feat-to-len 查看每条或所有语音的总帧数(可用于估算语音的总时长,大体等于总帧数与步移之积)。
Kaldi 以 ark 和 scp 两种格式同步存储文件,相关命令对这些数据进行读写(I/O)时
需要特别注明,并可添加相关选项,下面是基于 copy-feats 的几个例子。
1. 读 ark,写文本 ark:
copy-feats ark:raw_mfcc_train.1.ark ark,t:tmp.ark
2. 读 scp,写文本 ark:
copy-feats scp:feats.scp ark,t:tmp.ark
3. 读 scp,写二进制 ark:
copy-feats scp:feats.scp ark:tmp.ark
4. 读 ark,写二进制 ark、scp:
copy-feats ark:raw_mfcc_train.1.ark ark,scp:tmp.ark,tmp.scp
5. 读写 scp 时,忽略数据丢失错误:
copy-feats scp,p:feats.scp ark,scp,p:tmp.ark,tmp.scp
另外,同时写 ark 和 scp 时 ark 须放在 scp 前面;scp 不能单独写入;选项相对于
ark/scp 的位置不分先后;多种选项可以同时存在。
提取声学特征的目的是在保证音素可辨的情况下,增强信号对说话人、噪声、信道等的鲁棒性,常用的声学特征有 FBANK、MFCC、PLP(Perceptual Linear Prediction)等。Kaldi 中使用 compute-plp-feats 提取 PLP 特征。下面以 MFCC 特征为例说明其产生的主要步骤。声学特征提取需要预先对音频做一些处理,并将其转换至频域,进一步产生 FBANK 和 MFCC 特征,综合起来,大体上主要有如图 4.1 所示的流程。
4.2.1预加重(Pre-emphasis)
语音中有频谱倾斜(Spectral Tilt)现象,即低频具有较高能量,因此,需要加重高频语音的能量,使得高频信息凸显出来,其计算方法为
x'[t] = x[t] −ax[t −1] (4.1)
其中,x[t] 表示音频数据(可以看成一个向量)的第 t 个采样点, a 通常取值范围是(0.95,0.99)。预加重之前也可先对音频进行抖动(Dithering),抖动是信号处理常用的手段,它将信号加入低剂量随机噪音,可有效降低录制音频时模数转换产生的量化误差(Quantization Error),似一种以其人之道还治其人之身的方法。
4.2.2加窗(Windowing)
特征提取时,如果每次取出窗长为 25 ms 的语音,进行离散傅里叶变换计算出一帧,接着步移 10 ms 继续计算下一帧,这种基本做法就是矩形窗(Rectangular Window)。棱角分明的矩形窗容易造成频谱泄露(Spectral Leakage),可以选择使用钟形窗,如海明窗(Hamming Window)、 汉宁窗(Hanning Window)等。加窗的计算方法为
x'[n] = w[n]x[n] (4.2)
其中x[n]是所取窗口(窗长为 N,即 N 个采样点)之内的第 n 个采样点,w[n]是与之对应的权重,不同的加窗方式则体现在 w 的取值上,以N=400(16kHz∗25ms)为例,图 4.2 展示了不同窗口的形状。本质上,加窗计算也是卷积(Convolution)。
4.2.3离散傅里叶变换(DFT)
DFT 从每一段加窗后的音频中分别提取出频域信息,计算方式为
(4.3)
通过复数 X[k] 可计算第 k 个频段的幅度(Magnitude)和相位(Phase),幅度之于频率的坐标图即是频谱(Spectrum),一段语音的所有频谱按时间顺序横排在一起便是这段语音的频谱图(Spectrogram),如之前的图 1.6,每一列都是一个频谱(颜色明暗表示数值大小)
DFT 的一个实现方法是快速傅里叶变换(Fast Fourier Transform,FFT), 可将时间复杂度从O(N2)降为O(Nlog2N),但需要保证窗长 N 是 2 的指数,如果原窗长不满足此条件,一般在音频信号 x 末尾补零,如 400 的窗长可扩展为 512。
频谱的具体计算中,通常用|X[k]|2表示第 k 个频段的能量值(忽略了相位信息),记为 Power Spectrum(既是功率频谱,也是幂的频谱),并根据奈奎斯特频率(Nyquist Frequency),只取其前半段(比如 512 的频数,取其前 512∗1/2+1)作为最终输出结果。声学特征多基于频谱提取出来,甚至就使用频谱本身, compute-spectrogram-feats 可用于频谱特征的提取。
4.2.4FBANK 特征
人耳对不同频率的感知程度不一样,频率越高,敏感度较低,所以人耳的频域感知是非线性的,梅尔刻度(Mel Scale)正是刻画这种规律的, 它反映了人耳线性感知的梅尔频率(Mel Frequency) 与普通频率之间的关系,梅尔频率Mel( f )与普通频率 f 的转换公式为
(4.4)
将频谱规划到梅尔刻度上,能有效促进语音识别系统的性能,实现方法是梅尔滤波器组(Mel Filter Bank)。具体地,将上一节输出的能量频谱通过如图 4.3 所示的三角滤波器组(Triangular Filter Bank)得到梅尔频谱,计算方式与加窗类似,越往高频,滤波器窗口越大,窗口扩大的量级则与梅尔刻度一致。滤波器的个数就是梅尔频段的总数目,通常取为几十。梅尔频谱的能量数值取对数,最终得到的结果就是常说的 FBANK 特征。人类对能量强弱的感知是符合对数关系的,所以对数计算增强了特征的鲁棒性。用于 DNN 训练时,FBANK 的维度就是梅尔滤波器的个数,常取 20 到 40 之间。
梅尔滤波器的计算方式与加窗类似,只是窗口跨度依次变大,也属于卷积运算,故可使用卷积神经网络自动学习更加合理的滤波器组。
4.2.5MFCC 特征
1)倒谱(Cepstrum)
FBANK 中含有基频(Fundamental Frequency,F0)的谐波(Harmonic),可简单理解为频谱中的毛刺,不利于整体轮廓即包络(Envelope)的显现,且各维度之间具有较高的相关性,不适宜 GMM 学习。生理上,谐波源于声带(Vocal Cord),而真正对具体音素进行调节的是声道(Vocal Tract), MFCC 的目的便是消除与音素判别关系不大的谐波,保留包络信息。对 FBANK 特征每帧进行离散傅里叶逆变换(Inverse Discrete Fourier Transform,IDFT) 可以将包络与谐波分开,具体等价于对每帧 FBANK 进行离散余弦变换(Discrete Cosine Transform, DCT), 生成结果记为倒谱(Cepstrum 由 Spectrum 字母倒换而来)。倒谱的维度不大于 FBANK 维度,倒谱的低段位系数(通常前 13 个)可以描述频谱包络,即梅尔频率倒谱系数 MFCC。Spectrum 是频域,相对地 Cepstrum 则是时域。
使用 compute-mfcc-feats 计算 MFCC 时,如需添加一维能量(Energy)值,则由该帧下所有音频采样点取值的平方和计算而来(常取对数),并替换MFCC 的第一个系数(C0),若 num-ceps 设为 13,则 MFCC 特征为 Energy + 12 MFCCs。
声学特征提取中多次使用到对数计算,对数计算在其他地方也有很多好处,比如它可以一定程度地增加非线性,平滑数据;缩小数据范围,防止溢出;将乘(除)变成加法,方便计算;与 Softmax(神经网络的一种激活函数)合用便于梯度计算和传递等。
2) 动态特征(Dynamic Feature)
语音是时序信号,故声学特征的帧与帧之间并不是孤立的,是连续变化的,前后的变化往往包含一些声音线索,动态特性可以显示特征随时间变化的程度,常采用一阶差分、二阶差分,一阶差分的计算方法为
(4.5)
其中,c[t]表示第t帧 MFCC 特征,二阶差分则是一阶差分的差分, add-deltas 可以完成一阶差分、二阶差分的计算。所以通常用来训练 GMM 的声学特征共 39 维(∆表示一阶差分):
12 MFCCs + Energy(13 维);12∆MFCCs +∆Energy(13 维);12∆2MFCCs +∆2Energy(13 维)。
最后,Kaldi 通过 compute-fbank-feats 和 compute-mfcc-feats 综合以上过程分别计算 FBANK 和 MFCC 特征,并通过设置相关选项调节各个步骤的计算,比如“preemphasis-coefficient”选项设置预加重系数,“window-type”选项设置加窗类型。
4.3小结
前端声学特征提取是加入人类先验知识的重要步骤,也是研究者进行手工表征设计的积累,将有效减轻后期机器学习的负担。本章对声学特征提取的各个步骤进行了详细的说明,其过程可以作为语音识别系统的通用前端,研究目标可放在后面的声学模型或语言模型上。
4000520066 欢迎批评指正
All Rights Reserved 新浪公司 版权所有