ประมวลผลข้อมูลล่วงหน้าด้วย TensorFlow Transform

ส่วนประกอบวิศวกรรมคุณลักษณะของ TensorFlow Extended (TFX)

ตัวอย่างสมุดบันทึก colab นี้แสดงตัวอย่างง่ายๆ ของวิธีที่ TensorFlow Transform ( tf.Transform ) สามารถใช้ในการประมวลผลข้อมูลล่วงหน้าโดยใช้โค้ดเดียวกันทุกประการสำหรับทั้งการฝึกโมเดลและการอนุมานในการผลิต

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

  • ปรับค่าอินพุตให้เป็นมาตรฐานโดยใช้ค่าเฉลี่ยและค่าเบี่ยงเบนมาตรฐาน
  • แปลงสตริงเป็นจำนวนเต็มโดยสร้างคำศัพท์เหนือค่าอินพุตทั้งหมด
  • แปลงจำนวนเต็มเป็นจำนวนเต็มโดยกำหนดให้กับบัคเก็ต ตามการกระจายข้อมูลที่สังเกตได้

TensorFlow มีการสนับสนุนในตัวสำหรับการปรับเปลี่ยนในตัวอย่างเดียวหรือกลุ่มตัวอย่าง tf.Transform ขยายความสามารถเหล่านี้เพื่อรองรับการส่งผ่านข้อมูลเต็มรูปแบบในชุดข้อมูลการฝึกอบรมทั้งหมด

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

อัพเกรด Pip

เพื่อหลีกเลี่ยงการอัพเกรด Pip ในระบบเมื่อรันในเครื่อง ให้ตรวจสอบว่าเรากำลังทำงานใน Colab แน่นอนว่าระบบในพื้นที่สามารถอัพเกรดแยกกันได้

try:
  import colab
  !pip install --upgrade pip
except:
  pass

ติดตั้ง TensorFlow Transform

pip install -q -U tensorflow_transform

คุณรีสตาร์ทรันไทม์หรือไม่

หากคุณกำลังใช้ Google Colab ในครั้งแรกที่คุณเรียกใช้เซลล์ด้านบน คุณต้องเริ่มรันไทม์ใหม่ (รันไทม์ > รีสตาร์ทรันไทม์ ...) นี่เป็นเพราะวิธีที่ Colab โหลดแพ็คเกจ

นำเข้า

import pprint
import tempfile

import tensorflow as tf
import tensorflow_transform as tft

import tensorflow_transform.beam as tft_beam
from tensorflow_transform.tf_metadata import dataset_metadata
from tensorflow_transform.tf_metadata import schema_utils

ข้อมูล: สร้างข้อมูลจำลอง

เราจะสร้างข้อมูลจำลองง่ายๆ สำหรับตัวอย่างง่ายๆ ของเรา:

  • raw_data คือข้อมูลดิบเริ่มต้นที่เราจะประมวลผลล่วงหน้า
  • raw_data_metadata มีสคีมาที่บอกเราถึงประเภทของแต่ละคอลัมน์ใน raw_data ในกรณีนี้ มันง่ายมาก
raw_data = [
      {'x': 1, 'y': 1, 's': 'hello'},
      {'x': 2, 'y': 2, 's': 'world'},
      {'x': 3, 'y': 3, 's': 'hello'}
  ]

raw_data_metadata = dataset_metadata.DatasetMetadata(
    schema_utils.schema_from_feature_spec({
        'y': tf.io.FixedLenFeature([], tf.float32),
        'x': tf.io.FixedLenFeature([], tf.float32),
        's': tf.io.FixedLenFeature([], tf.string),
    }))

การแปลง: สร้างฟังก์ชันการประมวลผลล่วงหน้า

