你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
BrainScript CNTK文本格式读取器
本页从 BrainScript 的角度记录 CNTKTextFormatReader,但 Python 用户也可以通过阅读本文档来学习 -- 概念、参数和模式都是相同的。
CNTKTextFormatReader (稍后只需 CTF 读取器) 即可使用根据以下规范设置格式的输入文本数据。 它支持以下主要功能:
- 每个文件 (输入) 多个输入流
- 稀疏和密集输入
- 可变长度序列
CNTK文本格式 (CTF)
输入文件中的每一行都包含一个用于一个或多个输入的示例。 由于 (显式或隐式) 每个行也附加到序列,因此它定义一个或多个 <序列、输入、样本> 关系。 每个输入行的格式必须如下所示:
[Sequence_Id](Sample or Comment)+
where
Sample=|Input_Name (Value )*
Comment=|# some content
- 每行以序列 ID 开头,并包含一个或多个示例 (,换而言之,每行都是) 的无序样本集合。
- 序列 ID 是一个数字。 可以省略它,在这种情况下,行号将用作序列 ID。
- 每个示例实际上是一个键值配对由输入名称组成,相应的值向量 (映射到更高维度) 作为网络本身的一部分完成。
- 每个示例都以管道符号开头, (
|
) 后跟输入名称 (没有空格) ,后跟空格分隔符,然后是值列表。 - 每个值是稀疏输入的数字或索引前缀的数字。
- 制表符和空格都可以互换用作分隔符。
- 批注以管道开头,后跟哈希符号:
|#
然后是实际内容 (正文) 批注。 正文可以包含任何字符,但是需要通过将哈希符号追加到正文中的管道符号来转义, (请参阅以下示例) 。 批注正文一直持续到行尾或下一个未转义管道,以先行为准。
简单示例
此示例基于最小一组参数和格式选项。
若要使用 CTF 读取器,readerType
请在CNTK配置的读取器部分中设置:CNTKTextFormatReader
...
reader = [
readerType = "CNTKTextFormatReader"
file = "c:\mydata\SampleInput.txt" # See the second example for Linux path example
# IMPORTANT!
# All inputs are grouped within "input" sub-section.
input = [
A = [
dim = 5
format = "dense"
]
B = [
dim = 1000000
format = "sparse"
]
C = [
dim = 1
format = "dense"
]
]
]
# the rest of the cntk config ...
(本文档中此片段和其他 NDL 示例仅reader
显示一节,省略CNTK配置的其余部分;有关指向一组完整示例网络和相应数据集)
CTF 读取器需要以下一组参数:
file
- 包含数据集的文件的路径。input
- 定义输入名称 (A
标识的输入的子节,B
C
并在上面的示例中) 。 在每个输入中,必须指定以下必需参数:format
- 指定输入类型。dense
必须是或sparse
dim
- 为 密集 输入指定输入值向量 (的维度,这直接对应于每个样本中的值数,对于 稀疏 ,这表示) 可能索引值范围的上限。
与上述读取器配置对应的输入数据应如下所示:
|B 100:3 123:4 |C 8 |A 0 1 2 3 4 |# a CTF comment
|# another comment |A 0 1.1 22 0.3 54 |C 123917 |B 1134:1.911 13331:0.014
|C -0.001 |# a comment with an escaped pipe: '|#' |A 3.9 1.11 121.2 99.13 0.04 |B 999:0.001 918918:-9.19
请注意以下有关输入格式的信息:
|Input_Name
标识每个输入示例的开头。 此元素是必需的,后跟对应值向量。- 密集向量只是浮点值的列表;稀疏向量是元组的列表
index:value
。 - 在 输入向量) 以及 输入 分隔符之间 (输入) 之间,选项卡和空格都允许作为值分隔符 (。
- ) 下面的扩展示例中介绍了每个单独的行构成长度为 1 (“Real”可变长度序列的“序列”。
- 每个输入标识符只能在单个行上显示一次, (每行要求每个输入转换为 一个样本) 。
- 在概念上,行内输入样本的顺序并不重要 (,每行都是键值对的无序集合)
- 每个格式良好的线条必须以“换行符”
\n
或“回车符、换行符”\r\n
符号结尾。
扩展示例
此示例包含所有可能的配置参数,并显示各种输入格式选项。 有关此示例中使用的配置参数的完整说明,请参阅 下表 。
...
precision="double"
reader = [
readerType = "CNTKTextFormatReader"
file = "/home/mydata/SampleInput.txt" # See the first example for Windows style path example
randomize = true
randomizationWindow = 30
skipSequenceIds = false
maxErrors = 100
traceLevel = 2
chunkSizeInBytes = 1024
keepDataInMemory = true
frameMode = false
input = [
Some_very_long_input_name = [
alias = "a"
dim = 3
format = "dense"
]
Some_other_also_very_long_input_name = [
alias = "b"
dim = 2
format = "dense"
]
]
]
# the rest of the cntk config ...
使用复合读取器,如下所示:
reader = {
verbosity = 0 ;
randomize = true;
randomizationWindow=30
deserializers = ({
type = "CNTKTextFormatDeserializer" ; module = "CNTKTextFormatReader"
file = "/home/mydata/SampleInput.txt" # See the first example for Windows style path example
maxErrors = 100
skipSequenceIds = false
traceLevel = 2
input = {
qu1fea = {alias = "qui"; dim = 95589; format = "sparse"}
qu2fea = {alias = "quj"; dim = 95589; format = "sparse"}
pairweight = {alias = "wij"; dim = 1; format = "dense"}
}
})
}
然后,相应的输入文件可以大致如下所示:
100 |a 1 2 3 |b 100 200
100 |a 4 5 6 |b 101 201
100 |b 102983 14532 |a 7 8 9
100 |a 7 8 9
200 |b 300 400 |a 10 20 30
333 |b 500 100
333 |b 600 -900
400 |a 1 2 3 |b 100 200
|a 4 5 6 |b 101 201
|a 4 5 6 |b 101 201
500 |a 1 2 3 |b 100 200
以上示例中讨论的所有选项仍在此处应用。 除此之外,我们引入了两个附加功能:
输入名称别名
输入名称可以任意长,因此在整个输入文件中重复这些名称可能没有空间效率。 为了缓解这种情况,数据集可以使用“别名”而不是完整的输入名称。 然后,需要在每个输入子节中指定别名。 在我们的示例中,数据集使用别名,这些b
别名a
分别映射到读取器配置部分中的“Some_very_long_input_name”和“Some_other_also_very_long_input_name”。
序列 ID
如前所述,输入文件中的每一行表示一个 序列 ,其中包含每个输入的单个样本。 但是,如果行以非负数为前缀,则数字用作相应的 序列 ID。共享相同序列 ID 的所有后续行将合并在一起,成为同一序列的一部分。 因此,对 N 行重复相同的数字前缀可以生成多样本序列,每个输入包含 1 到 N 个样本。 省略第二行和以下行的序列前缀具有相同的效果。 因此,上面的示例数据集定义了 ID100
、200
、和 333
400
500
五个序列。
将读取器节中的参数设置为 skipSequenceIds
true
强制读取器忽略数据集中的所有显式序列 ID,并将单独的行视为单个序列。 此外,省略数据集中第一行的序列 ID 具有相同的效果 -- 将忽略所有后续序列 ID,将被视为单个序列的行,如以下示例所示:
|a 1 2 3 |b 100 200
100 |a 4 5 6 |b 101 201
200 |b 102983 14532 |a 7 8 9
使用序列时要考虑的一些最终事项:
- 序列 ID 必须是唯一的。
- ID 前缀只能针对连续行重复。
- 行 (的序列长度(即,共享相同 ID 前缀的行数) 不能超过样本的最大输入长度, (此序列中输入) 中的样本数。
例如,以下数据集 无效:
100 |a 1 2 3 |b 100 200
200 |a 4 5 6 |b 101 201
100 |b 102983 14532 |a 7 8 9
123 |a 1 2 3 |b 100 200
456 |a 4 5 6
456 |b 101 201
几个Real-World示例
- 分类:每行都包含一个示例,其中包含一个标签和特征。 不需要序列 ID,因为每一行都是其自己的长度 1 的“序列”。
|class 23:1 |features 2 3 4 5 6
|class 13:1 |features 1 2 0 2 3
...
- DSSM:每行都包含源目标文档配对,通过一袋单词表示,编码为稀疏向量。
|src 12:1 23:1 345:2 45001:1 |tgt 233:1 766:2 234:1
|src 123:1 56:1 10324:1 18001:3 |tgt 233:1 2344:2 8889:1 2234:1 253434:1
- 部分语音标记:序列将每个元素映射到相应的标签。 序列垂直对齐 (每行一个单词 + 标记) 。
0 |word 234:1 |tag 12:1
0 |word 123:1 |tag 10:1
0 |word 123:1 |tag 13:1
1 |word 234:1 |tag 12:1
1 |word 123:1 |tag 10:1
...
- 序列分类:映射到单个标签的序列。 序列垂直对齐;“class”标签可以出现在具有相同 sequenceId 的任何行中。
注意
目前,行数不能超过最长序列的长度。 这意味着标签不能单独出现在行上。 这是将来将解除的实现细节。
0 |word 234:1 |class 3:1
0 |word 123:1
0 |word 890:1
1 |word 11:1 |class 2:1
1 |word 344:1
- 序列到序列:将源序列映射到目标序列。 这两个序列垂直对齐,在最简单的情况下,只是在另一个之后打印。 它们通过具有相同的总体“序列 ID” (联接,在这种情况下,) 成为“工作单元 ID”。
注意
目前,行数不能超过最长序列的长度。 这意味着序列必须水平对齐。 这是将来将解除的实现细节。
0 |sourceWord 234:1 |targetWord 344:1
0 |sourceWord 123:1 |targetWord 456:1
0 |sourceWord 123:1 |targetWord 2222:1
0 |sourceWord 11:1
1 |sourceWord 123:1
...
- Learning排名:“序列”表示查询,每个示例都有一个带有手标分级的文档。 在这种情况下,“序列”只是一个多集, (在学习到排名损失函数的上下文中) 没有排序。
0 |rating 4 |features 23 35 0 0 0 21 2345 0 0 0 0 0
0 |rating 2 |features 0 123 0 22 44 44 290 22 22 22 33 0
0 |rating 1 |features 0 0 0 0 0 0 1 0 0 0 0 0
1 |rating 1 |features 34 56 0 0 0 45 1312 0 0 0 0 0
1 |rating 0 |features 45 45 0 0 0 12 335 0 0 0 0 0
2 |rating 0 |features 0 0 0 0 0 0 22 0 0 0 0 0
...
配置参数
参数 | 说明 |
---|---|
precision |
指定输入值的浮点精度 (double 或 float ) 。 可选,默认值为 float . |
reader
部分
参数 | 说明 |
---|---|
readerType |
指定一个受支持的CNTK读取器来加载 (, CNTKTextFormatReader 例如) 。 “必需”。 |
file |
包含输入数据集 (Windows或 Linux 样式) 的文件的路径。 “必需”。 |
randomize |
指定输入是否应随机化 (true , false ) 。 可选,默认值为 true . |
randomizationSeed |
当输入数据重新随机化) 时,初始随机化种子值 (递增。 可选,默认值为 0 . |
randomizationWindow |
指定随机化窗口的大小 (正整数) (,即随机化范围) 。 此参数会影响数据集一次驻留在内存中的多少。 可选,具体取决于 sampleBasedRandomizationWindow 值,默认值为样本中整个数据集的大小 (,即,当 (区块大小等于 32MB) 时,整个数据集) ) 随机化输入,或 4GB 的磁盘空间值(即 128 区块大小等于 32MB) )。 This parameter is ignored when randomize is false . |
sampleBasedRandomizationWindow |
如果 true ,随机化窗口的大小将解释为一定数量的样本,否则为多个区块。 可选,默认值为 false . Similarly to randomizationWindow , this parameter is ignored, when randomize is false . |
skipSequenceIds |
如果 true ,读取器将忽略输入文件中的序列 ID,将每个单独的行解释为大小为 1 的独立序列, (查看序列 ID) 部分 。 可选,默认值为 false . |
maxErrors |
应引发异常的输入错误数。 可选,默认为 0 ,这意味着第一个格式不正确的值将触发异常。 |
traceLevel |
输出详细级别。 0 - 仅显示错误; 1 - 显示错误和警告; 2 - 显示所有输出。 可选,默认值为 1 . |
chunkSizeInBytes |
单个读取操作中要从磁盘读取的连续字节数。 可选,默认为 33554432 (32MB) 。 |
keepDataInMemory |
如果 true ,整个数据集将缓存在内存中。 可选,默认值为 false . |
frameMode |
true 指示读取器使用针对仅包含单个样本) 的帧 (序列优化的打包方法。 可选,默认值为 false . |
cacheIndex |
指定在预处理阶段生成的元数据是否应写入磁盘,并在可用 (true false 时从磁盘加载,) 。 可选,默认值为 false . 有关更多详细信息,请参阅下面的部分。 CNTK版本 2.1 中的新增功能。 |
索引缓存
注意
CNTK版本 2.1 中的新增功能。
索引缓存允许以 2-3 倍) 显著 (减少启动时间,尤其是在处理大型输入文件时。 将 cacheIndex
标志设置为 true
指示读取器将索引元数据写入磁盘, (与输入文件相同的目录,) 缓存文件不可用,或者如果缓存文件) 早于输入文件 (过时。 编写是尽力的,在单独的线程上执行,以不影响读取器性能。 如果缓存文件存在且是最新的,则读取器将不再浏览输入文件以生成索引,而是从缓存文件加载索引。 请注意,某些读取器配置参数对索引 (有直接影响,不同的值 frameMode
可能会导致具有不同序列数的索引) 。 因此,读取器可以忽略缓存文件,其配置不同于生成缓存的配置。 若要查看缓存的完整优势,不应在后续重新运行时修改配置。
input
子节
input
将多个单独的输入组合在一起,每个输入都有一个适当标记的配置子部分。 下面介绍的所有参数都特定于与特定输入关联的 输入名称 子节。
参数 | 说明 |
---|---|
alias |
用于标识数据集中的输入的替代简写名称 (字符串) 。 可选 |
format |
指定输入类型 (dense , sparse ) 。 “必需”。 |
dim |
维度 (输入 (值的正整数) ,即样本中 密集 输入的输入值数、 稀疏 输入) 的索引范围的上限。 “必需”。 |
definesMBSize |
标志 (默认 false) ,指示是否应在来自此特定流的样本中计算小块大小 (可选)。 |
你将在CNTK存储库中找到完整的网络定义和相应的数据集示例。 在那里,还可以找到使用 CNTKTextFormat 读取器的 端到端测试 。