Пользовательские функциональные компоненты Python

Определение компонентов на основе функций Python упрощает создание пользовательских компонентов TFX, экономя усилия по определению класса спецификации компонента, класса исполнителя и класса интерфейса компонента. В этом стиле определения компонента вы пишете функцию, аннотированную подсказками типа. Подсказки типов описывают входные артефакты, выходные артефакты и параметры вашего компонента.

Написать собственный компонент в этом стиле очень просто, как показано в следующем примере.

class MyOutput(TypedDict):
  accuracy: float

@component
def MyValidationComponent(
    model: InputArtifact[Model],
    blessing: OutputArtifact[Model],
    accuracy_threshold: Parameter[int] = 10,
) -> MyOutput:
  '''My simple custom model validation component.'''

  accuracy = evaluate_model(model)
  if accuracy >= accuracy_threshold:
    write_output_blessing(blessing)

  return {
    'accuracy': accuracy
  }

Внутри он определяет пользовательский компонент, который является подклассом BaseComponent и его классов Spec и Executor.

Если вы хотите определить подкласс BaseBeamComponent , чтобы вы могли использовать конвейер луча с общей конфигурацией TFX-конвейера, т. е., beam_pipeline_args при компиляции конвейера ( Пример Chicago Taxi Pipeline ), вы можете установить use_beam=True в декораторе и добавить другой BeamComponentParameter со значением по умолчанию None в вашей функции, как показано в следующем примере:

@component(use_beam=True)
def MyDataProcessor(
    examples: InputArtifact[Example],
    processed_examples: OutputArtifact[Example],
    beam_pipeline: BeamComponentParameter[beam.Pipeline] = None,
    ) -> None:
  '''My simple custom model validation component.'''

  with beam_pipeline as p:
    # data pipeline definition with beam_pipeline begins
    ...
    # data pipeline definition with beam_pipeline ends

Если вы новичок в конвейерах TFX, узнайте больше об основных концепциях конвейеров TFX .

Входы, выходы и параметры

В TFX входные и выходные данные отслеживаются как объекты-артефакты, которые описывают расположение и свойства метаданных, связанные с базовыми данными; эта информация хранится в метаданных ML. Артефакты могут описывать сложные типы данных или простые типы данных, например: int, float, bytes или строки Юникода.

Параметр — это аргумент (int, float, байты или строка Юникода) компонента, известного во время построения конвейера. Параметры полезны для указания аргументов и гиперпараметров, таких как количество итераций обучения, частота отсева и другие настройки вашего компонента. Параметры сохраняются как свойства выполнения компонентов при отслеживании в метаданных ML.

Определение

Чтобы создать собственный компонент, напишите функцию, реализующую вашу пользовательскую логику, и украсьте ее декоратором @component из модуля tfx.dsl.component.experimental.decorators . Чтобы определить схему ввода и вывода вашего компонента, аннотируйте аргументы вашей функции и возвращаемое значение, используя аннотации из модуля tfx.dsl.component.experimental.annotations :

  • Для каждого входного артефакта примените аннотацию подсказки типа InputArtifact[ArtifactType] . Замените ArtifactType типом артефакта, который является подклассом tfx.types.Artifact . Эти входные данные могут быть необязательными аргументами.

  • Для каждого выходного артефакта примените аннотацию подсказки типа OutputArtifact[ArtifactType] . Замените ArtifactType типом артефакта, который является подклассом tfx.types.Artifact . Выходные артефакты компонента следует передавать в качестве входных аргументов функции, чтобы ваш компонент мог записывать выходные данные в расположение, управляемое системой, и устанавливать соответствующие свойства метаданных артефакта. Этот аргумент может быть необязательным или этот аргумент может быть определен со значением по умолчанию.

  • Для каждого параметра используйте аннотацию подсказки типа Parameter[T] . Замените T типом параметра. В настоящее время мы поддерживаем только примитивные типы Python: bool , int , float , str или bytes .

  • Для лучевого конвейера используйте аннотацию подсказки типа BeamComponentParameter[beam.Pipeline] . Установите значение по умолчанию None . Значение None будет заменено экземпляром балочного конвейера, созданным с помощью _make_beam_pipeline() из BaseBeamExecutor .

  • Для каждого простого типа ввода данных ( int , float , str или bytes ), неизвестного во время построения конвейера, используйте подсказку типа T Обратите внимание, что в версии TFX 0.22 конкретные значения не могут передаваться во время построения конвейера для этого типа входных данных (вместо этого используйте аннотацию Parameter , как описано в предыдущем разделе). Этот аргумент может быть необязательным или этот аргумент может быть определен со значением по умолчанию. Если ваш компонент имеет выходные данные простого типа ( int , float , str или bytes ), вы можете вернуть эти выходные данные, используя TypedDict в качестве аннотации возвращаемого типа и возвращая соответствующий объект dict.

В теле вашей функции артефакты ввода и вывода передаются как объекты tfx.types.Artifact ; вы можете проверить его .uri чтобы получить его местоположение, управляемое системой, и прочитать/установить любые свойства. Входные параметры и входные данные простого типа передаются как объекты указанного типа. Выходные данные простых типов данных должны возвращаться в виде словаря, где ключи — это соответствующие имена выходных данных, а значения — желаемые возвращаемые значения.

Готовый функциональный компонент может выглядеть так:

from typing import TypedDict
import tfx.v1 as tfx
from tfx.dsl.component.experimental.decorators import component

class MyOutput(TypedDict):
  loss: float
  accuracy: float

@component
def MyTrainerComponent(
    training_data: tfx.dsl.components.InputArtifact[tfx.types.standard_artifacts.Examples],
    model: tfx.dsl.components.OutputArtifact[tfx.types.standard_artifacts.Model],
    dropout_hyperparameter: float,
    num_iterations: tfx.dsl.components.Parameter[int] = 10
) -> MyOutput:
  '''My simple trainer component.'''

  records = read_examples(training_data.uri)
  model_obj = train_model(records, num_iterations, dropout_hyperparameter)
  model_obj.write_to(model.uri)

  return {
    'loss': model_obj.loss,
    'accuracy': model_obj.accuracy
  }

# Example usage in a pipeline graph definition:
# ...
trainer = MyTrainerComponent(
    examples=example_gen.outputs['examples'],
    dropout_hyperparameter=other_component.outputs['dropout'],
    num_iterations=1000)
pusher = Pusher(model=trainer.outputs['model'])
# ...

В предыдущем примере MyTrainerComponent определяется как пользовательский компонент на основе функций Python. Этот компонент принимает артефакт examples в качестве входных данных и создает артефакт model в качестве выходных данных. Компонент использует artifact_instance.uri для чтения или записи артефакта в его местоположении, управляемом системой. Компонент принимает входной параметр num_iterations и значение простого типа данных dropout_hyperparameter , а accuracy данные компонента loss в виде выходных значений простого типа данных. Артефакт выходной model затем используется компонентом Pusher .