ฟังก์ชันก่อนการประมวลผล เป็นแนวคิดที่สำคัญที่สุดของ tf.Transform ฟังก์ชันการประมวลผลล่วงหน้าเป็นที่ที่การแปลงชุดข้อมูลเกิดขึ้นจริง ยอมรับและส่งคืนพจนานุกรมของเมตริกซ์ โดยที่ tensor หมายถึง Tensor หรือSparseTensor การเรียก API มีสองกลุ่มหลักที่โดยทั่วไปแล้วจะเป็นหัวใจของฟังก์ชันการประมวลผลล่วงหน้า:

  1. TensorFlow Ops: ฟังก์ชันใดๆ ที่ยอมรับและส่งคืนเทนเซอร์ ซึ่งมักจะหมายถึง TensorFlow ops สิ่งเหล่านี้เพิ่มการดำเนินการ TensorFlow ให้กับกราฟที่แปลงข้อมูลดิบเป็นข้อมูลที่แปลงแล้วเวกเตอร์คุณลักษณะครั้งละหนึ่งรายการ สิ่งเหล่านี้จะทำงานในทุกตัวอย่าง ระหว่างการฝึกและการเสิร์ฟ
  2. Tensorflow Transform Analyzers/Mappers: ตัววิเคราะห์/ตัวแมปใดๆ ที่จัดเตรียมโดย tf.Transform สิ่งเหล่านี้ยังยอมรับและส่งคืนเทนเซอร์ และโดยทั่วไปประกอบด้วยการรวมกันของ Tensorflow ops และการคำนวณบีม แต่ไม่เหมือนกับ TensorFlow ops ที่รันในไปป์ไลน์บีมเท่านั้นในระหว่างการวิเคราะห์ที่ต้องการการส่งผ่านชุดข้อมูลการฝึกอบรมทั้งหมด การคำนวณบีมจะทำงานเพียงครั้งเดียว ระหว่างการฝึก และโดยทั่วไปแล้วจะส่งผ่านชุดข้อมูลการฝึกทั้งหมด พวกมันสร้างค่าคงที่เทนเซอร์ ซึ่งเพิ่มลงในกราฟของคุณ ตัวอย่างเช่น tft.min จะคำนวณค่าต่ำสุดของเมตริกซ์เหนือชุดข้อมูลการฝึก ขณะที่ tft.scale_by_min_max จะคำนวณค่าต่ำสุดและสูงสุดของเมตริกซ์ในชุดข้อมูลการฝึก จากนั้นจึงปรับขนาดเทนเซอร์ให้อยู่ในช่วงที่ผู้ใช้กำหนด [output_min, เอาต์พุตสูงสุด] tf.Transform มีชุดเครื่องมือวิเคราะห์/ตัวสร้างแผนที่แบบตายตัว แต่จะขยายเพิ่มเติมในเวอร์ชันต่อๆ ไป
def preprocessing_fn(inputs):
    """Preprocess input columns into transformed columns."""
    x = inputs['x']
    y = inputs['y']
    s = inputs['s']
    x_centered = x - tft.mean(x)
    y_normalized = tft.scale_to_0_1(y)
    s_integerized = tft.compute_and_apply_vocabulary(s)
    x_centered_times_y_normalized = (x_centered * y_normalized)
    return {
        'x_centered': x_centered,
        'y_normalized': y_normalized,
        's_integerized': s_integerized,
        'x_centered_times_y_normalized': x_centered_times_y_normalized,
    }

วางมันทั้งหมดเข้าด้วยกัน

ตอนนี้เราพร้อมที่จะแปลงข้อมูลของเราแล้ว เราจะใช้ Apache Beam กับ direct runner และจัดหาสามอินพุต:

  1. raw_data - ข้อมูลอินพุตดิบที่เราสร้างขึ้นด้านบน
  2. raw_data_metadata - สคีมาสำหรับข้อมูลดิบ
  3. preprocessing_fn - ฟังก์ชั่นที่เราสร้างขึ้นเพื่อทำการแปลงของเรา
def main():
  # Ignore the warnings
  with tft_beam.Context(temp_dir=tempfile.mkdtemp()):
    transformed_dataset, transform_fn = (  # pylint: disable=unused-variable
        (raw_data, raw_data_metadata) | tft_beam.AnalyzeAndTransformDataset(
            preprocessing_fn))

  transformed_data, transformed_metadata = transformed_dataset  # pylint: disable=unused-variable

  print('\nRaw data:\n{}\n'.format(pprint.pformat(raw_data)))
  print('Transformed data:\n{}'.format(pprint.pformat(transformed_data)))

if __name__ == '__main__':
  main()
