详解 DNN 在声学应用中的模型训练

简介:

本文通过简单kaldi源码,分析DNN训练声学模型时神经网络的输入与输出。在进行DNN训练之前需要用到之前GMM-HMM训练的模型,以训练好的mono模型为例,对模型进行维特比alignement(对齐),该部分主要完成了每个语音文件的帧到 transition-id 的映射

不妨查看对齐后的结果:


$ copy-int-vector "ark:gunzip -c ali.1.gz|" ark,t:- | head -n 1
speaker001_00003 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 15 15 15 18 890 889 889 889 889 889 889 892 894 893 893 893 86 88 87 90 89 89 89 89 89 89 89 89 89 89 89 89 89 89 194 193 196 195 195 198 197 386 385 385 385 385 385 385 385 385 388 387 387 390 902 901 901 904 903 906 905 905 905 905 905 905 905 905 905 905 905 914 913 913 916 918 917 917 917 917 917 917 752 751 751 751 751 751 754 753 753 753 753 753 753 753 753 756 755 755 926 925 928 927 927 927 927 927 927 927 930 929 929 929 929 929 929 929 929 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 18


对于一个训练语音文件speaker001_00003,后面的每一个数字标示一个transition-id,同时每个数字对应一个特征向量,对应的向量可以 copy-matrix 查看,可参考特征提取相关内容,链接如下:

http://t.cn/RX2n4Dx

同样查看 transition-id:


$ show-transitions phones.txt final.mdl

Transition-state 1: phone = sil hmm-state = 0 pdf = 0
 Transition-id = 1 p = 0.966816 [self-loop]
 Transition-id = 2 p = 0.01 [0 -> 1]
 Transition-id = 3 p = 0.01 [0 -> 2]
 Transition-id = 4 p = 0.013189 [0 -> 3]
Transition-state 2: phone = sil hmm-state = 1 pdf = 1
 Transition-id = 5 p = 0.970016 [self-loop]
 Transition-id = 6 p = 0.01 [1 -> 2]
 Transition-id = 7 p = 0.01 [1 -> 3]
 Transition-id = 8 p = 0.01 [1 -> 4]
Transition-state 3: phone = sil hmm-state = 2 pdf = 2
 Transition-id = 9 p = 0.01 [2 -> 1]
 Transition-id = 10 p = 0.968144 [self-loop]
 Transition-id = 11 p = 0.01 [2 -> 3]
 Transition-id = 12 p = 0.0118632 [2 -> 4]
Transition-state 4: phone = sil hmm-state = 3 pdf = 3
 Transition-id = 13 p = 0.01 [3 -> 1]
 Transition-id = 14 p = 0.01 [3 -> 2]
 Transition-id = 15 p = 0.932347 [self-loop]
 Transition-id = 16 p = 0.0476583 [3 -> 4]
Transition-state 5: phone = sil hmm-state = 4 pdf = 4
 Transition-id = 17 p = 0.923332 [self-loop]
 Transition-id = 18 p = 0.0766682 [4 -> 5]
Transition-state 6: phone = a1 hmm-state = 0 pdf = 5
 Transition-id = 19 p = 0.889764 [self-loop]
 Transition-id = 20 p = 0.110236 [0 -> 1]
...


唯一的Transition-state对应唯一的pdf,其下又包括多个 Transition-id,

接下来看神经网络的输入与输出到底是什么。这里以steps/nnet为例。追溯脚本到steps/nnet/train.sh,找到相关的命令:


...
 labels_tr="ark:ali-to-pdf $alidir/final.mdl \"ark:gunzip -c $alidir/ali.*.gz |\" ark:- | ali-to-post ark:- ark:- |"

...
feats_tr="ark:copy-feats scp:$dir/train.scp ark:- |"
...
# input-dim,
  get_dim_from=$feature_transform
  num_fea=$(feat-to-dim "$feats_tr nnet-forward \"$get_dim_from\" ark:- ark:- |" -)
# output-dim,
  num_tgt=$(hmm-info --print-args=false $alidir/final.mdl | grep pdfs | awk '{ print $NF }')
...

dnn)
 utils/nnet/make_nnet_proto.py $proto_opts \
   ${bn_dim:+ --bottleneck-dim=$bn_dim} \
   $num_fea $num_tgt $hid_layers $hid_dim >$nnet_proto
  ;;


