kaldi语音识别 chain模型的训练流程
0.解析配置文件
调用steps/nnet3/xconfig_to_configs.py函数生成final.config。如果配置文件中有指定affine-transform-file=$dir/configs/idct.mat。则也会在解析过程中生成该文件。
生成idct.mat的过程的调用顺序:steps/nnet3/xconfig_to_configs.py → steps/libs/nnet3/xconfig/basic_layers.py/get_full_config → steps/libs/nnet3/xconfig/basic_layers.py/_generate_config
这里需要注意的是:当network.config 文件中有fixed-affine-layer层时(通常是tdnn模型),则会生成init.config文件。这个文件在后面第五步会用到。而当有idct-layer层时(通常是cnn-tdnn模型),会在此步骤生成idct.mat文件。
在训练过程中,会根据final.config,解析相关参数。如,特征维度feat_dim,ivector的维度ivector_dim,模型上下文范围model_left_context, model_right_context等。
1.训练phone级别的语言模型
chain模型类似于基于最大互信息的区分性训练,也需要分子和分母有限状态机。在分母有限状态机方面,区别于传统最大互信息的区分性训练,chain模型用训练数据的强制对齐结果,训练了一个四元语法音素单元的语言模型,并将其转成有限状态机。相关代码如下:
该过程的输入是tree_sp文件中的alignments和修改topo结构后生成的gmm model。
2. 生成分母FST
调用chain-make-den-fst程序,以新的决策树、状态转移概率和音素级别的语言模型作为输入,生成den.fst和normalization.fst。其中后者是经前者修改初始和终止概率后得到的。在实际训练中将normalization.fst作为分母FST。
上图函数实际上是调用的chain-make-den-fst函数。
另外对于分子FST,早在chain模型的学习笔记2(chain模型的准备阶段)已经准备就绪。
3. 初始化模型
一般情况下,如果在输入环节有特征变换LDA操作或者IDCT操作,则会在该步骤生成相应的文件。
4.生成egs。详见chain模型的学习笔记1
5. 计算预调(precondition)矩阵
拼帧后的特征是强相关的,需要进行去相关操作。在chain模型中,采用LDA变换达到去相关目的。
6.初始化声学模型
先调用nnet3-init指令生成0.raw文件
然后调用nnet3-am-init指令生成0.mdl
7.开始训练模型
7.1 首先获取当前学习率,类似TensorFlow中的tf.train.exponential_decay学习率的指数衰减;还有一种tf.train.polynomial_decay学习率的多项式衰减。
7.2 后台计算训练子集和验证子集的似然值compute_train_cv_probabilities
7.3 后台打印当前迭代参数compute_progress。包括progress.{iter}.log,full_progress.{iter}.log,full_info.{iter}.log
7.4 计算当前迭代中,所需要的chunk数cur_num_chunk_per_minibatch_str和最大参数变化量cur_max_param_change。对于第一次迭代,将会把chunk数折半,最大参数变化值也会缩小sqrt(2)倍。
7.5 多进程训练模型train_new_models。生成{next_iter}.{job}.raw文件
7.6 合并训练结果
a. 先利用正则匹配,从日志中找出各个job的似然值
b. 以最佳结果为基准(最大似然),保留与最佳结果相差在一定范围内的计算结果(如果有结果太差而被剔除,则会告警)。
c. 合并保留的各个job的结果。对于第一步迭代,直接选取最佳结果;之后的步骤中则取平均。
具体对各模型求平均的相关代码如下:
d. 最终,删除中间文件
8.模型合并,并清除临时文件(egs和中间model)
a. 先获取需要合并的迭代数。从最后一个Epoch的中间迭代开始合并(假设最后一个Epoch是从1000代开始,1050代结束,则合并的起点是1025代)。从1025代到1050代中选择max_models_combine个做合并(默认20个)。
b. 将指定代数的模型合并
c. 清除egs和中间model。对于前面计算的需要合并的代数models_to_combine和每满足 iter %preserve_model_interval =0的模型将会保留
- 点赞
- 收藏
- 关注作者
评论(0)