你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

BrainScript HTKMLF 读取器

警告

HTKMLFReader 已过时,并正被 HTK MLF 和功能反序列化程序所取代,cf. 理解和扩展读取器。 请将这些内容用于网络。

HTKMLFReader 是一种数据读取器,可读取通常与语音识别任务关联的文件,特别是与隐藏的 Markov 模型Toolkit (HTK) 工具套件。 读取器可以将输入两种类型的文件(HTK 分析中已知的功能文件列表)作为 scp 文件 (“脚本”文件) 、称为 mlf 文件 (“模型标签文件”) 和存档文件的标签文件。

HTKMLFReader 依赖于 HTK 定义的数据集格式,因此我们建议使用 HTK Book 等熟悉 HTK 基础知识。

由于CNTK可用于生成具有任意拓扑的网络,包括具有多个输入和输出的网络,因此 HTKMLFReader 可以处理一个或多个scp文件MLF。 HTKMLFReader 的典型用法示例如下所示:

    reader = [
        readerType = "HTKMLFReader"
        readMethod = "blockRandomize"
        miniBatchMode = "partial"
        randomize = "17280000"
        features = [
            dim = 792
            scpFile = "$ScpDir$\TIMIT.train.scp.fbank.fullpath"
        ]
        labels = [
            mlfFile = "$MlfDir$\TIMIT.train.align_cistate.mlf.cntk"
            labelDim = 183
            labelMappingFile = "$MlfDir$\TIMIT.statelist"
        ]
    ]

HTKMLFReader 具有以下配置参数:

  • readMethod:用于在网络训练期间将特征文件读取到内存中进行处理的方法。 blockRandomize设置为readMethod将数据划分为大型块,然后随机化块的顺序,然后随机化块内数据的顺序。 每个块中的数据直接从功能文件读取,并在不再使用 RAM 时从 RAM 中释放。 此选项 blockRandomize 需要一个存档文件,如下所述。 此外,如下面所述,与frameMode = "false"blockRandomize读取方法结合使用时,将随机处理话语,但不会随机化帧。 当需要保留训练示例的顺序性质时,这适用于定期体系结构。 另一种方法是 rollingWindow ,它将读取所有功能文件中,并将其存储在一个大型临时二进制文件中的磁盘上。 然后,通过在此文件中的数据上运行大型滚动窗口并随机化窗口中的数据,从而随机化数据。 仅当存档文件不可用并且仅在帧模式下工作时,才应使用此方法。 默认方法是 blockRandomize

  • pageFilePath:指定应存储功能的临时页面文件的位置。 默认情况下,它将使用系统提供的临时文件。

  • randomize:指定随机化窗口大小。 CNTK使用此大小的滚动窗口来采样数据。 仅此滚动窗口中的样本从磁盘加载,并仅在需要时保存在 RAM 中。 生产大小的语音语料库的建议设置为 48 小时,即指定 17280000。 该 randomize 参数还了解两个特殊值: autononenone 完全禁用随机化,对计算或写入输出数据很有用。 auto 将整个语料库读入 RAM,对于数千小时语音的生产大小数据集来说,这通常不可行或可取。

  • minibatchModepartial 或者 full,如果没有足够的帧来形成所请求大小的完整迷你包,则此选项决定如何处理最后一个迷你包。 默认值为 partial,它将在训练纪元的较小最终迷你包中使用剩余的帧。 该 full 选项将仅处理完整的小型定点。

上面的示例包含读取器正在处理的两个数据源:特征,以 HTK 特征文件列表的形式处理,以及以 HTK MLF 文件的形式处理的标签。 特征和标签都对应于计算网络中节点,在本例中,输入和输出节点分别对应。 请注意, features 并且 labels 是 SimpleNetworkBuilder 使用的默认名称,但如果网络使用网络说明语言 (NDL) ,则只要网络中的每个名称都有相应的节点,就可以使用任何名称。

