רכיבי פונקציית 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 ומחלקות המפרט וה-Executor שלו.

אם ברצונך להגדיר תת-מחלקה של BaseBeamComponent כך שתוכל להשתמש בצינור קרן עם תצורה משותפת של TFX-pipeline-wise, כלומר, beam_pipeline_args בעת הידור הצינור ( דוגמה של Chicago Taxi Pipeline ) תוכל להגדיר use_beam=True ב-Decorator ולהוסיף 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, הקלט והפלט עוקבים כאובייקטים של Artifact המתארים את המיקום של מאפייני המטא נתונים הקשורים לנתונים הבסיסיים; מידע זה מאוחסן ב-ML Metadata. חפצים יכולים לתאר סוגי נתונים מורכבים או סוגי נתונים פשוטים, כגון: int, float, bytes או unicode מחרוזות.

פרמטר הוא ארגומנט (int, float, bytes או unicode מחרוזת) לרכיב הידוע בזמן בניית הצינור. פרמטרים שימושיים לציון ארגומנטים והיפרפרמטרים כמו ספירת איטרציות אימון, שיעור נשירה ותצורה אחרת לרכיב שלך. פרמטרים מאוחסנים כמאפיינים של ביצוע רכיבים כשהם עוקבים ב-ML Metadata.

הַגדָרָה

כדי ליצור רכיב מותאם אישית, כתוב פונקציה המיישמת את ההיגיון המותאם אישית שלך וקשט אותה עם ה- @component decorator מהמודול 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 בסוג הפרמטר. כרגע אנחנו תומכים רק בסוגי פיתון פרימיטיביים: 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 , והרכיב מוציא מדדי loss accuracy כערכי פלט של סוג נתונים פשוטים. חפץ model הפלט משמש לאחר מכן את רכיב ה- Pusher .