#!/bin/bash # Set -e here so that we catch if any executable fails immediately set -euo pipefail # (some of which are also used in this script directly). stage=-1 decode_nj=10 train_set=train gmm=tri3 nnet3_affix= suffix= # The rest are configs specific to this script. Most of the parameters # are just hardcoded at this level, in the commands below. affix= # affix for the TDNN directory name tree_affix= train_stage=-10 get_egs_stage=-10 decode_iter= # training options # training chunk-options chunk_width=140,100,160 common_egs_dir= xent_regularize=0.1 dropout_schedule='0,0@0.20,0.5@0.50,0' # training options srand=0 remove_egs=true # End configuration section. echo "$0 $@" # Print the command line for logging . ./cmd.sh . ./path.sh . ./utils/parse_options.sh # Problem: We have removed the "train_" prefix of our training set in # the alignment directory names! Bad! gmm_dir=exp/$gmm ali_dir=exp/${gmm}_ali tree_dir=exp/chain${suffix}/tree${tree_affix:+_$tree_affix} lang=data/lang_chain${suffix} lat_dir=exp/chain${suffix}/${gmm}_${train_set}_lats dir=exp/chain${suffix}/tdnn${affix} train_data_dir=data/${train_set} for f in $gmm_dir/final.mdl $train_data_dir/feats.scp $ali_dir/ali.1.gz; do [ ! -f $f ] && echo "$0: expected file $f to exist" && exit 1 done if [ $stage -le 9 ]; then local/chain/run_ivector_common.sh \ --train-set ${train_set} \ --gmm ${gmm} \ --suffix "${suffix}" fi if [ $stage -le 10 ]; then echo "$0: creating lang directory $lang with chain-type topology" rm -rf $lang cp -r data/lang $lang silphonelist=$(cat $lang/phones/silence.csl) nonsilphonelist=$(cat $lang/phones/nonsilence.csl) steps/nnet3/chain/gen_topo.py $nonsilphonelist $silphonelist >$lang/topo fi if [ $stage -le 11 ]; then steps/align_fmllr_lats.sh --nj 20 --cmd "$train_cmd" ${train_data_dir} \ data/lang $gmm_dir $lat_dir fi if [ $stage -le 12 ]; then steps/nnet3/chain/build_tree.sh \ --frame-subsampling-factor 3 \ --context-opts "--context-width=2 --central-position=1" \ --cmd "$train_cmd" 2500 ${train_data_dir} \ $lang $ali_dir $tree_dir fi if [ $stage -le 13 ]; then echo "$0: creating neural net configs using the xconfig parser"; num_targets=$(tree-info $tree_dir/tree | grep num-pdfs | awk '{print $2}') learning_rate_factor=$(echo "print (0.5/$xent_regularize)" | python) affine_opts="l2-regularize=0.008 dropout-proportion=0.0 dropout-per-dim=true dropout-per-dim-continuous=true" tdnnf_opts="l2-regularize=0.008 dropout-proportion=0.0 bypass-scale=0.75" linear_opts="l2-regularize=0.008 orthonormal-constraint=-1.0" prefinal_opts="l2-regularize=0.008" output_opts="l2-regularize=0.002" mkdir -p $dir/configs cat < $dir/configs/network.xconfig input dim=40 name=ivector input dim=40 name=input idct-layer name=idct input=input dim=40 cepstral-lifter=22 affine-transform-file=$dir/configs/idct.mat batchnorm-component name=batchnorm0 input=idct spec-augment-layer name=spec-augment freq-max-proportion=0.5 time-zeroed-proportion=0.2 time-mask-max-frames=20 delta-layer name=delta input=spec-augment no-op-component name=input2 input=Append(delta, ReplaceIndex(ivector, t, 0)) # the first splicing is moved before the lda layer, so no splicing here relu-batchnorm-dropout-layer name=tdnn1 $affine_opts dim=512 input=input2 tdnnf-layer name=tdnnf2 $tdnnf_opts dim=512 bottleneck-dim=96 time-stride=1 tdnnf-layer name=tdnnf3 $tdnnf_opts dim=512 bottleneck-dim=96 time-stride=1 tdnnf-layer name=tdnnf4 $tdnnf_opts dim=512 bottleneck-dim=96 time-stride=1 tdnnf-layer name=tdnnf5 $tdnnf_opts dim=512 bottleneck-dim=96 time-stride=0 tdnnf-layer name=tdnnf6 $tdnnf_opts dim=512 bottleneck-dim=96 time-stride=3 tdnnf-layer name=tdnnf7 $tdnnf_opts dim=512 bottleneck-dim=96 time-stride=3 tdnnf-layer name=tdnnf8 $tdnnf_opts dim=512 bottleneck-dim=96 time-stride=3 tdnnf-layer name=tdnnf9 $tdnnf_opts dim=512 bottleneck-dim=96 time-stride=3 tdnnf-layer name=tdnnf10 $tdnnf_opts dim=512 bottleneck-dim=96 time-stride=3 tdnnf-layer name=tdnnf11 $tdnnf_opts dim=512 bottleneck-dim=96 time-stride=3 tdnnf-layer name=tdnnf12 $tdnnf_opts dim=512 bottleneck-dim=96 time-stride=3 linear-component name=prefinal-l dim=192 $linear_opts ## adding the layers for chain branch prefinal-layer name=prefinal-chain input=prefinal-l $prefinal_opts small-dim=192 big-dim=512 output-layer name=output include-log-softmax=false dim=$num_targets $output_opts # adding the layers for xent branch prefinal-layer name=prefinal-xent input=prefinal-l $prefinal_opts small-dim=192 big-dim=512 output-layer name=output-xent dim=$num_targets learning-rate-factor=$learning_rate_factor $output_opts EOF steps/nnet3/xconfig_to_configs.py --xconfig-file $dir/configs/network.xconfig --config-dir $dir/configs/ fi if [ $stage -le 14 ]; then steps/nnet3/chain/train.py --stage $train_stage \ --cmd "$cuda_cmd" \ --feat.online-ivector-dir exp/chain${suffix}/ivectors_${train_set} \ --feat.cmvn-opts "--norm-means=false --norm-vars=false" \ --chain.xent-regularize $xent_regularize \ --chain.leaky-hmm-coefficient 0.1 \ --chain.l2-regularize 0.0 \ --chain.apply-deriv-weights false \ --chain.lm-opts="--num-extra-lm-states=2000" \ --egs.cmd "$get_egs_cmd" \ --egs.dir "$common_egs_dir" \ --egs.stage $get_egs_stage \ --egs.opts "--frames-overlap-per-eg 0 --constrained false" \ --egs.chunk-width $chunk_width \ --trainer.dropout-schedule $dropout_schedule \ --trainer.add-option="--optimization.memory-compression-level=2" \ --trainer.num-chunk-per-minibatch 64 \ --trainer.frames-per-iter 2500000 \ --trainer.num-epochs 20 \ --trainer.optimization.num-jobs-initial 1 \ --trainer.optimization.num-jobs-final 1 \ --trainer.optimization.initial-effective-lrate 0.001 \ --trainer.optimization.final-effective-lrate 0.0001 \ --trainer.max-param-change 2.0 \ --cleanup.remove-egs $remove_egs \ --feat-dir $train_data_dir \ --tree-dir $tree_dir \ --lat-dir $lat_dir \ --dir $dir || exit 1; fi