0

我们正在研究将我们的 ML 管道从一组手动步骤转换为 TFX 管道。然而,我确实有一些问题,我想对此有一些额外的见解。

我们通常执行以下步骤(对于图像分类任务):

  1. 加载图像数据和元数据
  2. 根据元数据过滤掉“坏”数据
  3. 确定基于图像的统计信息(Python 中的经典图像处理):
    1. 图像级特征
    2. 图像区域特征(区域基于微调的 EfficientDet 模型确定)
  4. 根据图像统计过滤掉“坏”数据
  5. 从此图像和元数据生成 TFRecords
  6. 对某些 TFRecord 进行过采样以进行类平衡(使用 tf.data)
  7. 训练图像分类器
  8. …</li>

现在,我正在尝试将其映射到典型的示例 TFX 管道上。

然而,这提出了一些问题:

  1. 我看到两个选项:

    • ExampleGen 使用一个 CSV 文件,其中包含指向要加载的图像和要加载的元数据的指针(在步骤“1”之上)。然而:

      • 如果此 CSV 文件包含图像文件的路径,ExampleGen 是否可以加载图像数据并将其添加到其输出中?
      • ExampleGen 的输出是流输出,还是所有示例数据的转储?
    • ExampleGen 将 TFRecords 作为输入(上述步骤“5”的输出)

      -> 这意味着我们仍然需要在 TFX 之外实施步骤 1-5……这会降低我们对 TFX 的价值……</p>

    你能建议什么是最好的前进方式吗?

  2. StatisticsGen 是否还可以生成基于每个示例的统计信息(例如基于经典图像处理的某些图像(区域)特征)?还是应该在 ExampleGen 中实现?或者…?

  3. 可以使用元数据存储缓存计算的统计信息吗?如果是,是否有可用的示例?

    使用经典图像处理计算基于图像的特征很慢。如果新数据可用,触发要执行的 TFX 输入组件,理想情况下应该从缓存中加载已经计算的统计信息。

  4. ExampleValidator 可能会拒绝某些示例(例如缺失数据、异常值……)是否正确?

  5. 如何在此设置中实现网络输入端的类平衡(不是通过损失函数)(通常我们通过使用 tf.data 对我们的 TFRecord 进行过采样来做到这一点)?如果这是在 ExampleGen 级别完成的,那么 ExampleValidator 可能仍会拒绝一些可能再次不平衡数据的示例。对于大数据 M​​L 任务,这似乎不是一个大问题,但对于小数据 ML 任务(通常在医疗保健环境中就是这种情况)而言,它变得至关重要。所以我希望在 Transform 组件之前有一个 TFX 组件,但是这个块应该可以访问所有数据,而不是以流的方式(参见我之前关于 ExampleGen 输出的问题)......</p>

感谢您的见解。

4

1 回答 1

0

我将尝试用我在 tfx 方面的经验来解决大多数问题。

  1. 我有一个数据流作业,我运行它来预处理我的图像、标签、特征等,并将所有这些转换为 tfrecords。它位于 tfx 之外,仅在数据刷新时运行。

你也可以这样做,这是一个非常简单的代码片段,我用它来调整所有图像的大小并创建简单的功能。

try:
      image = tf.io.decode_jpeg(image_string)
      image = tf.image.resize(image,[image_resize_size,image_resize_size])
      image = tf.image.convert_image_dtype(image/255.0, dtype=tf.uint8)
      image_shape = image.shape

      image = tf.io.encode_jpeg(image,quality=100)

      feature = {
        'height': _int64_feature(image_shape[0]),
        'width' : _int64_feature(image_shape[1]),
        'depth' : _int64_feature(image_shape[2]),
        'label' : _int64_feature(labels_to_int(element[2].decode())),
        'image_raw' : _bytes_feature(image.numpy())
      }

      tf_example = tf.train.Example(features=tf.train.Features(feature=feature))
    except:
      print('image could not be decoded')
      return None
  1. 获得 tfrecord 格式的数据后,我使用该ImportExampleGen组件将数据加载到我的 tfx 管道中。紧随其后的是 StatisticsGen,它将计算特征的统计信息。

在云中运行所有这些时,它在批处理模式下使用数据流。

  1. 您的元数据存储仅缓存管道元数据,但您的数据缓存在 gcs 存储桶中,元数据存储知道这一点。因此,当您重新运行管道时,如果您将缓存设置为 True,如果数据未更改,则不会重新运行 ImportExampleGen、StatisticsGen、SchemaGen、Transform。这在时间和成本上都有巨大的好处。

  2. ExampleValidator 输出一个工件,让您知道您的数据中有哪些数据异常。我创建了一个自定义组件来接收 examplevalidator 工件,如果我的数据不符合某些标准,我会通过在该组件中抛出错误来终止管道。我希望有一个组件可以停止管道,但我还没有找到,所以我的工作是抛出一个错误,阻止管道进一步前进。

  3. 通常当我创建一个 tfx 管道时,它是为了自动化机器学习过程。此时我们已经完成了类平衡、特征选择等。因为这更多地属于预处理阶段。

我想您可以在技术上创建一个自定义组件,该组件采用 StatisticsGen 工件,对其进行解析并尝试进行一些类平衡,并创建一个具有平衡类的新数据集。但老实说,我认为最好在预处理阶段进行。

于 2021-10-08T16:22:55.943 回答