مكون خط أنابيب تحويل TFX

تنظيم صفحاتك في مجموعات يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.

ينفذ مكون خط أنابيب Transform TFX هندسة ميزات على أمثلة تنبعث من مكون ExampleGen ، باستخدام مخطط بيانات تم إنشاؤه بواسطة مكون SchemaGen ، ويصدر كلاً من SavedModel بالإضافة إلى إحصائيات حول بيانات ما قبل التحويل وما بعد التحويل. عند التنفيذ ، سيقبل SavedModel tf.Examples المنبعثة من مكون ExampleGen وإصدار بيانات الميزة المحولة.

  • يستهلك: tf.Examples من مكون ExampleGen ، ومخطط بيانات من مكون SchemaGen.
  • الانبعاث: نموذج SavedModel لمكون المدرب وإحصاءات ما قبل التحويل وما بعد التحويل.

تكوين مكون التحويل

بمجرد كتابة preprocessing_fn ، يجب تحديده في وحدة Python النمطية التي يتم توفيرها بعد ذلك لمكون التحويل كمدخل. سيتم تحميل هذه الوحدة عن طريق التحويل وسيتم العثور على الوظيفة المسماة 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 داخل نفس الوحدة.

التحويل وتحويل TensorFlow

تستفيد Transform بشكل مكثف من TensorFlow Transform لتنفيذ هندسة الميزات على مجموعة البيانات الخاصة بك. TensorFlow Transform هي أداة رائعة لتحويل بيانات الميزات قبل أن تنتقل إلى النموذج الخاص بك وكجزء من عملية التدريب. تشمل تحولات السمات الشائعة ما يلي:

  • التضمين : تحويل السمات المتفرقة (مثل المعرفات الصحيحة التي تنتجها المفردات) إلى سمات كثيفة من خلال إيجاد رسم خرائط ذي مغزى من مساحة عالية الأبعاد إلى مساحة ذات أبعاد منخفضة. راجع وحدة Embeddings في دورة Crash Course للتعلم الآلي للحصول على مقدمة عن حفلات الزفاف.
  • توليد المفردات : تحويل السلاسل أو الميزات غير الرقمية الأخرى إلى أعداد صحيحة عن طريق إنشاء مفردات تعيّن كل قيمة فريدة إلى رقم معرّف.
  • قيم التسوية : تحويل المعالم الرقمية بحيث تقع جميعها ضمن نطاق مشابه.
  • الجرافة : تحويل الميزات ذات القيمة المستمرة إلى ميزات فئوية عن طريق تعيين قيم للمجموعات المنفصلة.
  • إثراء ميزات النص : إنتاج ميزات من البيانات الأولية مثل الرموز المميزة ، و n-grams ، والكيانات ، والمشاعر ، وما إلى ذلك ، لإثراء مجموعة الميزات.

يوفر TensorFlow Transform الدعم لهذه وأنواع كثيرة أخرى من التحويلات:

  • قم بإنشاء مفردات تلقائيًا من أحدث بياناتك.

  • قم بإجراء تحويلات عشوائية على بياناتك قبل إرسالها إلى النموذج الخاص بك. ينشئ TensorFlow Transform تحويلات إلى الرسم البياني TensorFlow للنموذج الخاص بك بحيث يتم إجراء نفس التحويلات في وقت التدريب والاستنتاج. يمكنك تحديد التحويلات التي تشير إلى الخصائص العامة للبيانات ، مثل القيمة القصوى لميزة في جميع حالات التدريب.

يمكنك تحويل بياناتك كيفما تشاء قبل تشغيل TFX. ولكن إذا قمت بذلك في TensorFlow Transform ، فإن التحولات تصبح جزءًا من الرسم البياني TensorFlow. يساعد هذا الأسلوب في تجنب التدريب / تقديم الانحراف.

التحولات داخل كود النمذجة الخاصة بك تستخدم FeatureColumns. باستخدام FeatureColumns ، يمكنك تحديد مجموعات ، أو أعداد صحيحة تستخدم مفردات محددة مسبقًا ، أو أي تحويلات أخرى يمكن تعريفها دون النظر إلى البيانات.

على النقيض من ذلك ، تم تصميم 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 ، ولكنها في الواقع تحدد حسابًا مؤجلًا سيتم إجراؤه بواسطة Apache Beam ، ويتم إدراج الإخراج في الرسم البياني باعتباره مستمر. في حين أن عملية TensorFlow العادية سوف تأخذ دفعة واحدة كمدخلاتها ، وتقوم ببعض العمليات الحسابية على تلك الدفعة فقط وتنبعث منها دفعة ، فإن analyzer سيقوم بإجراء تخفيض شامل (يتم تنفيذه في Apache Beam) على جميع الدُفعات ويعيد النتيجة.