从上面关键的几个神经网络的训练的准备阶段可以看出,神经网络的输入很清楚是变换后的特征向量(feats_tr),输出是labels_tr,下面单独运行上面的命令,来查看神经网络的输出(target)是什么。labels_tr的生成分两步:

  • ali-to-pdf: 将上面对齐文件中的transition-id转化为对应的pdf-id;

  • ali-to-post: 根据得到的pdf-id,生成[pdf, post]对,即pdf与其对应的后验概率。


$ ali-to-pdf final.mdl "ark:gunzip -c ali.1.gz|" ark,t:- | head -n 1
 speaker001_00003 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 3 3 4 440 440 440 440 440 440 440 441 442 442 442 442 38 39 39 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 92 92 93 93 93 94 94 188 188 188 188 188 188 188 188 188 189 189 189 190 446 446 446 447 447 448 448 448 448 448 448 448 448 448 448 448 448 452 452 452 453 454 454 454 454 454 454 454 371 371 371 371 371 371 372 372 372 372 372 372 372 372 372 373 373 373 458 458 459 459 459 459 459 459 459 459 460 460 460 460 460 460 460 460 460 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 4


观察前两帧,结合文章一开始,transition-id 分别为4和1,而对应的pdf均为0。对该结果再进行ali-to-post:


$ ali-to-pdf final.mdl "ark:gunzip -c ali.1.gz|" ark,t:- | head -n 1 | ali-to-post ark,t:- ark,t:-
 speaker001_00003 [ 0 1 ] [ 0 1 ] [ 0 1 ] [ 0 1 ] [ 0 1 ] [ 0 1 ] [ 0 1 ] [ 0 1 ] [ 0 1 ] [ 0 1 ] [ 0 1 ] [ 0 1 ] [ 0 1 ] [ 0 1 ] [ 0 1 ] ...... [ 3 1 ] [ 3 1 ] [ 3 1 ] [ 3 1 ] [ 4 1 ] [ 440 1 ] [ 440 1 ] [ 440 1 ] [ 440 1 ] [ 440 1 ] [ 440 1 ] [ 440 1 ] [ 441 1 ] [ 442 1 ] [ 442 1 ] [ 442 1 ] [ 442 1 ] [ 38 1 ] [ 39 1 ] [ 39 1 ] [ 40 1 ] [ 40 1 ] [ 40 1 ] [ 40 1 ] [ 40 1 ] [ 40 1 ] [ 40 1 ] [ 40 1 ] [ 40 1 ] [ 40 1 ] [ 40 1 ] [ 40 1 ] [ 40 1 ] [ 40 1 ] [ 40 1 ] [ 92 1 ] [ 92 1 ]...... [ 0 1 ] [ 0 1 ] [ 0 1 ] [ 0 1 ] [ 3 1 ] [ 4 1 ]


得到pdf-id以及相应的后验概率,这里均为1。

由此得到了训练数据以及对应的target label。进一步来看神经网络的输入与输出的维度,网络结构被utils/nnet/make_nnet_proto.py写到nnet_proto文件中,该Python脚本的两个重要参数 num_fea和num_tgt分别为神经网络的输入与输出的维度。其中num_fea是由feat-to-dim获得:


$ feat-to-dim scp:../tri4b_dnn/train.scp ark,t:- | grep speaker001_00003 
speaker001_00003 40


这里为fbank特征,维度为40,而在真正作为神经网络输入时,进一步对特征向量进行的变换,从源码steps/nnet/train.sh也可以看到splice参数(默认值为5),指定了对特征向量的变换:取对应帧前后5帧,拼成一个11帧组成的大向量(维度为440)。该部分特征变换的拓扑也被保存到final.feature_transform:


$ more final.feature_transform 
<Nnet> 
<Splice> 440 40 
[ -5 -4 -3 -2 -1 0 1 2 3 4 5 ]
<!EndOfComponent> 
...


后面在进行神经网络的训练时会使用该拓扑对特征向量进行变换,最终的神经网络输入维度为440。

而num_tgt的维度则是通过hmm-info获得:


$ hmm-info final.mdl
number of phones 218
number of pdfs 1026
number of transition-ids 2834
number of transition-states 1413

$ hmm-info final.mdl |  grep pdfs | awk '{ print $NF }'
1026


因此,看到神经网络的输出维度为1026,这时查看nnet_proto:


