3

我正在tf.data.Dataset准备一个用于训练 tf.kears 模型的流数据集。使用kedro,有没有办法创建一个节点并返回创建的节点tf.data.Dataset以在下一个训练节点中使用它?

MemoryDataset可能不起作用,因为tf.data.Dataset不能腌制(deepcopy不可能),另请参见这个 SO question。根据问题#91,深度复制MemoryDataset是为了避免其他节点修改数据。有人可以详细说明为什么/如何发生这种并发修改吗?

文档中,似乎有一个copy_mode = "assign". 如果数据不可提取,是否可以使用此选项?

另一个解决方案(在 issue 91 中也提到过)是只使用一个函数在训练节点内部生成流tf.data.Dataset,而不需要前面的数据集生成节点。但是,我不确定这种方法的缺点是什么(如果有的话)。如果有人可以举一些例子,那就太好了。

此外,我想避免存储流数据集的完整输出,例如使用tfrecordstf.data.experimental.save因为这些选项会使用大量磁盘存储。

有没有办法只传递创建的tf.data.Dataset对象以将其用于训练节点?

4

1 回答 1

0

尽管@DataEngineerOne 在kedro.community中提供了解决方法,但为了社区的利益,这里提供了解决方法。

根据@DataEngineerOne。

使用kedro,有没有办法创建一个节点并返回创建的tf.data.Dataset以在下一个训练节点中使用它?

是的,一点没错!

有人可以详细说明为什么/如何发生这种并发修改吗?

从文档中,似乎有一个 copy_mode = "assign" 。如果数据不可提取,是否可以使用此选项?

我还没有尝试过这个选项,但理论上它应该可以工作。您需要做的就是在catalog.yml包含该copy_mode选项的文件中创建一个新的数据集条目。

前任:

# catalog.yml
tf_data:
  type: MemoryDataSet
  copy_mode: assign

# pipeline.py
node(
  tf_generator,
  inputs=...,
  outputs="tf_data",
)

我不能保证这个解决方案,但试一试,让我知道它是否适合你。

另一种解决方案(在 issue 91 中也提到过)是只使用一个函数在训练节点内生成流式传输 tf.data.Dataset,而不需要前面的数据集生成节点。但是,我不确定这种方法的缺点是什么(如果有的话)。如果有人可以举一些例子,那就太好了。

这也是一个很好的替代解决方案,我认为(猜想)在这种情况下MemoryDataSet会自动使用assign,而不是正常的deepcopy,所以你应该没问题。

# node.py

def generate_tf_data(...):
  tensor_slices = [1, 2, 3]
  def _tf_data():
    dataset = tf.data.Dataset.from_tensor_slices(tensor_slices)
    return dataset
  return _tf_data

def use_tf_data(tf_data_func):
  dataset = tf_data_func()

# pipeline.py
Pipeline([
node(
  generate_tf_data,
  inputs=...,
  outputs='tf_data_func',
),
node(
  use_tf_data,
  inputs='tf_data_func',
  outputs=...
),
])

这里唯一的缺点是额外的复杂性。有关更多详细信息,您可以参考此处

于 2021-03-19T12:15:21.470 回答