WARNING:apache_beam.runners.interactive.interactive_environment:Dependencies required for Interactive Beam PCollection visualization are not available, please use: `pip install apache-beam[interactive]` to install necessary dependencies to enable all data visualization features.
WARNING:tensorflow:You are passing instance dicts and DatasetMetadata to TFT which will not provide optimal performance. Consider following the TFT guide to upgrade to the TFXIO format (Apache Arrow RecordBatch).
WARNING:tensorflow:You are passing instance dicts and DatasetMetadata to TFT which will not provide optimal performance. Consider following the TFT guide to upgrade to the TFXIO format (Apache Arrow RecordBatch).
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow_transform/tf_utils.py:289: Tensor.experimental_ref (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use ref() instead.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow_transform/tf_utils.py:289: Tensor.experimental_ref (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use ref() instead.
WARNING:tensorflow:You are passing instance dicts and DatasetMetadata to TFT which will not provide optimal performance. Consider following the TFT guide to upgrade to the TFXIO format (Apache Arrow RecordBatch).
WARNING:tensorflow:You are passing instance dicts and DatasetMetadata to TFT which will not provide optimal performance. Consider following the TFT guide to upgrade to the TFXIO format (Apache Arrow RecordBatch).
WARNING:apache_beam.options.pipeline_options:Discarding unparseable args: ['/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py', '-f', '/tmp/tmp8aif_7w8.json', '--HistoryManager.hist_file=:memory:']
WARNING:root:Make sure that locally built Python SDK docker image has Python 3.7 interpreter.
INFO:tensorflow:Assets written to: /tmp/tmpfvgb9_2h/tftransform_tmp/319450c9d7da4ab08741bc79e129ac38/assets
2022-02-03 10:18:41.378629: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
INFO:tensorflow:Assets written to: /tmp/tmpfvgb9_2h/tftransform_tmp/319450c9d7da4ab08741bc79e129ac38/assets
INFO:tensorflow:tensorflow_text is not available.
INFO:tensorflow:tensorflow_text is not available.
INFO:tensorflow:tensorflow_decision_forests is not available.
INFO:tensorflow:tensorflow_decision_forests is not available.
INFO:tensorflow:struct2tensor is not available.
INFO:tensorflow:struct2tensor is not available.
INFO:tensorflow:Assets written to: /tmp/tmpfvgb9_2h/tftransform_tmp/1f79865adbdd4ede9a3768fcac29949c/assets
INFO:tensorflow:Assets written to: /tmp/tmpfvgb9_2h/tftransform_tmp/1f79865adbdd4ede9a3768fcac29949c/assets
INFO:tensorflow:tensorflow_text is not available.
INFO:tensorflow:tensorflow_text is not available.
INFO:tensorflow:tensorflow_decision_forests is not available.
INFO:tensorflow:tensorflow_decision_forests is not available.
INFO:tensorflow:struct2tensor is not available.
INFO:tensorflow:struct2tensor is not available.
Raw data:
[{'s': 'hello', 'x': 1, 'y': 1},
 {'s': 'world', 'x': 2, 'y': 2},
 {'s': 'hello', 'x': 3, 'y': 3}]

Transformed data:
[{'s_integerized': 0,
  'x_centered': -1.0,
  'x_centered_times_y_normalized': -0.0,
  'y_normalized': 0.0},
 {'s_integerized': 1,
  'x_centered': 0.0,
  'x_centered_times_y_normalized': 0.0,
  'y_normalized': 0.5},
 {'s_integerized': 0,
  'x_centered': 1.0,
  'x_centered_times_y_normalized': 1.0,
  'y_normalized': 1.0}]

นี่เป็นคำตอบที่ถูกต้องหรือไม่?

ก่อนหน้านี้ เราใช้ tf.Transform เพื่อทำสิ่งนี้:

x_centered = x - tft.mean(x)
y_normalized = tft.scale_to_0_1(y)
s_integerized = tft.compute_and_apply_vocabulary(s)
x_centered_times_y_normalized = (x_centered * y_normalized)

x_centered

ด้วยอินพุตของ [1, 2, 3] ค่าเฉลี่ยของ x คือ 2 และเราลบมันออกจาก x เพื่อให้ค่า x อยู่กึ่งกลางที่ 0 ดังนั้นผลลัพธ์ของ [-1.0, 0.0, 1.0] จึงถูกต้อง

y_normalized

เราต้องการปรับขนาดค่า y ระหว่าง 0 ถึง 1 ข้อมูลที่ป้อนคือ [1, 2, 3] ดังนั้นผลลัพธ์ของ [0.0, 0.5, 1.0] จึงถูกต้อง

s_integerized

เราต้องการแมปสตริงของเรากับดัชนีในคำศัพท์ และมีเพียง 2 คำในคำศัพท์ของเรา ("สวัสดี" และ "โลก") ดังนั้นด้วยอินพุตของ ["hello", "world", "hello"] ผลลัพธ์ของ [0, 1, 0] ของเราจึงถูกต้อง เนื่องจาก "สวัสดี" เกิดขึ้นบ่อยที่สุดในข้อมูลนี้ จะเป็นรายการแรกในคำศัพท์

x_centered_times_y_normalized

เราต้องการสร้างคุณลักษณะใหม่โดยการข้าม x_centered และ y_normalized โดยใช้การคูณ โปรดทราบว่าการดำเนินการนี้จะคูณผลลัพธ์ ไม่ใช่ค่าเดิม และผลลัพธ์ใหม่ของเราเป็น [-0.0, 0.0, 1.0] นั้นถูกต้อง