kaldi学习笔记之卷积神经网络(CNN)
摘要:
本文将以switchboard为例,解读kaldi卷积神经网络部分的bash脚本。一方面便于以后自己回顾,另一方面希望能与大家互相交流。
正文:
在switchboard部分的训练代码中,kaldi官方并未提供相关训练的deamon,但kaldi本身支持卷积神经网络的训练,在egs/swbd/s5c/steps/nnet2中,kaldi提供了训练的CNN网络的核心代码脚本 train_convnet_accel2.sh,因此我们只需按照egs/swbd/s5c/run.sh的执行步骤,对代码进行一定的修改,便能进行卷积神经网络的构建。
在本文中,假设读者已经熟悉run.sh中的训练脚本并且对语音识别模型训练相关步骤有一定的经验。(目前没时间,不久之后我将会对run.sh的一些步骤进行解读。)
好,现在开始正式进入话题。
- 训练流程:
1. 标注对齐:训练CNN模型需要对每一帧进行标注,由于switchboard数据中仅对某段时间内的数据内容进行标注,因此我们需要用一个前面已经通过run.sh训练过的HMM-GMM模型进行数据对齐。
2. 数据准备:kaldi提供的CNN训练所选用的是FBANK特征,此处为了便于下文网络的结构解析,因此沿用kaldi的特征,读者理解完脚本以后可以根据自己的需要修改特征。FBANK特征维度是36维,对每一个说话人的特征进行归一化,训练CNN网络时还会用到特征的一阶和二阶差分参数。
对训练集进行划分,从中选取4000句作为交叉验证,剩下的全部作为训练集使用。
3. CNN模型训练:应用kaldi提供的核心训练代码,向训练脚本中传递相关的训练参数:网络的结构,learning rate,运行环境,任务数等。下文将会展开脚本对各个参数进行解析。
4. CNN模型测试:对训练所得的模型进行测试,与HMM-GMM模型,DNN模型进行比较。
s5c/conf/fbank.conf的配置:
--window-type=hamming # disable Dans window, use the standard
--sample-frequency=8000
--low-freq=64 # typical setup from Frantisek Grezl
--high-freq=3800
--dither=1
--num-mel-bins=36 # 8kHz so we use 36 bins (@ 8 filters/octave to get closer to 40 filters/16Khz used by IBM)
- 训练代码:
#!/bin/bash
#=> This script training the CNN(Convoluntional neural network ) model for swbd
temp_dir=
dir=nnet_cnn_fbank
has_fisher=true
. cmd.sh
. path.sh
set -e
printf 'Start CNN training in:'
date
. utils/parse_options.sh
#data prepare
echo '===============================CNN data preparing================================='
#fbank feature extract
fbankdir=fbank
for x in train eval2000;do
mkdir -p data/fbank/$x
cp data/$x/* data/fbank/$x
rm -rf data/fbank/$x/.backup data/fbank/$x/cmvn.scp data/fbank/$x/feats.scp
steps/make_fbank.sh --nj 64 --cmd "$train_cmd" \
data/fbank/$x exp/make_fbank/$x $fbankdir
#对每一个说话人进行特征归一化,将归一化值写入到$mfccdir/cmvn_$x.ark文件,不改变上一步提取的特征。
steps/compute_cmvn_stats.sh data/fbank/$x exp/make_fbank/$x $fbankdir
#去除utt2spk spk2utt feats.scp text segments wav.scp cmvn.scp vad.scp reco2file_and_channel spk2gender utt2lang中的物理上不存在的文件,
#并按照文件名对标注进行排序。
utils/fix_data_dir.sh data/fbank/$x
done
echo '*******************************************Start subset data for training *******************************************'
# Use the first 4k sentences as dev set. Note: when we trained the LM, we used
# the 1st 10k sentences as dev set, so the 1st 4k won't have been used in the
# LM training data. However, they will be in the lexicon, plus speakers
# may overlap, so it's still not quite equivalent to a test set.
#将数据分为训练集(train set)和交叉验证集(dev set)
utils/subset_data_dir.sh --first data/fbank/train 4000 data/train_cnn_dev # 5hr 6min
n=$[`cat data/fbank/train/segments | wc -l` -