คอมโพเนนต์ไปป์ไลน์การแปลง TFX

คอมโพเนนต์ไปป์ไลน์ Transform TFX ดำเนินการวิศวกรรมฟีเจอร์บน tf ตัวอย่างที่ปล่อยออกมาจากคอมโพเนนต์ ExampleGen โดยใช้สคีมาข้อมูลที่สร้างโดยคอมโพเนนต์ SchemaGen และปล่อยทั้ง SavedModel รวมถึงสถิติทั้งข้อมูลก่อนการแปลงและหลังการแปลง เมื่อดำเนินการแล้ว SavedModel จะยอมรับ tf.Examples ที่ปล่อยออกมาจากส่วนประกอบ ExampleGen และปล่อยข้อมูลคุณสมบัติที่แปลงแล้ว

  • ใช้: tf.Examples จากส่วนประกอบ 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 ภายในโมดูลเดียวกัน

การแปลงและการแปลง TensorFlow

Transform ใช้ TensorFlow Transform อย่างกว้างขวางเพื่อดำเนินการวิศวกรรมฟีเจอร์บนชุดข้อมูลของคุณ TensorFlow Transform เป็นเครื่องมือที่ยอดเยี่ยมสำหรับการแปลงข้อมูลฟีเจอร์ก่อนที่จะไปที่โมเดลของคุณและเป็นส่วนหนึ่งของกระบวนการฝึกอบรม การเปลี่ยนแปลงฟีเจอร์ทั่วไปได้แก่:

  • การฝัง : การแปลงคุณลักษณะกระจัดกระจาย (เช่น ID จำนวนเต็มที่สร้างโดยคำศัพท์) ให้เป็นคุณลักษณะหนาแน่นโดยการค้นหาการแมปที่มีความหมายจากพื้นที่มิติสูงไปยังพื้นที่มิติต่ำ ดู หน่วยการฝังในหลักสูตรข้อขัดข้องของแมชชีนเลิร์นนิง สำหรับข้อมูลเบื้องต้นเกี่ยวกับการฝัง
  • การสร้างคำศัพท์ : การแปลงสตริงหรือคุณลักษณะอื่นๆ ที่ไม่ใช่ตัวเลขให้เป็นจำนวนเต็มโดยการสร้างคำศัพท์ที่จับคู่ค่าที่ไม่ซ้ำกันแต่ละค่ากับหมายเลข ID
  • การทำให้ค่าเป็นมาตรฐาน : การแปลงคุณสมบัติตัวเลขเพื่อให้ทั้งหมดอยู่ในช่วงที่ใกล้เคียงกัน
  • Bucketization : การแปลงคุณสมบัติที่มีมูลค่าต่อเนื่องเป็นคุณสมบัติหมวดหมู่โดยการกำหนดค่าให้กับที่เก็บข้อมูลที่ไม่ต่อเนื่อง
  • การเพิ่มคุณลักษณะข้อความ : การสร้างคุณลักษณะจากข้อมูลดิบ เช่น โทเค็น n-กรัม เอนทิตี ความรู้สึก ฯลฯ เพื่อเพิ่มคุณค่าให้กับชุดคุณลักษณะ

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 op ทั่วไปจะใช้แบตช์เดียวเป็นอินพุต ทำการคำนวณเฉพาะกับแบตช์นั้นและปล่อยแบตช์ออกมา analyzer จะดำเนินการลดทั่วโลก (ใช้งานใน Apache Beam) เหนือแบตช์ทั้งหมดและส่งคืนผลลัพธ์

ด้วยการรวมการดำเนินการของ TensorFlow ธรรมดาเข้ากับตัววิเคราะห์ TensorFlow Transform ผู้ใช้จึงสามารถสร้างไปป์ไลน์ที่ซับซ้อนเพื่อประมวลผลข้อมูลล่วงหน้าได้ ตัวอย่างเช่น ฟังก์ชัน tft.scale_to_z_score รับอินพุตเทนเซอร์และส่งคืนค่าเทนเซอร์นั้นให้เป็นมาตรฐานให้มีค่าเฉลี่ย 0 และความแปรปรวน 1 โดยเรียกเครื่องวิเคราะห์ mean และ var ภายใต้ประทุน ซึ่งจะสร้างค่าคงที่ในกราฟเท่ากับค่าเฉลี่ยและความแปรปรวนของเทนเซอร์อินพุตได้อย่างมีประสิทธิภาพ จากนั้นจะใช้ตัวเลือก TensorFlow เพื่อลบค่าเฉลี่ยแล้วหารด้วยค่าเบี่ยงเบนมาตรฐาน

preprocessing_fn การแปลง TensorFlow_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 Proto จะถูกแปลงเป็น "ข้อมูลจำเพาะคุณลักษณะ" (บางครั้งเรียกว่า "ข้อมูลจำเพาะการแยกวิเคราะห์") ซึ่งใช้สำหรับการแยกวิเคราะห์ข้อมูล ดูรายละเอียดเพิ่มเติมเกี่ยวกับตรรกะการแปลงได้ ที่นี่

การใช้ 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