• kaldi学习


      参考文档:http://www.cnblogs.com/welen/p/7485151.html 

       写在前面,本文虽然对大多数脚本进行了解释,但只是初学者的理解,如果你认为读起来不知所云,建议从 kaldi 官方文档 读起,两边配合理解,可以解决很多看起来好像很难理解的东西。(官方文档地址: http://www.kaldi-asr.org/doc/data_prep.html )

      今天开始了kaldi脚本的学习,首先从kaldi 最简单的demo开始。

      路径: kaldi-trunk/egs/yesno/s5

      运行: ./run.sh

      目前代码:

     1 #!/bin/bash
     2 
     3 #====
     4 # run.sh 的代码会展现清晰的语音处理的过程,目前学习到 数据准备阶段的 prepare_data.sh
     5 #====
     6 
     7 train_cmd="utils/run.pl"
     8 decode_cmd="utils/run.pl"
     9 
    10 #====
    11 #waves_yesno 用于存储语音文件,检测到本目录不存在,就去指定链接下载语音包
    12 #====
    13 if [ ! -d waves_yesno ]; then
    14   wget http://www.openslr.org/resources/1/waves_yesno.tar.gz || exit 1;
    15   # was:
    16   # wget http://sourceforge.net/projects/kaldi/files/waves_yesno.tar.gz || exit 1;
    17   tar -xvzf waves_yesno.tar.gz || exit 1;
    18 fi
    19 
    20 
    21 train_yesno=train_yesno
    22 test_base_name=test_yesno
    23 
    24 #====
    25 # -r :rm 命令参数,递归删除
    26 # -f :rm 命令参数,递归删除
    27 # but I don not know why remove them
    28 #====
    29 rm -rf data exp mfcc
    30 
    31 # Data preparation
    32 
    33 #====
    34 # 目前只看到这里
    35 #====
    36 local/prepare_data.sh waves_yesno
     
     1. local/prepare_data.sh 
    #!/bin/bash
    #egs/yesno/s5/local/prepare_data.sh
    
    #====
    # -p means make all dirs if there is no such dir 
    #====
    mkdir -p data/local
    local=`pwd`/local
    scripts=`pwd`/scripts
    
    export PATH=$PATH:`pwd`/../../../tools/irstlm/bin
    
    echo "Preparing train and test data"
    
    #====
    #  $1 : shell 命令,指的是文件运行时传进来的第一个参数,自然 $2,$3就指的是第2,3个命令行参数
    #         这里 $1 =  waves_yesno
    #====
    train_base_name=train_yesno
    test_base_name=test_yesno
    waves_dir=$1
    
    
    
    #====
    # ls -1 : 所有的文件和目录都单行显示,每个文件或者目录占一行
    # > : 指的是重定向输出,后面跟的就是输出到哪一个文件。具体可以查找Linux重定向相关内容 
    # 形式: ls [option] > outputfile # 这里是把刚才下载的语音包的所有文件名都提取出来,写进data/local/waves_all.list # 目的是为了保存语音文件的文件名,后面建立语音ID与语音文本的对应还会用到这些文件名 #==== ls -1 $waves_dir > data/local/waves_all.list #==== # 下面几行代码创建的文件(比如waves.test waves.train)都在这个文件夹下面 #==== cd data/local. #==== # waves_all.list 的文件名被分成了两个部分, # 一部分放进了waves.test,用于测试 # 一部分放进了waves.train,用于训练
    # 具体代码在下一小节 #==== ../../local/create_yesno_waves_test_train.pl waves_all.list waves.test waves.train #==== # ../../local/create_yesno_wav_scp.pl waves_yesno waves.test > test_yesno_wav.scp # test_yesno_wav.scp 保存的是语音ID 以及 对应的语音文件名 # 就像这样 : 0_0_0_0_1_1_1_1 waves_yesno/0_0_0_0_1_1_1_1.wav # > : 重定向输出。 # ../../local/create_yesno_wav_scp.pl 里面有一个输出语句,输出语句的输出内容被重定向输出到了test_yesno_wav.scp #==== ../../local/create_yesno_wav_scp.pl ${waves_dir} waves.test > ${test_base_name}_wav.scp ../../local/create_yesno_wav_scp.pl ${waves_dir} waves.train > ${train_base_name}_wav.scp #==== # test_yesno.txt 保存的是语音ID以及语音文本的对应关系 # 像这样 : 0_0_1_1_1_1_0_0 NO NO YES YES YES YES NO NO #==== ../../local/create_yesno_txt.pl waves.test > ${test_base_name}.txt ../../local/create_yesno_txt.pl waves.train > ${train_base_name}.txt cp ../../input/task.arpabo lm_tg.arpa cd ../.. # This stage was copied from WSJ example #==== # 大概就是生成了两个文件 # spk2utt 发音人 - 发音id 对应关系 # utt2spk 发音id - 发音人 对应关系 #==== for x in train_yesno test_yesno; do mkdir -p data/$x cp data/local/${x}_wav.scp data/$x/wav.scp cp data/local/$x.txt data/$x/text cat data/$x/text | awk '{printf("%s global ", $1);}' > data/$x/utt2spk utils/utt2spk_to_spk2utt.pl <data/$x/utt2spk >data/$x/spk2utt do

      至此,prepare_data.sh 代码阅读完毕

      目录结构是这样的:

      

      目录结构如下:(来自WELEN的博客)
    data
    ├───train_yesno   训练文件夹
    │   ├───text      (发音id 发音文本)
    │   ├───utt2spk   (发音id 发音人)
    │   ├───spk2utt   (发音人 发音id)
    │   └───wav.scp   (发音id 发音文件)
    └───test_yesno
        ├───text
        ├───utt2spk
        ├───spk2utt
        └───wav.scp
     
      2. 再看下create_yesno_waves_test_train.pl
      
     1 #!/usr/bin/env perl
     2 
     3 #====
     4 # ARGV[]:perl 的命令行参数数组
     5 # 根据prepare_data.sh 知道三个参数分别是 
     6 # waves_all.list , waves.test , waves.train
     7 #====
     8 $full_list = $ARGV[0];
     9 $test_list = $ARGV[1];
    10 $train_list = $ARGV[2];
    11 
    12 #====
    13 # open : perl文件操作函数, 文件操作都是通过文件句柄
    14 #     形式: open FILEHANDLE FILENAME
    15 # <filehandle> 是文件信息读取运算符,按行读取
    16 # 这个循环得到了语音文件的总数,为下一步把文件名分成两部分做准备
    17 #====
    18 open FL, $full_list;
    19 $nol = 0;
    20 while ($l = <FL>)
    21 {
    22     $nol++;
    23 }
    24 close FL;
    25 
    26 #====
    27 # > : open 函数中对文件的操作方式,具体可以查找网上 perl open函数 相关内容
    28 # chomp: 大概的作用就是去掉当前行的末尾的换行符
    29 #====
    30 $i = 0;
    31 open FL, $full_list;
    32 open TESTLIST, ">$test_list";
    33 open TRAINLIST, ">$train_list";
    34 #====
    35 # this while(){} shows what this .pl file do:
    36 # divide all data into two part,
    37 # first part will put in waves.train
    38 # the second 30 files' name will put in waves.test
    39 #====
    40 while ($l = <FL>)
    41 {
    42     chomp($l);
    43     $i++;
    44     if ($i <= $nol/2 )
    45     {
    46         print TRAINLIST "$l
    ";
    47     }
    48     else
    49     {
    50         print TESTLIST "$l
    ";
    51     }
    52 }

      3. create_yesno_wav_scp.pl

    #!/usr/bin/env perl
    
    #====
    # $ARGV[0] = waves_yesno 
    # ARGV[1] = waves.test
    #====
    $waves_dir = $ARGV[0];
    $in_list = $ARGV[1];
    
    open IL, $in_list;
    
    #====
    # 把语音ID-语音文件的对应关系输出到 对应文件
    # final output like this : 0_0_0_0_1_1_1_1 waves_yesno/0_0_0_0_1_1_1_1.wav 
    # line 2: 
    #        "." :应该只是连接符号,但是不确定,没有查到
    #         “/”: 是转义字符,所以full_path应该是这样的:waves_yesno/0_0_0_0_1_1_1_1.wav
    # line 3: =~ s/// 是perl的替换符 
    #         形式: =~ s/pattern/replacement/[option]
    #             具体可以查看网上 perl s/// 操作符的内容
    # line 4: print strings will rewrite into test_yesno_wav.scp which have been gave in prepare_data.sh
    #====
    while ($l = <IL>)
    {
        chomp($l);
        $full_path = $waves_dir . "/" . $l;
        $l =~ s/.wav//;
        print "$l $full_path
    ";
    }

      

      4.create_yesno_txt.pl

    #!/usr/bin/env perl
    
    #====
    # ARGV[0] = waves.test
    # in_list = waves.test
    #====
    $in_list = $ARGV[0];
    
    open IL, $in_list;
    
    #====
    # here will replace all 0 as NO  ,all 1 as YES, all — as sapce
    # print will rewrite into test_yesno.txt which has been gave in prepare_data.sh
    # g : option of =~ s/patterns/replacement/[option]
    #     replace all patterns in string as replacement
    #====
    while ($l = <IL>)
    {
        chomp($l);
        $l =~ s/.wav//;
        $trans = $l;
        $trans =~ s/0/NO/g;
        $trans =~ s/1/YES/g;
        $trans =~ s/\_/ /g;
        print "$l $trans
    ";
    }

      5. 阶段性小结 

      5.1

        综上,数据准备阶段的 prepare_data.sh 的工作,主要集中在 egs/yesyno/s5/data 目录,完成的工作基本上可以看做是数据标注,将语音包分成两部分,一部分用于训练,一部分用于测试训练的模型。

        比如 text 文件,就将语音进行了标注,指出每一个语音对应的文字内容。wav.scp 就标注出了语音对应的语音文件。 

      5.2

        数据准备阶段完成的工作包括,

          下载语音包,

          建立必要的工作目录以及文件,

            包括训练使用的目录,

              建立的文件用于建立对应关系便于训练

                发音ID - 发音文本

                发音ID - 发音文件

                发音ID - 发音人

                发音人  - 发音ID

            包括测试使用的目录,

              建立的文件用于建立对应关系便于测试,检查测试结果

                发音ID - 发音文本

                发音ID - 发音文件

                发音ID - 发音人

                发音人  - 发音ID

  • 相关阅读:
    结对第一次—疫情统计可视化(原型设计)
    软工实践寒假作业(2/2)
    软工实践寒假作业(1/2)
    Luogu P3975 [TJOI2015]弦论
    【模板】后缀自动机 (SAM)
    停用FF新鲜事/FF新推荐
    模板汇总
    Luogu P4467 [SCOI2007]k短路(模板)
    【模板】 最短路
    Luogu P5960 【模板】差分约束算法
  • 原文地址:https://www.cnblogs.com/gstblog/p/8933797.html
Copyright © 2020-2023  润新知