<AffineTransform> <InputDim> 440 <OutputDim> 1024 <BiasMean> -2.000000 <BiasRange> 4.000000 <ParamStddev> 0.037344 <MaxNorm> 0.000000
<Sigmoid> <InputDim> 1024 <OutputDim> 1024
<AffineTransform> <InputDim> 1024 <OutputDim> 1024 <BiasMean> -2.000000 <BiasRange> 4.000000 <ParamStddev> 0.109375 <MaxNorm> 0.000000
<Sigmoid> <InputDim> 1024 <OutputDim> 1024
<AffineTransform> <InputDim> 1024 <OutputDim> 1024 <BiasMean> -2.000000 <BiasRange> 4.000000 <ParamStddev> 0.109375 <MaxNorm> 0.000000
<Sigmoid> <InputDim> 1024 <OutputDim> 1024
<AffineTransform> <InputDim> 1024 <OutputDim> 1024 <BiasMean> -2.000000 <BiasRange> 4.000000 <ParamStddev> 0.109375 <MaxNorm> 0.000000
<Sigmoid> <InputDim> 1024 <OutputDim> 1024
<AffineTransform> <InputDim> 1024 <OutputDim> 1026 <BiasMean> 0.000000 <BiasRange> 0.000000 <ParamStddev> 0.109322 <LearnRateCoef> 1.000000 <BiasLearnRateCoef> 0.100000
<Softmax> <InputDim> 1026 <OutputDim> 1026


这里可以看到神经网络的输入维度有40变为440,输出为pdf的个数(对应HMM状态的个数)。

如果继续追查代码,最后可以找到单次神经网络的训练实现,kaldi/src/nnetbin/nnet-train-frmshuff.cc:


Perform one iteration (epoch) of Neural Network training with mini-batch Stochastic Gradient Descent. The training targets are usually pdf-posteriors, prepared by ali-to-post.


继续分析代码,可以看到几个关键步骤:

  • 解析训练参数,配置网络

  • 读取特征向量和target label,输入为Matrix< BaseFloat >类型,输出为Posterior类型,即<pdf-id, posterior>对。


// get feature / target pair,
Matrix<BaseFloat> mat = feature_reader.Value();
Posterior targets = targets_reader.Value(utt);


  • 随机打乱训练数据,作为神经网络输入与期望输出:


const CuMatrixBase<BaseFloat>& nnet_in = feature_randomizer.Value();
const Posterior& nnet_tgt = targets_randomizer.Value();
const Vector<BaseFloat>& frm_weights = weights_randomizer.Value();


  • 前向传播,计算估计值nnet_out


// forward pass,
nnet.Propagate(nnet_in, &nnet_out);


  • 计算cost,这里支持交叉熵和平方差和multitask。结果为obj_diff


// evaluate objective function we've chosen,
if (objective_function == "xent") {
 // gradients re-scaled by weights in Eval,
 xent.Eval(frm_weights, nnet_out, nnet_tgt, &obj_diff);
} else if (objective_function == "mse") {
 // gradients re-scaled by weights in Eval,
 mse.Eval(frm_weights, nnet_out, nnet_tgt, &obj_diff);
}
...


  • 根据误差反向传播,更新参数


if (!crossvalidate) {
 // back-propagate, and do the update,
 nnet.Backpropagate(obj_diff, NULL);
}


  • 完成一次参数更新,继续迭代。


total_frames += nnet_in.NumRows(),

 accepting: the loss was better, or we had fixed learn-rate, or we had fixed epoch-number



最终由调用该部分代码的/steps/nnet/train_scheduler.sh指定最大迭代次数max_iters或accept训练的模型,


 accepting: the loss was better, or we had fixed learn-rate, or we had fixed epoch-number


小结

在进行DNN训练前:

  • 训练GMM-HMM模型,聚类,并得到音素(或状态)的后验。

  • 对语音数据进行对齐,这里得到语音文件按时间顺序transition-id到帧特征向量的对应。

  • 生成< pdf-id, posterior > 对作为训练目标target

  • 语音文件特征向量进行变换,这里取前后5帧,拼成一个11帧维度更高的特征向量,作为神经网络输入。

  • 神经网络输入变换后的特征向量,通过前向传播,经Softmax层,得到该帧特征对应每个pdf的概率预测值。

  • 对每个pdf根据< pdf-id, posterior >查到目标后验概率,与预测值求误差

  • 反向传播更新参数。

  • 不断迭代,直到达到最大训练次数,或模型经过cross validation得到较低的误差(loss)停止训练。

解码时,用训练好的DNN-HMM模型,输入帧的特征向量,得到该帧为每个状态(对应pdf)的概率。

详解 DNN 在声学应用中的模型训练

