如何在kedro中使用tf.data.Dataset?

问题描述

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

MemoryDataset可能无法工作,因为无法腌制tf.data.Dataset(不可能deepcopy),另请参见this SO question。根据{{​​3}},在MemoryDataset中进行了深拷贝,以避免其他节点修改数据。有人可以详细说明为什么/如何进行这种并行修改吗?

issue #91中似乎有一个copy_mode = "assign"。如果数据不可腌制,是否可以使用此选项?

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

此外,我想避免存储流数据集的完整输出,例如使用docstfrecords,因为这些选项会占用大量磁盘存储空间。

是否有一种方法可以只传递创建的tf.data.Dataset对象以将其用于训练节点?

解决方法

在此处提供解决方法以造福社区,尽管它由 @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,outputs='tf_data_func',),node(
  use_tf_data,inputs='tf_data_func',outputs=...
),])

这里唯一的缺点是额外的复杂性。详情请参阅here