zoukankan      html  css  js  c++  java
  • Kaldi样例实战

    一.前提条件

      在kaldi目录下的子目录kaldi/egs/目录下保存着资源管理示例脚本。查看该目录中的README.txt文件,尤其是查看资源管理部分,它提到 与语料库相对应的LDC目录号。这可以从LDC获取数据。

      

      

      进入rm目录,浏览README.txt文件查看整体结构,进入s5子目录,在s5目录中,列出并浏览RESULTS文件,以便对其中的内容有所了解。其中最重要的文件是run.sh。注意,run.sh不能直接执行,必须手动执行文件中的一系列命令。

      

      

    二.资料准备

      首先,需要配置作业,如果没有安装GridEngine【分布式资源管理工具】,或者是使用较小的数据集进行实验,可以在shell上执行以下命令:

      

      如果安装了GridEngine,则应将queue.pl文件与指定GridEngine驻留位置的参数一起使用。在这种情况下,执行以下命令【参数-q是示例,在实际应用中替换为GridEngine详细信息】:

      train_cmd=" queue.pl -q all.q@a*.clsp.jhu.edu"
      encode_cmd="queue.pl -q all.q@[ah]*.clsp.jhu.edu"

      下一步是从rm语料库中创建测试和训练集。为此,执行以下命令【假设要测试的数据在./export/LDC/LDC2019S20/rm_comp/下,此数据可以去KALDI下载,需要付费】

      

      命令:./local/rm_data_prep.sh /export/LDC/LDC2019S20/rm_comp/

      执行成功后,会在当前目录下创建data的新目录。这个新目录包含三种主要的文件夹类型:

        ·local:包含当前数据的字典。

        ·train:从语料库中分割出来的用于训练的数据。

        ·test_*:从语料库中分割出来的数据,用于测试。

      

      在数据目录下执行下面的命令:

      cd local/dict
      head lexicon.txt
      head nonsilence_phones.txt
      head silence_phones.txt

      使用这些命令可以大致了解通用数据准备过程的输出。应该意识到,并非所有的这些文件都是本地Kaldi格式,即,并非所有文件都可以被Kaldi的C++程序读取,部分还需要使用Kaldi之前使用OpenFST工具进行处理。

        lexicon.txt:词典

        *silence*.txt:这些文件包含有关电话静音已经保持静音的信息。

      在train目录下,执行以下命令:

      head text
      head spk2gender
      head spk2utt
      head utt2spk
      head wav.scp

      ·text:该文件包含发声和发声ID之间的映射,这些映射将由Kaldi使用。该文件将转换为整数格式,但仍然是文本文件,单词将被替换为整数。

      ·spk2gender:该文件包含说话人及其性别之间的映射。这将充当参与培训的唯一用户列表。

      .spk2utt:这是说话者标识符与说话者相关的所有话语标识符之间的映射。

      .utt2spk:这是发话ID与相应说话者标识符之间的一对一映射。

      ·wav.scp-Kaldi程序在进行特征提取时实际上直接读取该文件。再次查看该文件,它被解析成一组键值对,其中键是每一行的第一个字符串。该值是一种“扩展文件名”。请注意,尽管我们使用扩展名.scp,但从HTK的角度来看,它不是脚本文件。

      train文件夹和test_*文件夹的结构相同。但是,train数据的大小明显大于test_*数据。可以通过返回数据目录并执行以下命令来验证这一点,该命令将给出训练集和测试集的字数:wc train/text test_feb89/text

      下一步是创建Kaldi使用的原始语言文件。在大多数情况下,这些文件将是整数格式的文本文件。确保返回到s5目录,并执行以下命令:

        utils/prepare_lang.sh data/local/dict '!SIL' data/local/lang data/lang

      这将在本地文件夹中创建一个名为lang的新文件夹,其中将包含描述所用语言的FST。看一下脚本。它将以data/创建的某些文件转化为Kaldi读取的规范形式。该脚本在data/lang/目录中创建其输出。该脚本创建的前两个文件称为words.txt和phones.txt【都在data/lang/下】。这些是OpenFst格式的符号表,表示从字符串到整数再到整数的映射。查看这些文件,它们很重要并且会经常使用。

      查看后缀为.csl的文件【在data/lang/phones中】,这些分别是冒号分隔的非静音和静音电话的整数ID列表。有时需要它们作为程序命令行上的选项,以及其它目的。

      查看phone.txt【在data/lang/中】,该文件是电话符号表,还处理标准FST中使用的"消歧符号"。这些符号通常称为#1,#2等。其中符号#0用来替换语言模型中的epsilon转换。

      文件L.fst是FST格式的编译词典。要查看其中包含哪种信息,可以执行以下操作:

        fstprint --isymbols=data/lang/phones.txt --osymbols=data/lang/words.txt data/lang/L.fst | head

      如果bash找不到命令fstprint,则需要将OpenFST的安装路径添加到PATH环境变量中。只需要运行脚本path.sh即可:

        ../path.sh

      下一步是使用在上一步中创建的文件来创建描述该语言语法的FST。为此,返回目录s5并执行以下命令:

        ./local/rm_prepare_gtammar.sh

      如果成功,则应该返回消息"成功为RM准备语法"。将在/data/lang中创建一个名为G.fst的新文件。

    三.特征提取

      1.提取训练功能   

    export featdir=/my/disk/rm_mfccdir
    # make sure featdir exists and is somewhere you can write.
    # can be local if you want.
    mkdir $featdir
    for x in test_mar87 test_oct87 test_feb89 test_oct89 test_feb91 test_sep92 train; do 
      steps/make_mfcc.sh --nj 8 --cmd "run.pl" data/$x exp/make_mfcc/$x $featdir; 
      steps/compute_cmvn_stats.sh data/$x exp/make_mfcc/$x $featdir; 
    done

      运行这些作业,它们并行使用多个CPU,可以根据计算机的CPU数量更改-nj选项【指定要运行的作业数量】。查看文件exp /make_mfcc/train/make_mfcc.1.log以查看创建MFCC程序的日志输出。

      2.核心概念

      表的概念是基础脚本和归档文件。表格基本上是一组有序的项目,由唯一的字符串索引。Table并不是真正的C++对象,因为有单独的C++对象来访问数据,具体取决于我们是编写、迭代还是进行随机访问。类型的示例数据如下: 

    BaseFloatMatrixWriter
    RandomAccessBaseFloatMatrixReader
    SequentialBaseFloatMatrixReader

      这些类型都是实际为模板类的typedef。脚本【.scp】文件或存档【.ark】文件都被视为数据表。格式如下:

        ·脚本格式是纯文本格式,其中包含带有键的行,然后是扩展文件名,该文件名告诉Kaldi在哪里可以找到数据。

        ·存档格式可以是文本或二进制。格式为键+空格+对象数据。

      有关脚本和档案的一些一般要点:

        ·指定如何读取表的字符串称为rspecifier。例如:ark:gunzip -c my/dir/foo.ark.gz|

        ·指定如何编写表的字符串称为wspecifier。例如:ark,t:foo.ark

        ·归档可以串联在一起,仍然是有效的归档。

        ·该代码可以顺序或通过随机访问读取脚本和存档。用户级代码仅知道它是在迭代还是在进行查找。它不知道它是在访问脚本还是存档。

        ·Kaldi不会尝试在归档文件中表示对象类型。必须提前知道对象类型。

        ·归档文件和脚本文件不能包含类型的混合。

        ·由于代码可能必须将对象缓存在内存中,因此通过随机访问读取档案可能会导致内存效率低下。

        ·为了有效地随机访问档案,可以使用ark,scp写入机制来写入相应的脚步文件。然后通过scp文件访问它。

        ·避免对文档进行随机访问时内存中缓存了大量数据。

        ·对代码文档进行排序并且按照顺序进行调用。

        ·读写档案的类型以Holder类型为模板,该类型知道如何读取和写入相关对象。

  • 相关阅读:
    Java 集合系列06之 Vector详细介绍(源码解析)和使用示例
    Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例
    Java 集合系列04之 fail-fast总结(通过ArrayList来说明fail-fast的原理、解决办法)
    linked-list-cycle-ii-LeetCode
    reorder-list-LeetCode
    sum-root-to-leaf-numbers-LeetCode
    binary-tree-maximum-path-sum-LeetCode
    机器人的运动范围-剑指Offer
    矩阵中的路径-剑指Offer
    滑动窗口的最大值-剑指Offer
  • 原文地址:https://www.cnblogs.com/yszd/p/12168201.html
Copyright © 2011-2022 走看看