من خلال الجمع بين عمليات TensorFlow العادية ومحللات TensorFlow Transform ، يمكن للمستخدمين إنشاء خطوط أنابيب معقدة للمعالجة المسبقة لبياناتهم. على سبيل المثال ، تأخذ الدالة tft.scale_to_z_score موتر إدخال وتعيد الموتر الذي تم ضبطه ليكون يعني 0 والتباين 1 . يقوم بذلك عن طريق استدعاء محللي mean ​​و var تحت الغطاء ، والذي سيولد بشكل فعال ثوابت في الرسم البياني تساوي متوسط ​​وتباين موتر الإدخال. سيستخدم بعد ذلك عمليات TensorFlow لطرح المتوسط ​​والقسمة على الانحراف المعياري.

TensorFlow Transform preprocessing_fn

يبسط مكون تحويل TFX استخدام التحويل من خلال معالجة استدعاءات API المتعلقة بقراءة البيانات وكتابتها ، وكتابة الإخراج SavedModel على القرص. بصفتك مستخدم TFX ، ما عليك سوى تحديد وظيفة واحدة تسمى preprocessing_fn . في preprocessing_fn ، تقوم بتعريف سلسلة من الوظائف التي تتعامل مع إملاء إدخال الموترات لإنتاج إملاء الإخراج الخاص بالموترات. يمكنك العثور على وظائف مساعدة مثل 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) ولذا لكتابة preprocessing_fn بشكل صحيح ، من الضروري فهم كيفية تمثيل بياناتك كموترات. يتم تحديد المدخلات إلى preprocessing_fn بواسطة المخطط. يحتوي بروتو Schema على قائمة Feature ، ويقوم التحويل بتحويلها إلى "مواصفات ميزة" (تسمى أحيانًا "مواصفات التحليل") وهي عبارة عن إملاء تكون مفاتيحه أسماء ميزات وقيمها هي إحدى قيم FixedLenFeature أو VarLenFeature (أو غير ذلك خيارات لا يستخدمها TensorFlow Transform).

قواعد استنتاج مواصفات الميزة من Schema هي

  • كل feature مع مجموعة shape ستؤدي إلى tf.FixedLenFeature مع شكل و default_value=None . يجب أن تكون قيمة الحد الأدنى للكسر 1 وإلا فسيحدث خطأ ، لأنه في حالة عدم presence.min_fraction قيمة افتراضية ، تتطلب الخاصية tf.FixedLenFeature أن تكون الميزة موجودة دائمًا.
  • كل feature مع shape غير مضبوط سينتج عنها VarLenFeature .
  • سينتج عن كل sparse_feature من tf.SparseFeature التي يتم تحديد size is_sorted is_sorted الحقول التي تم SparseFeature fixed_shape
  • الميزات المستخدمة index_feature أو value_feature sparse_feature لن يكون لها إدخال خاص بها تم إنشاؤه في مواصفات الميزة.
  • يوضح الجدول التالي التطابق بين حقل type feature (أو ميزة القيم الخاصة sparse_feature ) ونوع dtype لمواصفات الميزة:
type dtype
schema_pb2.INT tf.int64
schema_pb2.FLOAT tf.float32
schema_pb2.BYTES tf.string

استخدام TensorFlow Transform للتعامل مع تسميات السلسلة

عادةً ما يرغب المرء في استخدام TensorFlow Transform لتوليد مفردات وتطبيق تلك المفردات لتحويل السلاسل إلى أعداد صحيحة. عند اتباع سير العمل هذا ، فإن input_fn الذي تم إنشاؤه في النموذج سينتج سلسلة متكاملة. ومع ذلك ، تعتبر التسميات استثناءً ، لأنه لكي يتمكن النموذج من تعيين تسميات الإخراج (عدد صحيح) مرة أخرى إلى السلاسل ، يحتاج النموذج إلى input_fn لإخراج تسمية سلسلة ، جنبًا إلى جنب مع قائمة بالقيم المحتملة للتسمية. على سبيل المثال ، إذا كانت الملصقات هي cat and 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 الملصق الأولي ويحول جميع الملصقات الخمس الأولى (حسب التردد) إلى 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. بالإضافة إلى ذلك ، يمكن إضافة تعيينات للمفردات التي تم إنشاؤها خارجيًا إما عن طريق (1) تعديل قاموس vocab_paths مباشرةً ضمن StatsOptions أو عن طريق (2) باستخدام tft.annotate_asset .