【问题标题】:Randomly sample from multiple tf.data.Datasets in Tensorflow从 Tensorflow 中的多个 tf.data.Datasets 中随机采样
【发布时间】:2018-09-19 20:11:48
【问题描述】:

假设我有 N tf.data.Datasets 和 N 个概率列表(总和为 1),现在我想创建数据集,以便示例从具有给定概率的 N 个数据集中采样。

我希望这适用于任意概率 -> 每个数据集中具有固定数量示例的简单 zip/concat/flatmap 可能不是我想要的。

在 TF 中可以做到这一点吗?谢谢!

【问题讨论】:

  • 您对使用所有数据不感兴趣吗?我在问,因为如果你是,概率只会影响生成示例的顺序(因为最终所有样本都将从所有数据集中生成)。您能否澄清您在这方面的问题?
  • 我假设每个数据集无限重复,因此较小的数据集可以循环多次,然后“完成”较大的数据集。

标签: python tensorflow tensorflow-datasets


【解决方案1】:

从 1.12 开始,tf.data.experimental.sample_from_datasets 提供此功能: https://www.tensorflow.org/api_docs/python/tf/data/experimental/sample_from_datasets

编辑:看起来在早期版本中这可以通过tf.contrib.data.sample_from_datasets 访问

【讨论】:

  • 如果不同数据集的长度明显不同,请务必小心。在这种情况下,您将不得不手动执行较小数据集的重复或截断较长数据集在应用tf.data.experimental.sample_from_datasets 方法之前。更多详情见this
  • 有没有办法从数据集中对单个元素进行采样?如果a 是一个数据集,我可以使用a.take(1) 访问第一个样本。我可以制作类似a.takerandom(1) 的东西吗?
【解决方案2】:

如果p 是概率的Tensor(或未归一化的相对概率),其中p[i] 是选择数据集i 的概率,则可以将tf.multinomialtf.contrib.data.choose_from_datasets 结合使用:

# create some datasets and their unnormalized probability of being chosen
datasets = [
    tf.data.Dataset.from_tensors(['a']).repeat(),
    tf.data.Dataset.from_tensors(['b']).repeat(),
    tf.data.Dataset.from_tensors(['c']).repeat(),
    tf.data.Dataset.from_tensors(['d']).repeat()]
p = [1., 2., 3., 4.]  # unnormalized

# random choice function
def get_random_choice(p):
  choice = tf.multinomial(tf.log([p]), 1)
  return tf.cast(tf.squeeze(choice), tf.int64)

# assemble the "choosing" dataset
choice_dataset = tf.data.Dataset.from_tensors([0])  # create a dummy dataset
choice_dataset = choice_dataset.map(lambda x: get_random_choice(p))  # populate it with random choices
choice_dataset = choice_dataset.repeat()  # repeat

# obtain your combined dataset, assembled randomly from source datasets
# with the desired selection frequencies. 
combined_dataset = tf.contrib.data.choose_from_datasets(datasets, choice_dataset)

注意数据集需要初始化(不能使用简单的make_one_shot_iterator):

choice_iterator = combined_dataset.make_initializable_iterator()
choice = choice_iterator.get_next()
with tf.Session() as sess:
  sess.run(choice_iterator.initializer)
  print ''.join([sess.run(choice)[0] for _ in range(20)])

>> ddbcccdcccbbddadcadb

【讨论】:

  • 还没试过,但这似乎是最佳解决方案。谢谢
【解决方案3】:

我觉得你可以使用tf.contrib.data.rejection_resample来实现目标分发。

【讨论】:

  • 好的,这可以工作,谢谢...如果我理解正确,我会统一交错数据集并在数据集中的张量中添加一个数据集标识符,然后这个rejection_resample会丢弃这个大的交错数据集以匹配提供的分布?这似乎是一种非常缓慢且低效的做事方式:(
  • @serycjon,是的,你没看错。是的,我认为这将是低效的。
  • 接受这个直到有人找到有效的解决方案。
  • @serycjon,我可以提出更有效的解决方案,但我需要了解更多细节。您的数据集的来源是什么?是 TFRecords,只是文件还是其他什么?
  • 我知道可以通过各种方式有效地组合不同的数据集,但是,我的问题只是关于 tf.data.Datasets -> 数据的来源是什么并不重要。让我们假设我有几个 Dataset 对象,不管它们的来源是什么。从逻辑上讲,从这些 N 个数据集中随机抽样应该很容易完成,性能损失几乎为零。问题是——在 tensorflow 中有可能吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-11
  • 2012-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-01
  • 1970-01-01
相关资源
最近更新 更多