若要指定连续值特征,例如 MFCC 或日志梅尔筛选器库系数,应将以下参数包含在配置块中:

  • scpFile:要处理的文件的列表。 这些文件应为 HTK 兼容文件,可以采用标准格式或“存档”格式指定。 下面介绍了如何使用存档的详细信息。

  • dim:一个整数,指定具有所需上下文窗口的完整特征向量维度。 例如,如果具有 72 维特征 (24 维筛选器库特征加上增量和增量系数) ,并且网络旨在处理 11 帧的上下文窗口,则指定的维度应为 792。 请注意,仅支持对称上下文窗口。

若要指定相应的标签(例如 phoneme 或 senone 标签),应使用配置块来指定以下参数:

  • mlfFile:一个 HTK 样式 mlf 文件,其中包含文件中指定的 scp 所有话语的标签。

  • labelDim:标签集的总基数。

  • labelMappingFile:文件的路径,其中列出了文件中显示的 mlf 所有标签,每行一个标签。

请注意,可以使用其他读取器块指定多个输入和输出,以便从文件中列出的 scp 文件读取或从文件中读取的标签读取的功能 mlf 。 例如,在多任务学习方案中,网络预测说话人标识和 senone 标签时,用户会指定一个附加块,其中包含 mlf 包含与说话人标识对应的标签的文件。 同样,对于具有多个输入的网络,例如 MFCC 和 PLP 功能,将使用其他功能块。

对于循环结构(如 RNN 或 LSTM),HTKMLFReader 中有其他配置选项

  • frameModetrue 或者 false,读取器是否应在帧级别或言语级别随机化数据。 设置为frameModetrue默认值,适用于不带任何临时连接的训练网络。 对于旨在了解顺序信息(例如 RNN frameMode )的网络,应设置为 false,这意味着话语是随机的,但在话语中维护正确的序列。 请注意,这仅适用于 blockRandomize 读取方法。

  • nbruttsineachrecurrentiter:指定要一起处理的话语数,以便高效训练具有重复性结构的网络。 默认值为 1,但任何低于 20 到 30 的值都会导致 GPU 效率显著下降。

  • truncatedtruefalse。 这会启用截断的 BPTT。

请务必注意,在 HTK 中使用的标准和scpmlf文件与CNTK中使用的文件之间存在一些细微差异。

最值得注意的是, mlf 该文件必须包含用于分类的实际符号。 对于连续语音识别,这通常意味着对应于物理HMstates () 的 senones 的标签。 但是,HVite 通常会在强制对齐期间生成一个 mlf 仅包含逻辑 HMM 状态名称的对齐方式。 因此,若要在CNTK中使用它mlfmlf必须帖子处理才能将逻辑状态名称替换为相应的 senone 标签,或者必须修改 HVite,以便直接写入 senone 标签。

scp HTKMLFReader 处理的文件可以是两个品种之一:标准格式,其中每行对应于物理特征文件,或别名格式,其中每行包含逻辑名称,并引用可能更大的物理文件的段,由开始和结束帧定义。 逻辑名称用于标识文件中的 mlf 相应标签。 即使文件单独存储,就像在第一种情况下一样,别名格式必须始终与读取方法一起使用 blockRandomize ,因为它使用文件中起始和结束帧 scp 的信息来确定言语长度,而无需打开文件本身。 在这种情况下,起始帧应为 0,结束帧应等于话语长度减 1。 此外,对于多个输入和输出,还应使用别名格式,以便所有 scp 文件和 mlf 文件都具有其逻辑名称。 rollingWindow如果使用读取方法而不是blockRandomize读取方法,则可以省略开始和结束帧信息。

下面是 TIMIT 语料库的示例代码片段和mlf文件,scp适合具有 2 个功能输入的网络 (,在本例中,MFCC 和 PLP 功能) 和 1 个对应于音素状态的输出。

该文件 scp 列出了要处理的所有文件,使用以下语法:

id=pathname

