Tensorflow数据集:如何选择参数进行数据集预处理? (批量,预取,地图等)

时间:2018-12-12 22:52:33

标签: python tensorflow optimization tensorflow-datasets

我的问题与如何为Tensorflow Dataset选择最佳(甚至合理)参数以优化GPU性能有关。

我去年建立了一个培训渠道,现在正在重新审查,以查看是否可以改进。这是我目前已编码的数据集:

    dataset    = tf.data.TFRecordDataset(self.filenames, "ZLIB", 384 * 1024 * 1024, num_parallel_reads=12)
    dataset    = dataset.map(parse_func, 20)
    dataset    = dataset.batch(8192) ## TODO
    dataset    = dataset.prefetch(2)
    dataset    = dataset.apply(tf.data.experimental.prefetch_to_device("/gpu:0", 1))        

作为背景,我正在读取一个protobuf文件,它们看起来像这样:

features {
  feature {
    key: "DAT"
    value {
      float_list {
        value: 1.0
        value: -7.0
        value: 0.0
        value: -7.0
        value: 0.0
        value: -7.0
        value: 0.0
        value: -7.0
        value: 0.0
        value: -7.0
        value: 0.0
        value: -7.0
        value: 0.0
        value: -7.0
        value: -1.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: -1.0
        value: -5.0
        value: 0.0
        value: -5.0
        value: 0.0
        value: -5.0
        value: 0.0
        value: -5.0
        value: 0.0
        value: -5.0
        value: 0.5
        value: -5.5
        value: 0.5
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: -1.0
        value: -5.0
        value: 0.0
        value: -5.0
        value: 1.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: -1.0
        value: -5.0
        value: 0.0
        value: -5.0
        value: 0.0
        value: -5.0
        value: 0.0
        value: -5.0
        value: 0.0
        value: -5.0
        value: 0.0
        value: -5.0
        value: -1.0
        value: -4.0
        value: 1.0
        value: -5.0
        value: 0.0
        value: -5.0
        value: 0.0
        value: -5.0
        value: 0.0
        value: -5.0
        value: 0.0
        value: -5.0
        value: 1.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: 0.0
        value: -6.0
        value: -1.0
        value: -5.0
        value: -1.0
        value: -4.0
        value: 0.0
        value: -4.0
        value: 0.0
        value: -4.0
        value: 0.0
        value: -4.0
        value: -1.0
        value: -3.0
        value: 1.0
        value: -4.0
        value: 0.0
        value: -4.0
        value: 0.0
        value: -4.0
        value: 0.0
        value: -4.0
        value: 0.0
        value: -4.0
        value: 0.0
        value: -4.0
        value: 0.0
        value: -4.0
        value: 0.0
        value: -4.0
        value: 0.0
        value: -4.0
        value: 1.0
        value: -5.0
        value: 0.0
        value: -5.0
        value: -1.0
        value: -4.0
        value: 0.0
        value: -4.0
        value: -1.0
        value: -3.0
        value: -2.0
        value: -1.0
        value: 0.0
        value: -1.0
        value: 1.0
        value: -2.0
        value: 0.0
        value: -2.0
        value: -2.0
        value: 0.0
        value: 0.0
        value: 0.0
        value: 0.0
        value: 0.0
        value: 0.0
        value: -2.5
        value: -0.5
        value: 0.0
        value: 0.0
        value: 0.000187634868780151
      }
    }
  }

此外,我像这样从protobuf解析example

def get_parse_func(self):
    def _parse_function(example_proto):
        keys_to_features = {
            "DAT": tf.FixedLenFeature(self._shapeX, tf.float32)
            }
        ex = ex = tf.parse_single_example(example_proto, keys_to_features)
        X = tf.reshape(ex["DAT"][1:257], (128, 2))
        ##X =    ex["DAT"][1:257]
        Y_bd = ex["DAT"][259]
        retBd = 5
        Y_bd = tf.clip_by_value(Y_bd, -retBd, retBd)
        Y_bd = tf.math.scalar_mul(1e4/retBd, Y_bd)
        Y_full = ex["DAT"][257:260]
        W = ex["DAT"][0]
        return X, Y_full, Y_bd, W
    return _parse_function

因此,这些文件一次仅包含一个示例/数据点,而在过去,我甚至在保存的文件中预先添加了批处理,以避免进行批处理的开销。但是,这样做有很多弊端,因此,我试图避免这种情况。附带说明一下,当我进行批量培训时,我的GPU利用率在训练时约为95%(尽管由于CPU / GPU io问题我经常将其利用率降至0%,但我也想解决这个问题,但这不是这个问题的重点) 。

我一直在尝试使用各种dataset预处理功能的参数,例如mapbatchprefetchprefetch_to_device,但这感觉就像ving牛刮胡子。看起来,无论我尝试使用哪种参数组合,即使我将参数改变了整个数量级,最终GPU利用率仍在30%到40%之间。令人惊讶的是,考虑到我正在改变输入参数的程度,性能几乎没有变化。通常,我尝试从除batch的参数以外的每个小参数(例如等于1)开始,我将其设为8192或8192 * 2。的8192)。

但是,我意识到我什至没有知道保留这些参数的数量级的原则基础。 以下每个问题的具体问题:

  • 用于初始化tf.data.TFRecordDataset的最佳num_parallel_reads参数是什么?我注意到如果我将它设置得太高(例如100),一切都会崩溃。但是太低会导致性能下降。这应该等于我计算机上的num核心吗?其他一些与操作系统相关的线程数?
  • 对于dataset.mapnum_parallel_calls同样与我设备上的cpus数有关吗?有什么好的经验法则?上面的项目符号点还应该与我的num_parallel_reads参数有关系吗?
  • 对于dataset.prefetchdataset.apply,我不认为它们与num个线程有关(但也许我错了?),但我认为这与可用的RAM或可用的GPU有关记忆?我如何获得一个合理的数字开始实验?
  • 关于批量大小的相同问题,尽管通常我通常会发现此参数最容易检查(我通常将其设置得越来越大,直到看到性能下降...是正确的)。确实最好以2的幂进行处理吗? (有人告诉我,我会坚持下去)。

谢谢您的帮助和建议。

0 个答案:

没有答案