רכיב Transform TFX Pipeline

רכיב הצינור Transform TFX מבצע הנדסת תכונות על tf. דוגמאות הנפלטות מרכיב של ExampleGen , תוך שימוש בסכימת נתונים שנוצרה על ידי רכיב SchemaGen , ופולט גם SavedModel וגם סטטיסטיקות על נתונים שלפני טרנספורמציה וגם שלאחר-טרנספורמציה. כאשר הוא מופעל, ה-SavedModel יקבל tf.Examples הנפלטים מרכיב ExampleGen ויפלוט את נתוני התכונה שהשתנו.

  • צורכת: tf.דוגמאות מרכיב ExampleGen, וסכימת נתונים מרכיב SchemaGen.
  • פולט: רכיב SavedModel ל-Trainer, סטטיסטיקות טרום טרנספורמציה ואחרי טרנספורמציה.

הגדרת רכיב טרנספורמציה

לאחר הכתיבה של preprocessing_fn שלך, יש להגדיר אותו במודול python אשר מסופק לרכיב Transform כקלט. מודול זה ייטען באמצעות טרנספורמציה והפונקציה בשם preprocessing_fn תימצא ותשתמש ב-Transform כדי לבנות את צינור העיבוד המקדים.

transform = Transform(
    examples=example_gen.outputs['examples'],
    schema=schema_gen.outputs['schema'],
    module_file=os.path.abspath(_taxi_transform_module_file))

בנוסף, ייתכן שתרצה לספק אפשרויות לחישוב סטטיסטיקה טרום-טרנספורמציה או לאחר-טרנספורמציה מבוסס TFDV . לשם כך, הגדר stats_options_updater_fn בתוך אותו מודול.

Transform ו- TensorFlow Transform

Transform עושה שימוש נרחב ב- TensorFlow Transform לביצוע הנדסת תכונות במערך הנתונים שלך. TensorFlow Transform הוא כלי נהדר להמרת נתוני תכונות לפני שהם עוברים למודל שלך וכחלק מתהליך ההדרכה. טרנספורמציות תכונות נפוצות כוללות:

  • הטבעה : המרת תכונות דלילות (כמו מזהי מספרים שלמים המיוצרים על ידי אוצר מילים) לתכונות צפופות על ידי מציאת מיפוי משמעותי ממרחב בעל מימד גבוה למרחב בעל מימד נמוך. ראה את יחידת ההטמעות בקורס התרסקות למידת מכונה למבוא להטמעות.
  • יצירת אוצר מילים : המרת מחרוזות או תכונות אחרות שאינן מספריות למספרים שלמים על ידי יצירת אוצר מילים הממפה כל ערך ייחודי למספר מזהה.
  • מנרמל ערכים : שינוי תכונות מספריות כך שכולן נופלות בטווח דומה.
  • bucketization : המרת תכונות בעלות ערך רציף לתכונות קטגוריות על ידי הקצאת ערכים לדליים נפרדים.
  • תכונות טקסט מעשרות : הפקת תכונות מנתונים גולמיים כמו אסימונים, n-גרם, ישויות, סנטימנט וכו', כדי להעשיר את מערך התכונות.

TensorFlow Transform מספקת תמיכה לסוגים אלה ולסוגים רבים אחרים של טרנספורמציות:

  • צור אוטומטית אוצר מילים מהנתונים העדכניים ביותר שלך.

  • בצע טרנספורמציות שרירותיות בנתונים שלך לפני שליחתם לדגם שלך. TensorFlow Transform בונה טרנספורמציות לתוך גרף TensorFlow עבור המודל שלך כך שאותן טרנספורמציות מבוצעות בזמן האימון וההסקה. אתה יכול להגדיר טרנספורמציות המתייחסות למאפיינים גלובליים של הנתונים, כמו הערך המקסימלי של תכונה בכל מופעי האימון.

