5

tf.estimator.train_and_evaluate文档清楚地表明,必须正确打乱输入数据集,以便训练查看所有示例:

过拟合:为了避免过拟合,建议设置训练 input_fn 来适当地打乱训练数据。还建议在执行评估之前对模型进行更长时间的训练,比如多个 epoch,因为每次训练的输入管道都是从头开始的。这对于当地的培训和评估尤为重要。

在我的应用程序中,我想从tf.data.Dataset具有任意评估频率和shuffle()缓冲区大小的完整示例中统一采样。否则,训练最多只能看到第一个:

(steps_per_second * eval_delay * batch_size) + buffer_size

元素,有效地丢弃其余部分。有没有一种有效的方法来解决这个问题,而无需在系统内存中加载完整的数据集?

我考虑过根据缓冲区大小对数据集进行分片,但如果评估不频繁发生,它将在同一个分片上迭代多次(arepeat()关闭管道)。理想情况下,我想在对数据集进行完整迭代后移动到另一个分片,这可能吗?

感谢您的任何指点!

4

1 回答 1

0

可以使用此数据集转换实现数据集的随机分片:

def random_shard(shard_size, dataset_size):
  num_shards = -(-dataset_size // shard_size)  # Ceil division.
  offsets = np.linspace(
      0, dataset_size, num=num_shards, endpoint=False, dtype=np.int64)

  def _random_shard(dataset):
    sharded_dataset = tf.data.Dataset.from_tensor_slices(offsets)
    sharded_dataset = sharded_dataset.shuffle(num_shards)
    sharded_dataset = sharded_dataset.flat_map(
        lambda offset: dataset.skip(offset).take(shard_size))
    return sharded_dataset

  return _random_shard

这需要提前知道总数据集的大小。但是,如果您实施基于文件的分片方法,您还会在整个数据集上迭代一次,因此这不是主要问题。

关于效率,请注意skip(offset)实际上迭代offset示例,因此如果延迟offset很大,则可以预期。仔细的预取应该对此有所帮助。

于 2018-03-07T10:31:12.307 回答