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

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

  • يستهلك: tf.Examples من مكون exampleGen، ومخطط بيانات من مكون SchemaGen.
  • يصدر: نموذج محفوظ لمكون المدرب، وإحصائيات ما قبل التحويل وما بعده.

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

بمجرد كتابة preprocessing_fn الخاص بك، يجب تعريفه في وحدة python التي يتم توفيرها بعد ذلك لمكون التحويل كمدخل. سيتم تحميل هذه الوحدة عن طريق التحويل وسيتم العثور على الوظيفة المسماة preprocessing_fn واستخدامها بواسطة التحويل لإنشاء خط أنابيب المعالجة المسبقة.

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 أداة رائعة لتحويل بيانات الميزات قبل أن تنتقل إلى النموذج الخاص بك وكجزء من عملية التدريب. تتضمن تحويلات الميزات المشتركة ما يلي:

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

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

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

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

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

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

على النقيض من ذلك، تم تصميم 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 لطرح المتوسط ​​والقسمة على الانحراف المعياري.

preprocessing_fn لتحويل TensorFlow_fn

يعمل مكون TFX Transform على تبسيط استخدام التحويل عن طريق التعامل مع استدعاءات واجهة برمجة التطبيقات (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

فهم المدخلات إلى المعالجة المسبقة_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 اختياريًا كمدخل. قد يرغب المستخدمون في تكوين هذا الكائن لتمكين إحصائيات إضافية معينة (مثل إحصائيات البرمجة اللغوية العصبية) أو لتعيين الحدود التي تم التحقق من صحتها (مثل الحد الأدنى / الحد الأقصى لتكرار الرمز المميز). للقيام بذلك، قم بتعريف 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 .