אתה יכול לשנות את הנתונים שלך איך שאתה רוצה לפני הפעלת TFX. אבל אם אתה עושה את זה בתוך TensorFlow Transform, טרנספורמציות הופכות לחלק מגרף TensorFlow. גישה זו מסייעת להימנע מהטיית אימון/הגשה.

טרנספורמציות בתוך קוד הדוגמנות שלך משתמשות ב- FeatureColumns. באמצעות FeatureColumns, אתה יכול להגדיר bucketizations, שילובים שלמים המשתמשים באוצר מילים מוגדרים מראש, או כל טרנספורמציה אחרת שניתן להגדיר מבלי להסתכל על הנתונים.

לעומת זאת, TensorFlow Transform מיועד לטרנספורמציות הדורשות מעבר מלא על הנתונים כדי לחשב ערכים שאינם ידועים מראש. לדוגמה, יצירת אוצר מילים דורשת מעבר מלא על הנתונים.

בנוסף לחישוב ערכים באמצעות Apache Beam, TensorFlow Transform מאפשר למשתמשים להטמיע ערכים אלו בגרף TensorFlow, אשר לאחר מכן ניתן לטעון לתוך גרף האימון. לדוגמה בעת נרמול תכונות, הפונקציה tft.scale_to_z_score תחשב את הממוצע ואת סטיית התקן של תכונה, וגם ייצוג, בגרף TensorFlow, של הפונקציה המפחיתה את הממוצע ומחלקת בסטיית התקן. על ידי פליטת גרף TensorFlow, לא רק סטטיסטיקה, TensorFlow Transform מפשטת את תהליך עריכת צינור העיבוד המוקדם שלך.

מכיוון שהעיבוד המקדים מתבטא כגרף, זה יכול לקרות בשרת, ומובטח שזה יהיה עקבי בין אימון להגשה. עקביות זו מבטלת מקור אחד להטיית אימון/הגשה.

TensorFlow Transform מאפשר למשתמשים לציין את צינור העיבוד המקדים שלהם באמצעות קוד TensorFlow. המשמעות היא שצינור נבנה באותו אופן כמו גרף TensorFlow. אם רק אופציות של TensorFlow היו בשימוש בגרף זה, הצינור יהיה מפה טהורה שמקבלת קבוצות של קלט ומחזירה אצות של פלט. צינור כזה יהיה שווה ערך להצבת גרף זה בתוך input_fn שלך בעת שימוש ב- tf.Estimator API. על מנת לציין פעולות מעבר מלא כגון קוונטילי מחשוב, TensorFlow Transform מספקת פונקציות מיוחדות הנקראות analyzers המופיעות כמו TensorFlow ops, אך למעשה מציינים חישוב דחוי שייעשה על ידי Apache Beam, והפלט יוכנס לגרף כ- קָבוּעַ. בעוד שמבצע TensorFlow רגיל ייקח אצווה בודדת כקלט שלו, יבצע חישוב על אצווה זו בלבד ויפלוט אצווה, analyzer יבצע הפחתה גלובלית (מיושם ב-Apache Beam) על כל האצווה ויחזיר את התוצאה.

על ידי שילוב של TensorFlow אופציות רגילות ומנתחי TensorFlow Transform, משתמשים יכולים ליצור צינורות מורכבים כדי לעבד מראש את הנתונים שלהם. לדוגמה, הפונקציה tft.scale_to_z_score לוקחת טנזור קלט ומחזירה טנזור זה מנורמל לממוצע 0 ושונות 1 . הוא עושה זאת על ידי קריאה למנתחי mean וה- var מתחת למכסה המנוע, אשר יפיקו למעשה קבועים בגרף השווים לממוצע והשונות של טנזור הקלט. לאחר מכן הוא ישתמש ב- TensorFlow ops כדי להחסיר את הממוצע ולחלק בסטיית התקן.

ה-TensorFlow Transform preprocessing_fn

