【问题标题】:How to do a pairwise iteration over two unequal-length tf.datasets?如何对两个不等长的 tf.datasets 进行成对迭代?
【发布时间】:2021-04-05 21:46:09
【问题描述】:

我使用两个长度不等的数据集。

我的目标是为 datasetA 中的每个元素获取另一个 datasetB 中的元素。我尝试.take(1)(如图here)从datasetB 中获取单个元素,但重复调用.take(1) 不会提前数据集的内部计数,即它总是返回相同的元素;但我想每次都得到一个新元素。

我可以使用for element in datasetA: 遍历一个数据集,然后使用elementB = iterB.get_next() 使用内部的第二个数据集。这会在使用 iterB 时引发错误。

这是我正在使用的完整玩具代码:

datasetA = tf.data.Dataset.from_tensor_slices([1,  2,  3,  4,  5, 6])
datasetB = tf.data.Dataset.from_tensor_slices([11, 22, 33, 44])

iterB = iter(datasetB)
epochs = 5

for epoch in range(epochs):
  print(f"Epoch {epoch}")
  for element in datasetA:
    print(element)
    elementB = iterB.get_next()
    print(elementB)

然后我继续:

for epoch in range(epochs):
  print(f"Epoch {epoch}")
  for element in datasetA:
    print(element)
    elementB = iterB.get_next_as_optional()
    if not elementB.has_value():
      iterB = iter(datasetB)
      elementB = iterB.get_next_as_optional()

    print(elementB.get_value())

这可行,但重新初始化 datasetB 的迭代器很麻烦。

我进一步发现的是这个for old TensorFlow,它使用TF操作重新初始化迭代器,不再可用。 this question 中也提到了这一点,这很有帮助,但没有让我找到 TF2.+ 解决方案。

我正在寻找一种从datasetAdatasetB 中获取成对元素的优雅方法,其中datasetB 在使用时(自动)重复。

我不需要遍历组合数据集,除非较短的数据集通过重复“填充”到较长的数据集,然后我可以从数据集A 和 B 中的 A 和 B数据集B。

TL;DR: 想要对两个长度不等的数据集进行成对迭代,使用时重新启动较短的数据集。

【问题讨论】:

    标签: python tensorflow iterator


    【解决方案1】:

    要从两个数据集中获取所有可能的样本对,可以使用以下generator

        # assuming that dataset_A and dataset_B are defined globally
        def generator():
            for sample_A in dataset_A:
                for sample_B in dataset_B:
                    yield (sample_A, sample_B)
    

    为了只获取数据集中相同位置(相同索引)的样本对,有一个标准的zip 方法:

        dataset = tf.data.Dataset.zip(dataset_A, dataset_B)
    

    当其中一个数据集耗尽时,此类生成器将停止。

    如果目标是从dataset_A 获得所有样本的成对样本,但dataset_B 更小,则可以无限重复第二个数据集,

         dataset_B = dataset_B.repeat()
    

    然后zip 两个数据集。

    【讨论】:

    • 这是一个方向,但将适用于数据集 A 中的每个样本,而不是整个数据集 B。我的意图是同时迭代它们,这样当我从 datasetA 中获取第二个样本时,我也会从 datasetB 中获取第二个样本。
    • 编辑答案以获得所需的数据集。
    • 虽然这并不能完全回答我的问题,但它似乎是我目前能得到的最接近的!谢谢!
    • 您想在dataset_B 耗尽时“重新启动”它,但不是dataset_A 中的所有元素都被使用了吗?如果这是目标,那么在压缩之前,请致电dataset_B = dataset_B.repeat()
    • 这正是我想要的!非常感谢!
    【解决方案2】:

    我不知道这种编码语言,但这是你应该做的。

    datasetA = tf.data.Dataset.from_tensor_slices([1,  2,  3,  4,  5, 6]);
    datasetB = tf.data.Dataset.from_tensor_slices([11, 22, 33, 44]);
    set i=0,j=0;
    get lengths of both alength and blength;
    for(i=0;i<alength;i++){
     print(datasetA[i]);
     print(datasetB[j]);
     if(j<blength-1)
       j++;
     else
      j=0;  
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-12
      • 2018-05-21
      • 2016-08-01
      • 1970-01-01
      相关资源
      最近更新 更多