其中 x_t 对应t时刻的观测值(输入),q_t=s_i 即表示t时刻的状态为 s_i。p(x_t) 为该观测值出现概率,对结果影响不大。p(s_i) 为 s_i 出现的先验概率,可以从语料库中统计得到。最终得到了与GMM相同的目的:HMM状态到观测帧特征向量的输出概率。就有了下面的示意图:

详解 DNN 在声学应用中的模型训练





====================================分割线================================


本文作者:AI研习社

本文转自雷锋网禁止二次转载,原文链接

目录
相关文章
|
1月前
|
机器学习/深度学习 人工智能 物联网
通义灵码在人工智能与机器学习领域的应用
通义灵码不仅在物联网领域表现出色,还在人工智能、机器学习、金融、医疗和教育等领域展现出广泛应用前景。本文探讨了其在这些领域的具体应用,如模型训练、风险评估、医疗影像诊断等,并总结了其提高开发效率、降低门槛、促进合作和推动创新的优势。
通义灵码在人工智能与机器学习领域的应用
|
3天前
|
机器学习/深度学习 监控 算法
机器学习在图像识别中的应用:解锁视觉世界的钥匙
机器学习在图像识别中的应用:解锁视觉世界的钥匙
179 95
|
1月前
|
机器学习/深度学习 传感器 自动驾驶
探索机器学习在图像识别中的创新应用
本文深入分析了机器学习技术在图像识别领域的最新进展,探讨了深度学习算法如何推动图像处理技术的突破。通过具体案例分析,揭示了机器学习模型在提高图像识别准确率、效率及应用场景拓展方面的潜力。文章旨在为读者提供一个全面的视角,了解当前机器学习在图像识别领域的创新应用和未来发展趋势。
|
11天前
|
机器学习/深度学习 数据采集 运维
机器学习在运维中的实时分析应用:新时代的智能运维
机器学习在运维中的实时分析应用:新时代的智能运维
62 12
|
27天前
|
机器学习/深度学习 算法 数据挖掘
C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出
本文探讨了C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出。文章还介绍了C语言在知名机器学习库中的作用,以及与Python等语言结合使用的案例,展望了其未来发展的挑战与机遇。
44 1
|
1月前
|
机器学习/深度学习 数据采集 算法
机器学习在医疗诊断中的前沿应用,包括神经网络、决策树和支持向量机等方法,及其在医学影像、疾病预测和基因数据分析中的具体应用
医疗诊断是医学的核心,其准确性和效率至关重要。本文探讨了机器学习在医疗诊断中的前沿应用,包括神经网络、决策树和支持向量机等方法,及其在医学影像、疾病预测和基因数据分析中的具体应用。文章还讨论了Python在构建机器学习模型中的作用,面临的挑战及应对策略,并展望了未来的发展趋势。
123 1
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
思通数科AI平台在尽职调查中的技术解析与应用
思通数科AI多模态能力平台结合OCR、NLP和深度学习技术,为IPO尽职调查、融资等重要交易环节提供智能化解决方案。平台自动识别、提取并分类海量文档,实现高效数据核验与合规性检查,显著提升审查速度和精准度,同时保障敏感信息管理和数据安全。
118 11
|
2月前
|
机器学习/深度学习 数据可视化 数据挖掘
机器学习中空间和时间自相关的分析:从理论基础到实践应用
空间和时间自相关是数据分析中的重要概念,揭示了现象在空间和时间维度上的相互依赖关系。本文探讨了这些概念的理论基础,并通过野火风险预测的实际案例,展示了如何利用随机森林模型捕捉时空依赖性,提高预测准确性。
110 0
机器学习中空间和时间自相关的分析:从理论基础到实践应用
|
1月前
|
机器学习/深度学习 数据采集 运维
智能化运维:机器学习在故障预测和自动化响应中的应用
智能化运维:机器学习在故障预测和自动化响应中的应用
62 4
|
1月前
|
机器学习/深度学习 TensorFlow API
机器学习实战:TensorFlow在图像识别中的应用探索
【10月更文挑战第28天】随着深度学习技术的发展,图像识别取得了显著进步。TensorFlow作为Google开源的机器学习框架,凭借其强大的功能和灵活的API,在图像识别任务中广泛应用。本文通过实战案例,探讨TensorFlow在图像识别中的优势与挑战,展示如何使用TensorFlow构建和训练卷积神经网络(CNN),并评估模型的性能。尽管面临学习曲线和资源消耗等挑战,TensorFlow仍展现出广阔的应用前景。
71 5

热门文章

最新文章