רכיב TFX Transform מפשט את השימוש ב-Transform על ידי טיפול בקריאות API הקשורות לקריאה וכתיבת נתונים, וכתיבת הפלט SavedModel לדיסק. כמשתמש TFX, אתה רק צריך להגדיר פונקציה אחת הנקראת preprocessing_fn . ב- preprocessing_fn אתה מגדיר סדרה של פונקציות המבצעות מניפולציה על dict קלט של טנסורים כדי לייצר את dict הפלט של טנסורים. אתה יכול למצוא פונקציות עוזרות כמו scale_to_0_1 ו-compute_and_apply_vocabulary את TensorFlow Transform API או להשתמש בפונקציות TensorFlow רגילות כפי שמוצג להלן.

def preprocessing_fn(inputs):
  """tf.transform's callback function for preprocessing inputs.

  Args:
    inputs: map from feature keys to raw not-yet-transformed features.

  Returns:
    Map from string feature key to transformed feature operations.
  """
  outputs = {}
  for key in _DENSE_FLOAT_FEATURE_KEYS:
    # If sparse make it dense, setting nan's to 0 or '', and apply zscore.
    outputs[_transformed_name(key)] = transform.scale_to_z_score(
        _fill_in_missing(inputs[key]))

  for key in _VOCAB_FEATURE_KEYS:
    # Build a vocabulary for this feature.
    outputs[_transformed_name(
        key)] = transform.compute_and_apply_vocabulary(
            _fill_in_missing(inputs[key]),
            top_k=_VOCAB_SIZE,
            num_oov_buckets=_OOV_SIZE)

  for key in _BUCKET_FEATURE_KEYS:
    outputs[_transformed_name(key)] = transform.bucketize(
        _fill_in_missing(inputs[key]), _FEATURE_BUCKET_COUNT)

  for key in _CATEGORICAL_FEATURE_KEYS:
    outputs[_transformed_name(key)] = _fill_in_missing(inputs[key])

  # Was this passenger a big tipper?
  taxi_fare = _fill_in_missing(inputs[_FARE_KEY])
  tips = _fill_in_missing(inputs[_LABEL_KEY])
  outputs[_transformed_name(_LABEL_KEY)] = tf.where(
      tf.is_nan(taxi_fare),
      tf.cast(tf.zeros_like(taxi_fare), tf.int64),
      # Test if the tip was > 20% of the fare.
      tf.cast(
          tf.greater(tips, tf.multiply(taxi_fare, tf.constant(0.2))), tf.int64))

  return outputs

הבנת התשומות ל-preprocessing_fn

ה- preprocessing_fn מתאר סדרה של פעולות על טנסורים (כלומר, Tensor s, SparseTensor s או RaggedTensor s). על מנת להגדיר נכון את ה- preprocessing_fn יש צורך להבין כיצד הנתונים מיוצגים כטנסורים. הקלט ל- preprocessing_fn נקבע על ידי הסכימה. פרוטו של Schema מומר בסופו של דבר ל"מפרט תכונה" (נקרא לפעמים "מפרט ניתוח") המשמש לניתוח נתונים, ראה פרטים נוספים על לוגיקת ההמרה כאן .

שימוש ב-TensorFlow Transform לטיפול בתוויות מחרוזות

בדרך כלל רוצים להשתמש ב-TensorFlow Transform גם כדי ליצור אוצר מילים וגם ליישם את אוצר המילים הזה כדי להמיר מחרוזות למספרים שלמים. כאשר עוקבים אחר זרימת עבודה זו, ה- input_fn שנבנה במודל יוציא את המחרוזת המשולמת. עם זאת התוויות הן חריגות, מכיוון שכדי שהמודל יוכל למפות את תוויות הפלט (מספר שלם) בחזרה למחרוזות, המודל צריך את ה- input_fn כדי להוציא תווית מחרוזת, יחד עם רשימה של ערכים אפשריים של התווית. למשל, אם התוויות הן cat dog אז הפלט של ה- input_fn צריך להיות מחרוזות גולמיות אלה, ויש להעביר את המפתחות ["cat", "dog"] לאומדן כפרמטר (ראה פרטים למטה).

