kaldi中文语音识别_基于thchs30(6)

时间:2024-03-16 21:14:41

接上回,其实上回我们在make_mfcc.sh中提取特性

$cmd JOB=1:$nj $logdir/make_mfcc_${name}.JOB.log \
    compute-mfcc-feats  $vtln_opts --verbose=2 --config=$mfcc_config \
     scp,p:$logdir/wav_${name}.JOB.scp ark:- \| \
      copy-feats $write_num_frames_opt --compress=$compress ark:- \
      ark,scp:$mfccdir/raw_mfcc_$name.JOB.ark,$mfccdir/raw_mfcc_$name.JOB.scp \
      || exit 1;

在执行这段出现的问题都是因为python环境没有安装好,目前通过升级python为python3版本之后,进行kaldi的编译,后再次执行提取特性是成功的,也就是按照下面这篇文章先进行python的升级和编译安装kaldi
centos7编译安装kaldi,链接是:https://blog.csdn.net/zeratyl/article/details/78646818

我们在编译之前,在kaldi/src/featbin下的compute-mfcc-feats.cc中加入如下打印信息

kaldi中文语音识别_基于thchs30(6)

用于观测compute-mfcc-feats 调用时的参数
然后我们编译kaldi,编译后,我们继续运行原来的 run.sh

其中注释掉($cmd JOB=1:$nj $logdir/make_mfcc_${name}.JOB.log \
    compute-mfcc-feats  $vtln_opts --verbose=2 --config=$mfcc_config \
     scp,p:$logdir/wav_${name}.JOB.scp ark:- \| \
      copy-feats $write_num_frames_opt --compress=$compress ark:- \
      ark,scp:$mfccdir/raw_mfcc_$name.JOB.ark,$mfccdir/raw_mfcc_$name.JOB.scp \
      || exit 1;)后面的
运行后,我们发现在kaldi/egs/thchs30/s5/exp/make_mfcc/train下生成有四个文件
kaldi中文语音识别_基于thchs30(6)
我们打开make_mfcc_train.1.log看一下

kaldi中文语音识别_基于thchs30(6)

kaldi中文语音识别_基于thchs30(6)

我们发现,它里面显示说明了运行compute-mfcc-feats时下发的具体的参数,一开始是计算特征,然后就是拷贝特征,处理每个文件时打印一次,然后看到最后面显示拷贝特征到矩阵。

我们看一下与compute-mfcc-feats.cc的同级目录下的copy-feats.cc,其中就有如下的打印,说明拷贝特征就是运行的这里的。
kaldi中文语音识别_基于thchs30(6)

我们也看到kaldi/egs/thchs30/s5/mfcc/train下生成有ark文件和scp文件,

kaldi中文语音识别_基于thchs30(6)

其中ark文件比较大,我们用一些专业的工具来查看

kaldi中文语音识别_基于thchs30(6)

我们看到第一行是我们在compute-mfcc-feats.cc中加入的打印信息,查看参数用的,然后后面都是一些二进制信息,我们暂且不管,我们再看看scp文件
kaldi中文语音识别_基于thchs30(6)

 

我们看到第一行也是我们的参数打印,然后就是每个ark文件后面加入一个数字,猜想ark的数字就是在ark文件中的位置点,后面在分析。
我们为了分析他们两个是怎么生成这些文件的,所以我们删除s5下的exp和mfcc目录,然后分别执行他们两个命令.
我们先注释掉copy-feats
kaldi中文语音识别_基于thchs30(6)
然后运行run.sh,我们发现在kaldi/egs/thchs30/s5/mfcc/train没有文件生成,说明是copy-feats产生了ark文件和scp文件,而compute-mfcc-feats产生了log日志文件和wav_train.1.scp文件,其实在compute-mfcc-feats命令执行完成以后,后面紧跟着 shell "| 是管道符号 表示前面的命令结果作为后面的命令输入",也就是说compute-mfcc-feats产生的结果要作为copy-feats的输入

我们继续往下看,这块是如果在日志路径下存在错误的日志文件就执行,我们运行时没有发现有错误日志,所以暂且不关心这里
if [ -f $logdir/.error.$name ]; then
  echo "Error producing mfcc features for $name:"
  tail $logdir/make_mfcc_${name}.1.log
  exit 1;
fi
下面这一步其实是将$mfccdir/raw_mfcc_train.1.scp ...... raw_mfcc_train.4.scp合并在一起,前提是需要将上面的$cmd JOB=1 ...命令全部打开,使其生成这些文件
# concatenate the .scp files together. #将.scp文件连接在一起
for n in $(seq $nj); do
  cat $mfccdir/raw_mfcc_$name.$n.scp || exit 1;
done > $data/feats.scp || exit 1  #然后输出到$data/feats.scp中
下面就是由于之前write_utt2num_frames=false,所以不运行
if $write_utt2num_frames; then
  for n in $(seq $nj); do
    cat $logdir/utt2num_frames.$n || exit 1;
  done > $data/utt2num_frames || exit 1
  rm $logdir/utt2num_frames.*
fi
然后是删除日志路径下的wav_train.*.scp,日志下的其他的类似segments.*的文件
rm $logdir/wav_${name}.*.scp  $logdir/segments.* 2>/dev/null

wc命令是统计命令,如文件的字符数等,wc -l是统计行数
-ne 表示 不等于

nf=`cat $data/feats.scp | wc -l` #统计$data/feats.scp文件行数
nu=`cat $data/utt2spk | wc -l` #统计$data/utt2spk文件行数
if [ $nf -ne $nu ]; then
  echo "It seems not all of the feature files were successfully processed ($nf != $nu);"   #打印它看起来不是所有的特征文件都被处理了
  echo "consider using utils/fix_data_dir.sh $data" #考虑使用utils/fix_data_dir.sh $data
fi
我们运行后发现没有打印此处消息,说明所有特征文件都已经处理了

-lt 表示小于

if [ $nf -lt $[$nu - ($nu/20)] ]; then
  echo "Less than 95% the features were successfully generated.  Probably a serious error." #打印成功生成的特征不到95%。可能是一个严重的错误
  exit 1;
fi

我们运行后也没有发现打印此处消息

最后打印了正确的消息
echo "Succeeded creating MFCC features for $name"

未完待续。。。。。。