在CNTK中解释epoch_size、minibatch_size_in_samples和MinibatchSource.next_minibatch

在本文中,我们将阐明 Python 中以下参数和函数的解释和用法:

epoch_size

每个时期的动态轴) (张量的 标签 样本数。 CNTKepoch_size标签样本数,之后将执行特定的附加操作,包括

  • 可以在此处重启检查点模型 (训练)
  • 交叉验证
  • learning-rate 控制
  • minibatch-scaling

请注意,标签样本数的定义类似于用于 minibatch_size_in_samples的示例数。 epoch_size定义不同于minibatch_size_in_samplesepoch_size标签样本的定义,而不是输入样本。

因此,对于顺序数据,示例是序列的各个项。 因此,CNTK epoch_size引用多个序列,而是构成迷你块的序列标签中的序列数。

同样重要的是, epoch_size标签 样本,而不是输入样本,每个序列的标签数不一定是输入样本数。 例如,每个序列有一个标签,每个序列都有一个标签,并且每个序列有多个样本 (在这种情况下epoch_size,其作用类似于序列) 的序列数,并且每个样本都有一个标签,在这种情况下epoch_sizeminibatch_size_in_samples,每个样本 (不按顺序计算) 。

对于较小的数据集大小, epoch_size 通常设置为等于数据集大小。 在 Python 中,可以为此指定 cntk.io.INFINITELY_REPEAT 。 在 Python 中,还可以将其设置为 cntk.io.FULL_DATA_SWEEP,处理将在整个数据大小的一次传递后停止。

对于大型数据集,可能需要通过检查点来指导你选择 epoch_size 。 例如,如果要在发生停电或网络故障时最多丢失 30 分钟的计算,需要大约每 30 分钟创建一个检查点 (,以便从中恢复训练) 。 选择 epoch_size 为计算大约需要 30 分钟的示例数。

minibatch_size_in_samples

注意:对于 BrainScript 用户,小块大小的参数是 minibatchSize;对于 Python 用户,它是 minibatch_size_in_samples

CNTK具有非常具体的参数定义minibatch_size_in_samples:它表示模型更新之间的样本数。 此处 的示例 定义为一个向量或张量流经系统。 例如,在图像识别任务中,一个图像是一个示例。

每个时期的迷你batch大小在动态轴) (张量 样本 中给出。 默认值是 256。 可以将不同的值用于不同的纪元;例如, 128*2 + 1024 在 Python) 中的 (表示对前两个时期使用 128 的小型batch 大小,然后对其余时间使用 1024。 请注意,CNTK中的“minibatch 大小”表示模型更新之间处理的示例数。 当跨辅助角色并行化 ((例如对于 K 辅助角色)时,每个辅助角色将处理的示例数) minibatch_size_in_samples/K 。 对于可变长度输入, minibatch_size_in_samples 是指这些序列中的项数, 而不是 序列数。 SGD 将尝试尽可能多地容纳到不超过 minibatch_size_in_samples 总样本的迷你样本中。 如果给定了多个输入,则张量将添加到当前微分量,直到其中一个输入超过该 minibatch_size_in_samples量。

重要的是,对于顺序数据,示例是序列的各个项。 因此,CNTK minibatch_size_in_samples指小块中的序列数,而是构成迷你块的序列中的序列项/标记的聚合数。 CNTK对可变长度序列具有本机支持,例如,它可以容纳同一个迷你块中高度不同长度的序列,而无需使用存储桶等解决方法。 除了CNTK指定每个样本的学习速率的概念 (而不是小块平均) ,任何长度的每个序列项都对渐变的贡献相同,从而导致一致收敛。 (许多其他工具包将顺序数据的微型batch 大小定义为迷你包中的序列数。这是有问题的,特别是如果渐变也定义为迷你batch平均值,而不是CNTK的小块总和,因为对序列中每个标记或步骤的渐变的贡献与序列长度成反比。CNTK的方法避免了这种情况。)

使用多个输入时,并非所有输入都具有相同的序列长度。 例如,在序列分类中,每个序列的标签都是一个标记。 在这种情况下,具有最大样本数的输入控制小块大小。 (可以通过指定 defines_mb_size=True 某些输入来更改此行为,然后根据此特定输入中的序列对小块大小进行计数。指定多个输入时,只能将单个 defines_mb_size 输入设置为 True.)

尽管我们明确定义了 minibatch_size_in_samples 模型更新之间的样本数,但有两次必须放宽定义:

  • 顺序数据:可变长度序列通常不完全求和所请求的小块大小。 在这种情况下,尽可能多的序列被打包到迷你包中,而不超过所请求的迷你包大小 (,但有一个例外:如果随机化料库中的下一个序列超过小块大小的长度,则小块大小将包含此序列) 。
  • 数据并行度:此处,小块大小是近似的,因为我们的基于区块的随机化算法无法保证每个辅助角色接收的样本数完全相同。

上述所有注意事项也适用于 epoch_size,但 epoch_size 存在一些差异,请参阅 上文

MinibatchSource.next_minibatch

该方法 MinibatchSource.next_minibatch () 读取包含所有输入流的数据的微型batch。 在训练期间调用时, MinibatchSource.next_minibatch(minibatch_size_in_samples, input_map) 将从训练数据集中选取随机样本子集 k ,其中 k=minibatch_size_in_samples

实现可确保在调用) 时N = number_of_training_samples/minibatch_size_in_samples (调用时next_minibatch,会在调用next_minibatch结束时N覆盖整个训练数据集。N 这也意味着在调用2*N时间时next_minibatch,整个数据集被覆盖了两次。

其他信息:

  • 通过数据的每个周期将具有不同的随机顺序。
  • 如果双精度小块大小,现在一个迷你包将包含样本,在此之前,相应的两个连续小巴将包含 (如果具有可变长度序列) ,则可能是近似的。 即,两个运行在迷你块大小上只有所不同,以相同的顺序处理数据。
  • 如果中断并从检查点重启,将得到与未中断训练相同的随机顺序。 这是通过基于名义时间轴的读取/随机化过程实现的,采用以下简单算法:
    • 训练在名义上无限时间轴上进行。 如果提取大小为 256 的迷你包,则名义时间将按 256 进行。
    • 此时间轴上将无限次复制训练料料库。 如果有 M 示例,则第一个副本跨越名义时间 0..M-1;第二 M..2M-1个副本等。
    • 每个副本在副本边界内随机分配,但不跨副本边界。 即,一旦精确处理 M 样本,就只看到每个样本一次。
    • 调用 next_minibatch(K) 可提供此重新调整的无限时间线上的下一个 K 示例。 这与调用next_minibatch(1)K时间相同。
    • 这一切都是懒惰的。
    • 从检查点重启就像将名义时间重置为创建检查点时的名义时间一样简单。