kaldi 如何微调模型
Author : Xin Pan
Date: 2020.07.22
在已经有了一个模型的基础上如何去微调一个模型?
需要的文件
- 基础模型文件夹A(需要包含final.mdl以及tree,除此以外还需要ali.*.gz文件);
- data文件夹以及保存特征的文件夹;
- 新模型文件夹B(需要包含final.mdl以及tree);
- exp/tri4_lat(有时不需要,正在看什么情况需要什么情况不需要)
那么需要做哪些更改?
- 需要build tree吗?(如果需要请看“一个额外步骤”再继续看步骤2,否则请直接看步骤2)
- local/chain/run_tdnn.sh stage=10;
- train.py 中的
train_stage=-6; get_egs_stage=0
; - train.py 设定
trainer.input-model old_dir/old_final.mdl
为需要微调的旧模型; - 将旧模型考到输出文件夹命名为0.mdl ?
- 运行
step/nnet3/chain/train.py
一个额外处理步骤
使用命令转换旧的tri4_cd_tree里边的ali.*.gz 到新的final.mdl和tree下边
for i in `seq 30`; do convert-ali tri4_cd_tree_sp/final.mdl hljmdl3/final.mdl hljmdl3/tree ark:"gunzip -c tri4_cd_tree_sp/ali.${i}.gz |" "ark:|gzip -c >tri4_cd_tree_sp_hljmdl3/ali.${i}.gz"; done
其实这个额外的处理步骤就是在build_tree.sh中的最后一步也就是stage = -1
这个额外的步骤其实需要细分一些情况:
- 产生ali的模型和将要训练的新的声学模型相同的结构,或者说相同。额外步骤我觉得可以不用进行;
- 产生ali的模型和将要训练的新的声学模型完全不同。那么额外步骤这里是需要的。
基于这样的前提条件,如果是微调一个模型,而且新的数据的ali来自微调模型本身那么这个额外步骤可以省略。
微调脚本
#!/usr/bin/env bash
# Made by Xin Pan
# Version 0.2
# Used for fine-tune a model with tdnn ali.
stage=6
train_stage=-2 #-6
get_egs_stage=-10
nj=40
affix=all
dir=exp/chain/tdnn_model
lat_dir=exp/chain/tdnn_1b_all_sp_ali
decode_iter=
# train config
num_epochs=4
initial_effective_lrate=0.001
final_effective_lrate=0.0001
max_param_change=2.0
final_layer_normalize_target=0.5
num_jobs_initial=6
num_jobs_final=7
minibatch_size=128
dropout_schedule='0,0@0.20,0.3@0.50,0'
dropout_schedule='0,0@0.20,0.3@0.50,0'
frames_per_eg=150,110,90
remove_egs=false
common_egs_dir=
xent_regularize=0.1
# End of config
echo "$0 $@"
. ./cmd.sh
. ./path.sh
. ./utils/parse_options.sh
train_set=train
lang=data/lang_chain
dir=${dir}
if [ $stage -le 1 ]; then
echo "in stage 1"
mfccdir=mfcc_hires
for datadir in ${train_set} ; do
utils/copy_data_dir.sh data/${datadir} data/${datadir}_hires
utils/data/perturb_data_dir_volume.sh data/${datadir}_hires || exit 1;
steps/make_mfcc_pitch.sh --mfcc-config conf/mfcc_hires.conf --pitch-config conf/pitch.conf \
--nj $nj data/${datadir}_hires exp/make_mfcc/ ${mfccdir}
#steps/make_fbank_pitch.sh --fbank-config conf/fbank_hires.conf --pitch-config conf/pitch.conf \
# --nj ${nj} data/${datadir}_hires exp/make_mfcc/ ${mfccdir}
steps/compute_cmvn_stats.sh data/${datadir}_hires exp/make_mfcc/ ${mfccdir}
utils/data/limit_feature_dim.sh 0:39 data/${datadir}_hires data/${datadir}_hires_nopitch
steps/compute_cmvn_stats.sh data/${datadir}_hires_nopitch exp/make_mfcc ${mfccdir}
done
fi
if [ $stage -le 2 ]; then
echo "Extracting iVector for data dir."
for datadir in ${train_set} ${test_set}; do
steps/online/nnet2/copy_data_dir.sh --utts-per-spk-max 2 \
data/${datadir}_hires_nopitch data/${datadir}_hires_nopitch_max2
steps/online/nnet2/extract_ivectors_online.sh --cmd "$train_cmd" --nj ${nj} \
data/${datadir}_hires_nopitch_max2 exp/chain/extractor_${affix} exp/chain/ivectors_${datadir}_${affix} || exit 1;
done
fi
if [ $stage -le 3 ]; then
steps/nnet3/align.sh --cmd "$train_cmd" --nj ${nj} --scale-opts '--transition-scale=1.0 --acoustic-scale=1.0 --self-loop-scale=1.0' --online-ivector-dir exp/chain/ivectors_${train_set}_${affix} --use-gpu false data/train_hires data/lang ${dir} ${lat_dir} || exit 1;
fi
if [ $stage -le 4 ]; then
steps/nnet3/align_lats.sh --cmd "$train_cmd" --nj ${nj} --scale-opts '--transition-scale=1.0 --self-loop-scale=1.0' --acoustic_scale 1.0 --online-ivector-dir exp/chain/ivectors_${train_set}_${affix} data/train_hires data/lang ${dir} ${lat_dir} || exit 1;
fi
echo "Skip tree build"
if [ $stage -le 5 ]; then
steps/nnet3/chain/train.py --stage ${train_stage} \
--cmd "${decode_cmd}" \
--feat.online-ivector-dir exp/chain/ivectors_${train_set}_${affix} \
--feat.cmvn-opts "--norm-means=false --norm-vars=false" \
--chain.xent-regularize $xent_regularize \
--chain.leaky-hmm-coefficient 0.1 \
--chain.l2-regularize 0.00005 \
--chain.apply-deriv-weights false \
--chain.lm-opts="--num-extra-lm-states=2000" \
--egs.dir "$common_egs_dir" \
--egs.stage $get_egs_stage \
--egs.opts "--frames-overlap-per-eg 0" \
--egs.chunk-width $frames_per_eg \
--trainer.input-model "exp/chain/tdnn_model/final.mdl" \
--trainer.dropout-schedule $dropout_schedule \
--trainer.num-chunk-per-minibatch $minibatch_size \
--trainer.frames-per-iter 1500000 \
--trainer.num-epochs $num_epochs \
--trainer.optimization.num-jobs-initial $num_jobs_initial \
--trainer.optimization.num-jobs-final $num_jobs_final \
--trainer.optimization.initial-effective-lrate $initial_effective_lrate \
--trainer.optimization.final-effective-lrate $final_effective_lrate \
--trainer.max-param-change $max_param_change \
--cleanup.remove-egs $remove_egs \
--use-gpu "wait" \
--feat-dir data/${train_set}_hires \
--tree-dir ${lat_dir} \
--lat-dir ${lat_dir}\
--dir ${dir}_finetune || exit 1;
fi
if [ $stage -le 6 ]; then
utils/mkgraph.sh --self-loop-scale 1.0 data/lang_test ${dir}_finetune ${dir}_finetune/graph
fi
echo "Training all done"
exit 0;
TODO
- 需要的文件第四点再敲定;
- 需要做哪些更改中第一和五点;
- 微调脚本添加判断是否需要build tree;
- 添加解码。