Componenti di funzioni Python personalizzate

La definizione dei componenti basati su funzioni Python semplifica la creazione di componenti personalizzati TFX, risparmiando lo sforzo di definire una classe di specifica del componente, una classe dell'esecutore e una classe dell'interfaccia del componente. In questo stile di definizione del componente, scrivi una funzione annotata con suggerimenti sul tipo. I suggerimenti sul tipo descrivono gli artefatti di input, gli artefatti di output e i parametri del componente.

Scrivere il componente personalizzato in questo stile è molto semplice, come nell'esempio seguente.

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
  }

Sotto il cofano, questo definisce un componente personalizzato che è una sottoclasse di BaseComponent e le sue classi Spec ed Executor.

Se desideri definire una sottoclasse di BaseBeamComponent in modo da poter utilizzare una pipeline di travi con configurazione condivisa TFX-pipeline, ovvero beam_pipeline_args durante la compilazione della pipeline ( esempio di Chicago Taxi Pipeline ) puoi impostare use_beam=True nel decoratore e aggiungere un altro BeamComponentParameter con valore predefinito None nella funzione come nell'esempio seguente:

@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

Se non conosci le pipeline TFX, scopri di più sui concetti fondamentali delle pipeline TFX .

Ingressi, uscite e parametri

In TFX, gli input e gli output vengono tracciati come oggetti Artifact che descrivono la posizione e le proprietà dei metadati associati ai dati sottostanti; queste informazioni sono archiviate nei metadati ML. Gli artefatti possono descrivere tipi di dati complessi o tipi di dati semplici, come: int, float, byte o stringhe Unicode.

Un parametro è un argomento (int, float, byte o stringa Unicode) di un componente noto al momento della costruzione della pipeline. I parametri sono utili per specificare argomenti e iperparametri come il conteggio delle iterazioni di training, la frequenza di abbandono e altre configurazioni del componente. I parametri vengono archiviati come proprietà delle esecuzioni dei componenti quando monitorati nei metadati ML.

Definizione

Per creare un componente personalizzato, scrivi una funzione che implementa la tua logica personalizzata e decorala con il decoratore @component dal modulo tfx.dsl.component.experimental.decorators . Per definire lo schema di input e output del componente, annota gli argomenti della funzione e restituisci il valore utilizzando le annotazioni del modulo tfx.dsl.component.experimental.annotations :

  • Per ogni input di artefatto , applica l'annotazione di suggerimento di tipo InputArtifact[ArtifactType] . Sostituisci ArtifactType con il tipo dell'artefatto, che è una sottoclasse di tfx.types.Artifact . Questi input possono essere argomenti facoltativi.

  • Per ogni artefatto di output , applica l'annotazione del suggerimento di tipo OutputArtifact[ArtifactType] . Sostituisci ArtifactType con il tipo dell'artefatto, che è una sottoclasse di tfx.types.Artifact . Gli artefatti di output del componente devono essere passati come argomenti di input della funzione, in modo che il componente possa scrivere gli output in una posizione gestita dal sistema e impostare le proprietà appropriate dei metadati dell'artefatto. Questo argomento può essere facoltativo oppure può essere definito con un valore predefinito.

  • Per ogni parametro , utilizzare l'annotazione del suggerimento di tipo Parameter[T] . Sostituisci T con il tipo del parametro. Al momento supportiamo solo tipi Python primitivi: bool , int , float , str o bytes .

  • Per beam pipeline , utilizzare l'annotazione del suggerimento sul tipo BeamComponentParameter[beam.Pipeline] . Impostare il valore predefinito su None . Il valore None verrà sostituito da una pipeline di travi istanziata creata da _make_beam_pipeline() di BaseBeamExecutor

  • Per ogni input di tipo dati semplice ( int , float , str o bytes ) non noto al momento della costruzione della pipeline, utilizzare l'hint di tipo T . Tieni presente che nella versione TFX 0.22, i valori concreti non possono essere passati al momento della costruzione della pipeline per questo tipo di input (utilizza invece l'annotazione Parameter , come descritto nella sezione precedente). Questo argomento può essere facoltativo oppure può essere definito con un valore predefinito. Se il tuo componente ha output di tipo dati semplici ( int , float , str o bytes ), puoi restituire questi output utilizzando TypedDict come annotazione del tipo restituito e restituendo un oggetto dict appropriato.

Nel corpo della funzione, gli artefatti di input e output vengono passati come oggetti tfx.types.Artifact ; puoi controllare il suo .uri per ottenere la sua posizione gestita dal sistema e leggere/impostare eventuali proprietà. I parametri di input e gli input di tipi di dati semplici vengono passati come oggetti del tipo specificato. Gli output di tipi di dati semplici devono essere restituiti come dizionario, dove le chiavi sono i nomi di output appropriati e i valori sono i valori restituiti desiderati.

Il componente funzione completato può assomigliare a questo:

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'])
# ...

L'esempio precedente definisce MyTrainerComponent come componente personalizzato basato su funzioni Python. Questo componente utilizza un artefatto examples come input e produce un artefatto model come output. Il componente utilizza artifact_instance.uri per leggere o scrivere l'artefatto nella posizione gestita dal sistema. Il componente accetta un parametro di input num_iterations e un valore del tipo di dati semplice dropout_hyperparameter e restituisce le metriche di loss e accuracy come valori di output del tipo di dati semplice. L'artefatto model di output viene quindi utilizzato dal componente Pusher .