在原始 HTK) 中找不到此格式 (的CNTK专有扩展是,CNTK在文件位于特征旁边时scp允许更方便的相对路径名称语法:

id=.../filename

其中 ... 引用文件的目录 scp

scp MFCC 功能的文件包含这些条目。

train-dr1-fcjf0-si1027.mfc=//hostname/data/TIMIT/mfc/train/dr1/fcjf0/train-dr1-fcjf0-si1027.mfc[0,306]

train-dr1-fcjf0-si1657.mfc=//hostname/data/TIMIT/mfc/train/dr1/fcjf0/train-dr1-fcjf0-si1657.mfc[0,281]

train-dr1-fcjf0-si648.mfc=//hostname/data/TIMIT/mfc/train/dr1/fcjf0/train-dr1-fcjf0-si648.mfc[0,359]

scp PLP 功能的文件类似,但指向不同的物理文件。 请注意,这两个 scp 文件中的逻辑根名称相同。

train-dr1-fcjf0-si1027.plp=//hostname/data/TIMIT/plp/train/dr1/fcjf0/train-dr1-fcjf0-si1027. plp[0,306]

train-dr1-fcjf0-si1657.plp=//hostname/data/TIMIT/plp/train/dr1/fcjf0/train-dr1-fcjf0-si1657. plp[0,281]

train-dr1-fcjf0-si648.plp=//hostname/data/TIMIT/plp/train/dr1/fcjf0/train-dr1-fcjf0-si648.plp [0,359]

文件 mlf 使用此语法列出标签:

#!MLF!#
"id"
labelBegin1 labelEnd1 label1
labelBegin2 labelEnd2 label1

...

.
"id"
labelBegin1 labelEnd1 label1
labelBegin2 labelEnd2 label1

...

.

...

此处,我们终止 . 了每个输入文件的 (点) 部分,每个节中的每个标记有一行。 标签时间在时间基 10e-7数中给出,语音帧通常 10e-2为 50,因此需要追加到每次索引的 5 个零

请务必注意,CNTK只读取文件节mlp中的前三列*,并忽略其余列。 在我们的示例中 mlf ,文件还与“'scp”文件共享逻辑名称。 下面是代码片段:

#!MLF!#
"train-dr1-fcjf0-si1027.rec"
0 200000 h#_s2 -136.655975 h# -589.680481 h#
200000 400000 h#_s3 -145.780716
400000 800000 h#_s4 -307.243774
800000 1200000 q_s2 -349.529327 q -897.429504 q
1200000 1500000 q_s3 -280.568817
1500000 1800000 q_s4 -267.331390
1800000 1900000 iy_s2 -76.825096 iy -673.892883 iy
1900000 2400000 iy_s3 -305.832458
2400000 2800000 iy_s4 -291.235352

现在,我们将描述 存档 文件,有时也称为 chunk 文件。 CNTK为其所有读者使用区块的概念,这意味着一个绝对不同的事情,因此为了避免混淆,我们不使用术语区块来处理下面所述的文件,而是将它们称为“存档”。

存档文件基本上是列主矩阵 float32,其中包含包含样本大小和样本数的 12 字节标头。 通常,它们更易于使用,尤其是作为一个开始。 文件的预期标头通过 struct 以下内容定义:

struct fileheader
{
    int nsamples;
    int sampperiod;
    short sampsize;
    short sampkind;
}

其中:

  • sampsize 是矢量的大小(以字节为单位) (=4 * feature dimension) ;
  • sampkind 是功能类型的数字标识符, (MFCC、PLP 等) 。 CNTK忽略此情况。 如果你的文件不是由 HTK 创建的,则只需将此文件设置为 9 (USER) 。 And
  • sampperiod100000 (CNTK主要忽略此值,但错误消息可能) 除外。

最后,请务必注意,在大多数语音识别应用程序中,连续值特征用作输入,而离散分类标签用作输出。 但是,HTKMLFReader 只是将数据与节点名称相关联,并且与使用此数据的方式无关。 例如,可以使用说话 mlf 人标识标签的适当文件生成一个热向量,将说话人标识功能作为网络的输入。