ส่วนประกอบไปป์ไลน์ Transform TFX

จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ

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

  • ใช้: tf.Examples จากคอมโพเนนต์ ExampleGen และสคีมาข้อมูลจากคอมโพเนนต์ SchemaGen
  • ปล่อย: แบบจำลองที่บันทึกไปยังคอมโพเนนต์ 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 จำนวนเต็มที่เกิดจากคำศัพท์) ให้เป็นคุณสมบัติที่หนาแน่นโดยการค้นหาการจับคู่ที่มีความหมายจากช่องว่างมิติสูงไปยังพื้นที่มิติต่ำ ดู หน่วยการฝังใน Machine-learning Crash Course สำหรับคำแนะนำเกี่ยวกับการฝัง
  • การสร้างคำศัพท์ : การแปลงสตริงหรือคุณลักษณะอื่นๆ ที่ไม่ใช่ตัวเลขให้เป็นจำนวนเต็มโดยการสร้างคำศัพท์ที่จับคู่ค่าเฉพาะแต่ละค่ากับหมายเลข ID
  • การทำให้เป็น มาตรฐาน : การแปลงคุณลักษณะที่เป็นตัวเลขเพื่อให้ทั้งหมดอยู่ในช่วงที่ใกล้เคียงกัน
  • Bucketization : การแปลงคุณสมบัติที่มีมูลค่าอย่างต่อเนื่องเป็นคุณสมบัติหมวดหมู่โดยการกำหนดค่าให้กับบัคเก็ตแบบแยกส่วน
  • การเพิ่ม คุณสมบัติข้อความ : การสร้างคุณสมบัติจากข้อมูลดิบ เช่น โทเค็น 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 ops ในกราฟนี้ ไปป์ไลน์จะเป็นแผนที่บริสุทธิ์ที่รับชุดอินพุตและส่งกลับชุดเอาต์พุต ไปป์ไลน์ดังกล่าวจะเทียบเท่ากับการวางกราฟนี้ไว้ใน input_fn ของคุณเมื่อใช้ tf.Estimator API เพื่อระบุการดำเนินการแบบฟูลพาส เช่น การคำนวณควอนไทล์ TensorFlow Transform มีฟังก์ชันพิเศษที่เรียกว่า analyzers ที่ดูเหมือน TensorFlow ops แต่อันที่จริงแล้วระบุการคำนวณแบบเลื่อนเวลาซึ่งจะทำโดย Apache Beam และเอาต์พุตที่แทรกลงในกราฟเป็น คงที่. ในขณะที่ TensorFlow op ทั่วไปจะใช้แบทช์เดียวเป็นอินพุต ทำการคำนวณบางอย่างบนแบทช์นั้นและปล่อยแบทช์ analyzer จะทำการลดโดยรวม (ใช้ใน Apache Beam) เหนือแบทช์ทั้งหมดและส่งคืนผลลัพธ์

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

การแปลง TensorFlow 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 proto จะถูกแปลงเป็น "feature spec" (บางครั้งเรียกว่า "parsing spec") ที่ใช้สำหรับ data parsing ดูรายละเอียดเพิ่มเติมเกี่ยวกับตรรกะการแปลงได้ ที่นี่

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

การกำหนดค่าสถิติก่อนการแปลงและหลังการแปลง

ตามที่กล่าวไว้ข้างต้น คอมโพเนนต์ Transform เรียกใช้ 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

,

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

  • ใช้: tf.Examples จากคอมโพเนนต์ ExampleGen และสคีมาข้อมูลจากคอมโพเนนต์ SchemaGen
  • ปล่อย: แบบจำลองที่บันทึกไปยังคอมโพเนนต์ 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 จำนวนเต็มที่เกิดจากคำศัพท์) ให้เป็นคุณสมบัติที่หนาแน่นโดยการค้นหาการจับคู่ที่มีความหมายจากช่องว่างมิติสูงไปยังพื้นที่มิติต่ำ ดู หน่วยการฝังใน Machine-learning Crash Course สำหรับคำแนะนำเกี่ยวกับการฝัง
  • การสร้างคำศัพท์ : การแปลงสตริงหรือคุณลักษณะอื่นๆ ที่ไม่ใช่ตัวเลขให้เป็นจำนวนเต็มโดยการสร้างคำศัพท์ที่จับคู่ค่าเฉพาะแต่ละค่ากับหมายเลข ID
  • การทำให้เป็น มาตรฐาน : การแปลงคุณลักษณะที่เป็นตัวเลขเพื่อให้ทั้งหมดอยู่ในช่วงที่ใกล้เคียงกัน
  • Bucketization : การแปลงคุณสมบัติที่มีมูลค่าอย่างต่อเนื่องเป็นคุณสมบัติหมวดหมู่โดยการกำหนดค่าให้กับบัคเก็ตแบบแยกส่วน
  • การเพิ่ม คุณสมบัติข้อความ : การสร้างคุณสมบัติจากข้อมูลดิบ เช่น โทเค็น 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 ops ในกราฟนี้ ไปป์ไลน์จะเป็นแผนที่บริสุทธิ์ที่รับชุดอินพุตและส่งกลับชุดเอาต์พุต ไปป์ไลน์ดังกล่าวจะเทียบเท่ากับการวางกราฟนี้ไว้ใน input_fn ของคุณเมื่อใช้ tf.Estimator API เพื่อระบุการดำเนินการแบบฟูลพาส เช่น การคำนวณควอนไทล์ TensorFlow Transform มีฟังก์ชันพิเศษที่เรียกว่า analyzers ที่ดูเหมือน TensorFlow ops แต่อันที่จริงแล้วระบุการคำนวณแบบเลื่อนเวลาซึ่งจะทำโดย Apache Beam และเอาต์พุตที่แทรกลงในกราฟเป็น คงที่. ในขณะที่ TensorFlow op ทั่วไปจะใช้แบทช์เดียวเป็นอินพุต ทำการคำนวณบางอย่างบนแบทช์นั้นและปล่อยแบทช์ analyzer จะทำการลดโดยรวม (ใช้ใน Apache Beam) เหนือแบทช์ทั้งหมดและส่งคืนผลลัพธ์

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

การแปลง TensorFlow 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 proto จะถูกแปลงเป็น "feature spec" (บางครั้งเรียกว่า "parsing spec") ที่ใช้สำหรับ data parsing ดูรายละเอียดเพิ่มเติมเกี่ยวกับตรรกะการแปลงได้ ที่นี่

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

การกำหนดค่าสถิติก่อนการแปลงและหลังการแปลง

ตามที่กล่าวไว้ข้างต้น คอมโพเนนต์ Transform เรียกใช้ 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