单一唤醒词识别模型
思路
- 与DNN-HMM的ASR任务相同,逐帧分类,按音素建模,不同的是KWS任务分类数量比ASR任务分类数量更少,只有唤醒词包含的音素,其他通用音素都视为非唤醒词音素,采用一个非唤醒词音素建模(gbg);音频经过声学模型输出后采用beam search解码,最优路径上判断是否是唤醒词路径。
目标
唤醒Recall高,FAR低
- 提高Recall方法:唤醒数据增广,增加唤醒样本的丰富性,其他未有正向结论;
- 降低FAR方法:参考Sigtia, Siddharth, et al. “Efficient Voice Trigger Detection for Low Resource Hardware.” INTERSPEECH. 2018. 文章通过加入状态持续时间的约束minimum duration constraint,最小状态帧长的约束,也就是每个状态至少持续n帧,增大帧移,来减少误唤醒。因此实验中在解码过程中进行下采样,以及声学模型的拼帧采用较长拼帧,来减少误唤醒。
声学模型
- 输出分类标签:唤醒词“小源小源”对应的音素组成“x、iao、vv、van”、静音“sil”、其他音“gbg”,共6个分类数;
- 声学模型网络结构为TDNN,结构特点为拼帧较长:
1 | cat <<EOF > $dir/configs/network.xconfig |
词典
- lexicon.txt
语言模型
words.txt
2gram,srilm.o3g.kn.gz:
语言模型训练通过很多的sil和gbg和几条小源小源、xiao、yuan、xiaoyuan等训练得到,观察测试集中没识别出唤醒词识别成什么文本,观察测试集中误唤醒成什么文本,调节该文本相关语言模型权重;
根据recall和far值,不断微调唤醒词和非唤醒词语言模型权重,使得recall较高下也有较低的far;
声学模型训练过程
训练集
- 用6w原始数据,5种噪声,加上原来没有加噪的数据,6*6=36w条;路径:data/train_xiaoyuan
- 速度扰动 36*3=108w条,路径:data/train_xiaoyuan_sp(727小时)
- 108w条提取16维mfcc特征,train_xiaoyuan_sp_mfcc(steps/make_mfcc_pitch.sh),做对齐,对齐路径:exp/nnet3/tdnn_lei/ali_train_xiaoyuan_sp
- 提取50维plp特征
- 108w条对齐文件 + Xiaoyuan 9w条对齐文件 = 117w条,作为小源命令词数据(正样本)
- 4000小时ASR通用数据,360万条作为非唤醒词数据(负样本)
训练标签准备
将对齐标签转为6分类(可参考kaldi脚本hi_mia/w1/run_kws_kf.sh)
构建phone映射表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#转换,使得只保留命令词的phone,其他无关phone都用garbage这个phone表示
awk -v hotword_phone=data/dict/phones.txt \
'BEGIN {
while (getline < hotword_phone) {
map[$1] = $2-1
}
}
{
if(!match($1, "#") && !match($1, "<")) {
if(match($1, "sil"))
{
printf("%s %s\n", $2, 0)
}
else
{
printf("%s %s\n", $2, map[$1] != "" ? map[$1] : 1)
}
}
}
' data/lang/phones.txt > data/phone.map构建6分类的alignment文件
1
2
3
4
5
6
7
8mkdir -p $dir_temp
cur=$(cat $ali/num_jobs)
for x in $(seq 1 $cur);do
gunzip -c $ali/ali.$x.gz |
ali-to-phones --per-frame=true exp_sil_ftv/mfcc_pitch/nnet3_tdnn6layers_8b_relu_ali_train_ftv/final.mdl ark:- t,ark:- |
utils/apply_map.pl -f 2- data/phone.map |
copy-int-vector t,ark:- ark,scp:$dir_temp/ali.$x.ark,$dir_temp/ali.$x.scp
done
声学模型训练
- steps/nnet3/train_raw_dnn.py,没有转移概率,生成声学模型final.raw
生成final.mdl
- 生成tree:
- gmm-init-mono –shared-phones=data/lang_xyxy/phones/sets.int “–train-feats=ark,s,cs:apply-cmvn –utt2spk=ark:data/train/split10/1/utt2spk scp:data/train/split10/1/cmvn.scp scp:data/train/split10/1/feats.scp ark:- | add-deltas ark:- ark:- | subset-feats –n=10 ark:- ark:-|” data/lang_xiaoyuan/topo 39 0.mdl tree
- final.raw生成final.mdl
- nnet3-am-init exp/nnet3/tdnn_1/tree data/lang_xyxy/topo exp/nnet3/tdnn_1/final.raw exp/nnet3/tdnn_1/final.mdl
解码过程
- 与普通识别模型相同,输出声学模型分数,在事先构建好的解码网络HCLG.fst中搜索最优路径,最优路径有唤醒词则唤醒;
- 解码长度与触发VAD长度相关;
- 解码时“–frame-subsampling-factor=3”,(即在keyword_lib改为chain model网络结构),跳帧输入解码器/cmvn后特征跳帧输入DNN;
训练小结
- 对比负样本音素用一个音素gbg表示与保留唤醒词音素的模型,用一个音素表示造成声学特征下输出gbg的概率和唤醒词音素概率都高,造成区分性不明显,混淆,因此不能将负样本音素用一个音素表示,需要在负样本中保留唤醒词音素;
- 数据增广的效果:
- 对比不同唤醒数据量训练的模型,加噪后用上所有唤醒数据,与加噪后没用上所有唤醒数据相比,没有改善;因此在样本数据有一定数量条件下,单纯只用上所有噪声未带来更加丰富的样本信息。
- 加噪后用上所有唤醒数据,再加入速度扰动,与加噪后没用上所有唤醒数据相比,能有一些改善;因此速度扰动在该样本集条件下能带来更加丰富的样本信息。
- asr和kws联合训练的多任务学习、用训好的asr除最后一层作为初始kws模型,未取得正向结论;训练时asr的accuracy在60%,猜想asr的loss较大可能影响了kws任务。
- 更改模型结构,crnn、attention结构,未取得正向结论;应该还是没有训练好。
实验结果
- 结果从decode.log获取,不通过lattice得到