על מנת לטפל במיפוי של תוויות מחרוזות למספרים שלמים, עליך להשתמש ב-TensorFlow Transform כדי ליצור אוצר מילים. אנו מדגימים זאת בקטע הקוד שלהלן:

def _preprocessing_fn(inputs):
  """Preprocess input features into transformed features."""

  ...


  education = inputs[features.RAW_LABEL_KEY]
  _ = tft.vocabulary(education, vocab_filename=features.RAW_LABEL_KEY)

  ...

פונקציית העיבוד הקדם שלמעלה לוקחת את תכונת הקלט הגולמית (שגם תוחזר כחלק מהפלט של פונקציית העיבוד הקדם) וקוראת עליה tft.vocabulary . כתוצאה מכך נוצר אוצר מילים education שניתן לגשת אליו במודל.

הדוגמה גם מראה כיצד להפוך תווית ולאחר מכן ליצור אוצר מילים עבור התווית שעברה שינוי. במיוחד הוא לוקח את התווית הגולמית education וממיר את כל התוויות מלבד 5 התוויות המובילות (לפי תדירות) ל- UNKNOWN , מבלי להמיר את התווית למספר שלם.

בקוד המודל, יש לתת למסווג את אוצר המילים שנוצר על ידי tft.vocabulary כארגומנט label_vocabulary . זה נעשה על ידי קריאה ראשונה של אוצר מילים זה כרשימה עם פונקציית עוזר. זה מוצג בקטע למטה. שימו לב שהקוד לדוגמה משתמש בתווית שעברה טרנספורמציה שנדונה לעיל, אבל כאן אנו מציגים קוד לשימוש בתווית הגולמית.

def create_estimator(pipeline_inputs, hparams):

  ...

  tf_transform_output = trainer_util.TFTransformOutput(
      pipeline_inputs.transform_dir)

  # vocabulary_by_name() returns a Python list.
  label_vocabulary = tf_transform_output.vocabulary_by_name(
      features.RAW_LABEL_KEY)

  return tf.contrib.learn.DNNLinearCombinedClassifier(
      ...
      n_classes=len(label_vocab),
      label_vocabulary=label_vocab,
      ...)

הגדרת נתונים סטטיסטיים לפני טרנספורמציה ואחרי טרנספורמציה

כפי שהוזכר לעיל, רכיב הטרנספורמציה מפעיל את TFDV כדי לחשב סטטיסטיקות טרום-טרנספורמציה וגם לאחר-טרנספורמציה. TFDV לוקח כקלט אובייקט StatsOptions אופציונלי. ייתכן שמשתמשים ירצו להגדיר את האובייקט הזה כדי לאפשר נתונים סטטיסטיים נוספים מסוימים (למשל סטטיסטיקות NLP) או להגדיר ספים מאומתים (למשל תדירות אסימון מינימלי/מקסימלית). לשם כך, הגדר stats_options_updater_fn בקובץ המודול.

def stats_options_updater_fn(stats_type, stats_options):
  ...
  if stats_type == stats_options_util.StatsType.PRE_TRANSFORM:
    # Update stats_options to modify pre-transform statistics computation.
    # Most constraints are specified in the schema which can be accessed
    # via stats_options.schema.
  if stats_type == stats_options_util.StatsType.POST_TRANSFORM
    # Update stats_options to modify post-transform statistics computation.
    # Most constraints are specified in the schema which can be accessed
    # via stats_options.schema.
  return stats_options

נתונים סטטיסטיים לאחר טרנספורמציה נהנים לעתים קרובות מהידע על אוצר המילים המשמש לעיבוד מקדים של תכונה. שם אוצר המילים למיפוי נתיב מסופק ל-StatsOptions (ומכאן ל-TFDV) עבור כל אוצר מילים שנוצר באמצעות TFT. בנוסף, ניתן להוסיף מיפויים עבור אוצר מילים שנוצרו באופן חיצוני על ידי (i) שינוי ישיר של מילון vocab_paths בתוך StatsOptions או על ידי (ii) שימוש tft.annotate_asset .