Kaldi命令词识别(续)

作者: zqh_zy | 来源:发表于2017-04-06 15:12 被阅读1384次
    kaldi

    task4 : 特征提取(FMCC)

    完成了语言模型的构建,下面开始生成声学模型部分,首先对语音文件进行特征提取,这里用到了上面准备的文件,包括:text, wav.scp, utt2spk, spk2utt 。
    run.sh中完成特征提取,并对语音进行归一化处理:

    #gen MFCC features
    rm -rf data/mfcc && mkdir -p data/mfcc &&  cp -R data/{train,cv,test} data/mfcc || exit 1;
    for x in train cv test; do
       #make  mfcc 
       steps/make_mfcc.sh --nj $n --cmd "$train_cmd" data/mfcc/$x exp/make_mfcc/$x mfcc/$x || exit 1;
       #compute cmvn
       steps/compute_cmvn_stats.sh data/mfcc/$x exp/mfcc_cmvn/$x mfcc/$x || exit 1;
    done
    

    生成的特征提取相关文件保存在data/mfcc目录下,真实的数据保存在mfcc/目录下。

    task5 : 训练声学模型、 构建解码图

    该部分调用kaldi脚本,训练单音节模型,后面测试证明,单个词汇的识别,该模型同样能保证良好的识别效果,同样run.sh脚本中:

    #monophone
    #steps/train_mono.sh --boost-silence 1.25 --nj $n --cmd "$train_cmd" data/mfcc/train data/lang exp/mono || exit 1;
    
    

    声学模型的训练结果文件保存在exp/mono目录下。下面构建解码图,这部分调用utils/mkgraph.sh, 利用先前创建的语言模型和上步训练的声学模型构建HCLG解码图,该部分生成的解码图保存在exp/mono/graph_word文件夹下:

    utils/mkgraph.sh --mono --nj $n  data/graph/lang exp/mono exp/mono/graph_word  || exit 1;
    

    task6: 测试

    在local目录下创建data_decode.sh 脚本对解码步骤进行封装:

    #!/bin/bash
    #decoding wrapper
    #run from ../
    nj=2
    mono=false
    . ./cmd.sh ## You'll want to change cmd.sh to something that will work on your system.
    . ./path.sh ## Source the tools/utils (import the queue.pl)
    . utils/parse_options.sh || exit 1;
    
    decoder=$1
    srcdir=$2
    datadir=$3
    
    if [ $mono = true ];then
      echo  "using monophone to generate graph"
      opt="--mono"
    fi
    
    #decode word
    $decoder --cmd "$decode_cmd"  $srcdir/graph_word $datadir/test $srcdir/decode_test_word || exit 1
    
    

    在run.sh脚本中调用上脚本:

    #test mono model
    local/data_decode.sh --nj 2 "steps/decode.sh" exp/mono data/mfcc &
    

    这里注意由于测试集只有两个说话者,并发度设置为2,否则会出现文件分割数与并发数不匹配的情况,解码过程主要用到特征提取后的test文件,上部分生成的解码图,测试结果在exp/mono/decode_test_word文件夹中查看。

    为了对测试结果进行评估,还需在local目录下完成打分脚本相关的代码,这里参考thchs30,拷贝文件:score.sh、wer_output_filter 。

    下面给出完整的run.sh脚本,之后运行脚本:

    #!/bin/bash
    
    . ./cmd.sh
    . ./path.sh
    
    run_path=`pwd`
    n=8 #parallel jobs
    
    #dataset path
    dataset=~/dataset_wakeup
    
    #data prepare
    #gen text, wav.scp, utt2spk, spk2utt
    local/data_prep.sh $run_path $dataset/King-ASR-M-005 || exit 1
    
    
    #gen lang dir 
    (
        echo "create new dir data/dict,lang,graph"
        cd $run_path
        mkdir -p data/{dict,lang,graph} && \
        cp $dataset//resource/dict/{extra_questions.txt,nonsilence_phones.txt,optional_silence.txt,silence_phones.txt} data/dict && \
        cat $dataset/resource/dict/lexicon.txt | \
        grep -v '<s>' | grep -v '</s>' | sort -u > data/dict/lexicon.txt || exit 1;
        utils/prepare_lang.sh --position_dependent_phones false data/dict "<SPOKEN_NOISE>" data/local/lang data/lang || exit 1;
        gzip -c $dataset/King-ASR-M-005/lm_word/word.arpa > data/graph/word.arpa.gz || exit 1;
        utils/format_lm.sh data/lang data/graph/word.arpa.gz $dataset/King-ASR-M-005/lm_word/lexicon.txt data/graph/lang || exit 1;
    )
    
    #gen MFCC features
    rm -rf data/mfcc && mkdir -p data/mfcc &&  cp -R data/{train,cv,test} data/mfcc || exit 1;
    for x in train cv test; do
       #make  mfcc 
       steps/make_mfcc.sh --nj $n --cmd "$train_cmd" data/mfcc/$x exp/make_mfcc/$x mfcc/$x || exit 1;
       #compute cmvn
       steps/compute_cmvn_stats.sh data/mfcc/$x exp/mfcc_cmvn/$x mfcc/$x || exit 1;
    done
    
    #monophone
    steps/train_mono.sh --boost-silence 1.25 --nj $n --cmd "$train_cmd" data/mfcc/train data/lang exp/mono || exit 1;
    #decode word
    
    # make decoder graph
    utils/mkgraph.sh --mono  data/graph/lang exp/mono exp/mono/graph_word  || exit 1;
    
    #test mono model
    local/data_decode.sh --nj 2 "steps/decode.sh" exp/mono data/mfcc &
    
    

    运行脚本,由于数据量不大,并不需要很长时间,运行测试结束查看效果:

    [uesrname@hostname scoring_kaldi]$ ls
    best_wer  log  penalty_0.0  penalty_0.5  penalty_1.0  test_filt.txt  wer_details
    [uesrname@hostname scoring_kaldi]$ more best_wer 
    %WER 5.57 [ 100 / 1795, 19 ins, 4 del, 77 sub ] exp/mono/decode_test_word/wer_17_1.0
    

    错词率为5.57%,在penalty_1.0中可以查看最好的识别结果。

    小结

    文章记录了从拿到语料库,到应用Kaldi的全过程,主要想对流程进行总结,对语音识别相关的原理没有涉及太多。另外这里仅仅训练了单音节模型,其他模型可以参照thchs30完成,这里不再补充。
    过程中遇到的小问题很多,一个比较典型的,一开始想偷懒直接使用thchs30的词典,后来识别结果很差,单词均为一个或两个毫不相干的字。考虑自己语料库中的词汇在thchs30的词典中并未涉及,还是通过自己标注词典解决问题。

    考虑篇幅,未完待续,原创文章,转载注明出处。
    更多关注公众号:

    wechat

    相关文章

      网友评论

      • xxoospring:楼主你好,你这个数据集中的录音只是一个个的词还是一句句的话?能否将你这个数据集分享出来,你这个博客实在是不错。
        zqh_zy:@xxoospring 就是唤醒词的demo,只是是个玩具数据集,一共只有300个不同的app名词,好像分多人说的
        xxoospring:@zqh_zy 不好意思,我后面看到你的评论了,我已经在那个商城买了。楼住,我想问一下,这个可以作为唤醒词识别的一个demo吗?或者唤醒词和这个有什么区别吗?
        zqh_zy:@xxoospring 数据貌似不太方便分享:smile:
      • YANGDQIANG:楼主您好,我参考您的文章做了一下实验,错误率5%,看起来很好,但是用在线识别效果不是很好,可能对环境要求比较高吧!我还有一个疑问,就是将句子分词,然后跑出来,效果非常差,不知道什么原因!
        zqh_zy:您好,句子分词后可能是给语言模型增加了难度,但是我想如果数据量足够,泛化效果可能要更好一些

      本文标题:Kaldi命令词识别(续)

      本文链接:https://www.haomeiwen.com/subject/enlqattx.html